1 /***************************************************************************/ |
|
2 /* */ |
|
3 /* gxvmod.c */ |
|
4 /* */ |
|
5 /* FreeType's TrueTypeGX/AAT validation module implementation (body). */ |
|
6 /* */ |
|
7 /* Copyright 2004, 2005, 2006 */ |
|
8 /* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ |
|
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
|
10 /* */ |
|
11 /* This file is part of the FreeType project, and may only be used, */ |
|
12 /* modified, and distributed under the terms of the FreeType project */ |
|
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
|
14 /* this file you indicate that you have read the license and */ |
|
15 /* understand and accept it fully. */ |
|
16 /* */ |
|
17 /***************************************************************************/ |
|
18 |
|
19 /***************************************************************************/ |
|
20 /* */ |
|
21 /* gxvalid is derived from both gxlayout module and otvalid module. */ |
|
22 /* Development of gxlayout is supported by the Information-technology */ |
|
23 /* Promotion Agency(IPA), Japan. */ |
|
24 /* */ |
|
25 /***************************************************************************/ |
|
26 |
|
27 |
|
28 #include <ft2build.h> |
|
29 #include FT_TRUETYPE_TABLES_H |
|
30 #include FT_TRUETYPE_TAGS_H |
|
31 #include FT_GX_VALIDATE_H |
|
32 #include FT_INTERNAL_OBJECTS_H |
|
33 #include FT_SERVICE_GX_VALIDATE_H |
|
34 |
|
35 #include "gxvmod.h" |
|
36 #include "gxvalid.h" |
|
37 #include "gxvcommn.h" |
|
38 |
|
39 |
|
40 /*************************************************************************/ |
|
41 /* */ |
|
42 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
|
43 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
|
44 /* messages during execution. */ |
|
45 /* */ |
|
46 #undef FT_COMPONENT |
|
47 #define FT_COMPONENT trace_gxvmodule |
|
48 |
|
49 |
|
50 static FT_Error |
|
51 gxv_load_table( FT_Face face, |
|
52 FT_Tag tag, |
|
53 FT_Byte* volatile* table, |
|
54 FT_ULong* table_len ) |
|
55 { |
|
56 FT_Error error; |
|
57 FT_Memory memory = FT_FACE_MEMORY( face ); |
|
58 |
|
59 |
|
60 error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); |
|
61 if ( error == GXV_Err_Table_Missing ) |
|
62 return GXV_Err_Ok; |
|
63 if ( error ) |
|
64 goto Exit; |
|
65 |
|
66 if ( FT_ALLOC( *table, *table_len ) ) |
|
67 goto Exit; |
|
68 |
|
69 error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); |
|
70 |
|
71 Exit: |
|
72 return error; |
|
73 } |
|
74 |
|
75 |
|
76 #define GXV_TABLE_DECL( _sfnt ) \ |
|
77 FT_Byte* volatile _sfnt = NULL; \ |
|
78 FT_ULong len_ ## _sfnt = 0 |
|
79 |
|
80 #define GXV_TABLE_LOAD( _sfnt ) \ |
|
81 if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \ |
|
82 ( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \ |
|
83 { \ |
|
84 error = gxv_load_table( face, TTAG_ ## _sfnt, \ |
|
85 &_sfnt, &len_ ## _sfnt ); \ |
|
86 if ( error ) \ |
|
87 goto Exit; \ |
|
88 } |
|
89 |
|
90 #define GXV_TABLE_VALIDATE( _sfnt ) \ |
|
91 if ( _sfnt ) \ |
|
92 { \ |
|
93 ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \ |
|
94 FT_VALIDATE_DEFAULT ); \ |
|
95 if ( ft_setjmp( valid.jump_buffer ) == 0 ) \ |
|
96 gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \ |
|
97 error = valid.error; \ |
|
98 if ( error ) \ |
|
99 goto Exit; \ |
|
100 } |
|
101 |
|
102 #define GXV_TABLE_SET( _sfnt ) \ |
|
103 if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) \ |
|
104 tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt |
|
105 |
|
106 |
|
107 static FT_Error |
|
108 gxv_validate( FT_Face face, |
|
109 FT_UInt gx_flags, |
|
110 FT_Bytes tables[FT_VALIDATE_GX_LENGTH], |
|
111 FT_UInt table_count ) |
|
112 { |
|
113 FT_Memory volatile memory = FT_FACE_MEMORY( face ); |
|
114 |
|
115 FT_Error error = GXV_Err_Ok; |
|
116 FT_ValidatorRec volatile valid; |
|
117 |
|
118 FT_UInt i; |
|
119 |
|
120 |
|
121 GXV_TABLE_DECL( feat ); |
|
122 GXV_TABLE_DECL( bsln ); |
|
123 GXV_TABLE_DECL( trak ); |
|
124 GXV_TABLE_DECL( just ); |
|
125 GXV_TABLE_DECL( mort ); |
|
126 GXV_TABLE_DECL( morx ); |
|
127 GXV_TABLE_DECL( kern ); |
|
128 GXV_TABLE_DECL( opbd ); |
|
129 GXV_TABLE_DECL( prop ); |
|
130 GXV_TABLE_DECL( lcar ); |
|
131 |
|
132 for ( i = 0; i < table_count; i++ ) |
|
133 tables[i] = 0; |
|
134 |
|
135 /* load tables */ |
|
136 GXV_TABLE_LOAD( feat ); |
|
137 GXV_TABLE_LOAD( bsln ); |
|
138 GXV_TABLE_LOAD( trak ); |
|
139 GXV_TABLE_LOAD( just ); |
|
140 GXV_TABLE_LOAD( mort ); |
|
141 GXV_TABLE_LOAD( morx ); |
|
142 GXV_TABLE_LOAD( kern ); |
|
143 GXV_TABLE_LOAD( opbd ); |
|
144 GXV_TABLE_LOAD( prop ); |
|
145 GXV_TABLE_LOAD( lcar ); |
|
146 |
|
147 /* validate tables */ |
|
148 GXV_TABLE_VALIDATE( feat ); |
|
149 GXV_TABLE_VALIDATE( bsln ); |
|
150 GXV_TABLE_VALIDATE( trak ); |
|
151 GXV_TABLE_VALIDATE( just ); |
|
152 GXV_TABLE_VALIDATE( mort ); |
|
153 GXV_TABLE_VALIDATE( morx ); |
|
154 GXV_TABLE_VALIDATE( kern ); |
|
155 GXV_TABLE_VALIDATE( opbd ); |
|
156 GXV_TABLE_VALIDATE( prop ); |
|
157 GXV_TABLE_VALIDATE( lcar ); |
|
158 |
|
159 /* Set results */ |
|
160 GXV_TABLE_SET( feat ); |
|
161 GXV_TABLE_SET( mort ); |
|
162 GXV_TABLE_SET( morx ); |
|
163 GXV_TABLE_SET( bsln ); |
|
164 GXV_TABLE_SET( just ); |
|
165 GXV_TABLE_SET( kern ); |
|
166 GXV_TABLE_SET( opbd ); |
|
167 GXV_TABLE_SET( trak ); |
|
168 GXV_TABLE_SET( prop ); |
|
169 GXV_TABLE_SET( lcar ); |
|
170 |
|
171 Exit: |
|
172 if ( error ) |
|
173 { |
|
174 FT_FREE( feat ); |
|
175 FT_FREE( bsln ); |
|
176 FT_FREE( trak ); |
|
177 FT_FREE( just ); |
|
178 FT_FREE( mort ); |
|
179 FT_FREE( morx ); |
|
180 FT_FREE( kern ); |
|
181 FT_FREE( opbd ); |
|
182 FT_FREE( prop ); |
|
183 FT_FREE( lcar ); |
|
184 } |
|
185 |
|
186 return error; |
|
187 } |
|
188 |
|
189 |
|
190 static FT_Error |
|
191 classic_kern_validate( FT_Face face, |
|
192 FT_UInt ckern_flags, |
|
193 FT_Bytes* ckern_table ) |
|
194 { |
|
195 FT_Memory volatile memory = FT_FACE_MEMORY( face ); |
|
196 |
|
197 FT_Byte* volatile ckern = NULL; |
|
198 FT_ULong len_ckern = 0; |
|
199 |
|
200 /* without volatile on `error' GCC 4.1.1. emits: */ |
|
201 /* warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */ |
|
202 /* this warning seems spurious but --- */ |
|
203 FT_Error volatile error = GXV_Err_Ok; |
|
204 FT_ValidatorRec volatile valid; |
|
205 |
|
206 |
|
207 *ckern_table = NULL; |
|
208 |
|
209 error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern ); |
|
210 if ( error ) |
|
211 goto Exit; |
|
212 |
|
213 if ( ckern ) |
|
214 { |
|
215 ft_validator_init( &valid, ckern, ckern + len_ckern, |
|
216 FT_VALIDATE_DEFAULT ); |
|
217 if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
|
218 gxv_kern_validate_classic( ckern, face, |
|
219 ckern_flags & FT_VALIDATE_CKERN, &valid ); |
|
220 error = valid.error; |
|
221 if ( error ) |
|
222 goto Exit; |
|
223 } |
|
224 |
|
225 *ckern_table = ckern; |
|
226 |
|
227 Exit: |
|
228 if ( error ) |
|
229 FT_FREE( ckern ); |
|
230 |
|
231 return error; |
|
232 } |
|
233 |
|
234 |
|
235 static |
|
236 const FT_Service_GXvalidateRec gxvalid_interface = |
|
237 { |
|
238 gxv_validate |
|
239 }; |
|
240 |
|
241 |
|
242 static |
|
243 const FT_Service_CKERNvalidateRec ckernvalid_interface = |
|
244 { |
|
245 classic_kern_validate |
|
246 }; |
|
247 |
|
248 |
|
249 static |
|
250 const FT_ServiceDescRec gxvalid_services[] = |
|
251 { |
|
252 { FT_SERVICE_ID_GX_VALIDATE, &gxvalid_interface }, |
|
253 { FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface }, |
|
254 { NULL, NULL } |
|
255 }; |
|
256 |
|
257 |
|
258 static FT_Pointer |
|
259 gxvalid_get_service( FT_Module module, |
|
260 const char* service_id ) |
|
261 { |
|
262 FT_UNUSED( module ); |
|
263 |
|
264 return ft_service_list_lookup( gxvalid_services, service_id ); |
|
265 } |
|
266 |
|
267 |
|
268 FT_CALLBACK_TABLE_DEF |
|
269 const FT_Module_Class gxv_module_class = |
|
270 { |
|
271 0, |
|
272 sizeof( FT_ModuleRec ), |
|
273 "gxvalid", |
|
274 0x10000L, |
|
275 0x20000L, |
|
276 |
|
277 0, /* module-specific interface */ |
|
278 |
|
279 (FT_Module_Constructor)0, |
|
280 (FT_Module_Destructor) 0, |
|
281 (FT_Module_Requester) gxvalid_get_service |
|
282 }; |
|
283 |
|
284 |
|
285 /* END */ |
|