1 /***************************************************************************/ |
|
2 /* */ |
|
3 /* otvmod.c */ |
|
4 /* */ |
|
5 /* FreeType's OpenType validation module implementation (body). */ |
|
6 /* */ |
|
7 /* Copyright 2004, 2005, 2006, 2007, 2008 by */ |
|
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
|
9 /* */ |
|
10 /* This file is part of the FreeType project, and may only be used, */ |
|
11 /* modified, and distributed under the terms of the FreeType project */ |
|
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
|
13 /* this file you indicate that you have read the license and */ |
|
14 /* understand and accept it fully. */ |
|
15 /* */ |
|
16 /***************************************************************************/ |
|
17 |
|
18 |
|
19 #include <ft2build.h> |
|
20 #include FT_TRUETYPE_TABLES_H |
|
21 #include FT_TRUETYPE_TAGS_H |
|
22 #include FT_OPENTYPE_VALIDATE_H |
|
23 #include FT_INTERNAL_OBJECTS_H |
|
24 #include FT_SERVICE_OPENTYPE_VALIDATE_H |
|
25 |
|
26 #include "otvmod.h" |
|
27 #include "otvalid.h" |
|
28 #include "otvcommn.h" |
|
29 |
|
30 |
|
31 /*************************************************************************/ |
|
32 /* */ |
|
33 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
|
34 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
|
35 /* messages during execution. */ |
|
36 /* */ |
|
37 #undef FT_COMPONENT |
|
38 #define FT_COMPONENT trace_otvmodule |
|
39 |
|
40 |
|
41 static FT_Error |
|
42 otv_load_table( FT_Face face, |
|
43 FT_Tag tag, |
|
44 FT_Byte* volatile* table, |
|
45 FT_ULong* table_len ) |
|
46 { |
|
47 FT_Error error; |
|
48 FT_Memory memory = FT_FACE_MEMORY( face ); |
|
49 |
|
50 |
|
51 error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); |
|
52 if ( error == OTV_Err_Table_Missing ) |
|
53 return OTV_Err_Ok; |
|
54 if ( error ) |
|
55 goto Exit; |
|
56 |
|
57 if ( FT_ALLOC( *table, *table_len ) ) |
|
58 goto Exit; |
|
59 |
|
60 error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); |
|
61 |
|
62 Exit: |
|
63 return error; |
|
64 } |
|
65 |
|
66 |
|
67 static FT_Error |
|
68 otv_validate( FT_Face volatile face, |
|
69 FT_UInt ot_flags, |
|
70 FT_Bytes *ot_base, |
|
71 FT_Bytes *ot_gdef, |
|
72 FT_Bytes *ot_gpos, |
|
73 FT_Bytes *ot_gsub, |
|
74 FT_Bytes *ot_jstf ) |
|
75 { |
|
76 FT_Error error = OTV_Err_Ok; |
|
77 FT_Byte* volatile base; |
|
78 FT_Byte* volatile gdef; |
|
79 FT_Byte* volatile gpos; |
|
80 FT_Byte* volatile gsub; |
|
81 FT_Byte* volatile jstf; |
|
82 FT_Byte* volatile math; |
|
83 FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; |
|
84 FT_ULong len_math; |
|
85 FT_UInt num_glyphs = (FT_UInt)face->num_glyphs; |
|
86 FT_ValidatorRec volatile valid; |
|
87 |
|
88 |
|
89 base = gdef = gpos = gsub = jstf = math = NULL; |
|
90 len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; |
|
91 |
|
92 /* |
|
93 * XXX: OpenType tables cannot handle 32-bit glyph index, |
|
94 * although broken TrueType can have 32-bit glyph index. |
|
95 */ |
|
96 if ( face->num_glyphs > 0xFFFFL ) |
|
97 { |
|
98 FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", |
|
99 face->num_glyphs )); |
|
100 FT_TRACE1(( "are not handled by OpenType tables\n" )); |
|
101 num_glyphs = 0xFFFF; |
|
102 } |
|
103 |
|
104 /* load tables */ |
|
105 |
|
106 if ( ot_flags & FT_VALIDATE_BASE ) |
|
107 { |
|
108 error = otv_load_table( face, TTAG_BASE, &base, &len_base ); |
|
109 if ( error ) |
|
110 goto Exit; |
|
111 } |
|
112 |
|
113 if ( ot_flags & FT_VALIDATE_GDEF ) |
|
114 { |
|
115 error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef ); |
|
116 if ( error ) |
|
117 goto Exit; |
|
118 } |
|
119 |
|
120 if ( ot_flags & FT_VALIDATE_GPOS ) |
|
121 { |
|
122 error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos ); |
|
123 if ( error ) |
|
124 goto Exit; |
|
125 } |
|
126 |
|
127 if ( ot_flags & FT_VALIDATE_GSUB ) |
|
128 { |
|
129 error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub ); |
|
130 if ( error ) |
|
131 goto Exit; |
|
132 } |
|
133 |
|
134 if ( ot_flags & FT_VALIDATE_JSTF ) |
|
135 { |
|
136 error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf ); |
|
137 if ( error ) |
|
138 goto Exit; |
|
139 } |
|
140 |
|
141 if ( ot_flags & FT_VALIDATE_MATH ) |
|
142 { |
|
143 error = otv_load_table( face, TTAG_MATH, &math, &len_math ); |
|
144 if ( error ) |
|
145 goto Exit; |
|
146 } |
|
147 |
|
148 /* validate tables */ |
|
149 |
|
150 if ( base ) |
|
151 { |
|
152 ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); |
|
153 if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
|
154 otv_BASE_validate( base, &valid ); |
|
155 error = valid.error; |
|
156 if ( error ) |
|
157 goto Exit; |
|
158 } |
|
159 |
|
160 if ( gpos ) |
|
161 { |
|
162 ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); |
|
163 if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
|
164 otv_GPOS_validate( gpos, num_glyphs, &valid ); |
|
165 error = valid.error; |
|
166 if ( error ) |
|
167 goto Exit; |
|
168 } |
|
169 |
|
170 if ( gsub ) |
|
171 { |
|
172 ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); |
|
173 if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
|
174 otv_GSUB_validate( gsub, num_glyphs, &valid ); |
|
175 error = valid.error; |
|
176 if ( error ) |
|
177 goto Exit; |
|
178 } |
|
179 |
|
180 if ( gdef ) |
|
181 { |
|
182 ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); |
|
183 if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
|
184 otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid ); |
|
185 error = valid.error; |
|
186 if ( error ) |
|
187 goto Exit; |
|
188 } |
|
189 |
|
190 if ( jstf ) |
|
191 { |
|
192 ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); |
|
193 if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
|
194 otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid ); |
|
195 error = valid.error; |
|
196 if ( error ) |
|
197 goto Exit; |
|
198 } |
|
199 |
|
200 if ( math ) |
|
201 { |
|
202 ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); |
|
203 if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
|
204 otv_MATH_validate( math, num_glyphs, &valid ); |
|
205 error = valid.error; |
|
206 if ( error ) |
|
207 goto Exit; |
|
208 } |
|
209 |
|
210 *ot_base = (FT_Bytes)base; |
|
211 *ot_gdef = (FT_Bytes)gdef; |
|
212 *ot_gpos = (FT_Bytes)gpos; |
|
213 *ot_gsub = (FT_Bytes)gsub; |
|
214 *ot_jstf = (FT_Bytes)jstf; |
|
215 |
|
216 Exit: |
|
217 if ( error ) |
|
218 { |
|
219 FT_Memory memory = FT_FACE_MEMORY( face ); |
|
220 |
|
221 |
|
222 FT_FREE( base ); |
|
223 FT_FREE( gdef ); |
|
224 FT_FREE( gpos ); |
|
225 FT_FREE( gsub ); |
|
226 FT_FREE( jstf ); |
|
227 } |
|
228 |
|
229 { |
|
230 FT_Memory memory = FT_FACE_MEMORY( face ); |
|
231 |
|
232 |
|
233 FT_FREE( math ); /* Can't return this as API is frozen */ |
|
234 } |
|
235 |
|
236 return error; |
|
237 } |
|
238 |
|
239 |
|
240 static |
|
241 const FT_Service_OTvalidateRec otvalid_interface = |
|
242 { |
|
243 otv_validate |
|
244 }; |
|
245 |
|
246 |
|
247 static |
|
248 const FT_ServiceDescRec otvalid_services[] = |
|
249 { |
|
250 { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface }, |
|
251 { NULL, NULL } |
|
252 }; |
|
253 |
|
254 |
|
255 static FT_Pointer |
|
256 otvalid_get_service( FT_Module module, |
|
257 const char* service_id ) |
|
258 { |
|
259 FT_UNUSED( module ); |
|
260 |
|
261 return ft_service_list_lookup( otvalid_services, service_id ); |
|
262 } |
|
263 |
|
264 |
|
265 FT_CALLBACK_TABLE_DEF |
|
266 const FT_Module_Class otv_module_class = |
|
267 { |
|
268 0, |
|
269 sizeof( FT_ModuleRec ), |
|
270 "otvalid", |
|
271 0x10000L, |
|
272 0x20000L, |
|
273 |
|
274 0, /* module-specific interface */ |
|
275 |
|
276 (FT_Module_Constructor)0, |
|
277 (FT_Module_Destructor) 0, |
|
278 (FT_Module_Requester) otvalid_get_service |
|
279 }; |
|
280 |
|
281 |
|
282 /* END */ |
|