Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3918 | Serge | 1 | /***************************************************************************/ |
2 | /* */ |
||
3 | /* otvmod.c */ |
||
4 | /* */ |
||
5 | /* FreeType's OpenType validation module implementation (body). */ |
||
6 | /* */ |
||
7 | /* Copyright 2004-2008, 2013 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 |
||
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 ( FT_ERR_EQ( error, Table_Missing ) ) |
||
53 | return FT_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 = FT_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 */ |