1 | /**************************************************************************** |
2 | * |
3 | * gxvmod.c |
4 | * |
5 | * FreeType's TrueTypeGX/AAT validation module implementation (body). |
6 | * |
7 | * Copyright (C) 2004-2023 by |
8 | * 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 <freetype/tttables.h> |
29 | #include <freetype/tttags.h> |
30 | #include <freetype/ftgxval.h> |
31 | #include <freetype/internal/ftobjs.h> |
32 | #include <freetype/internal/services/svgxval.h> |
33 | |
34 | #include "gxvmod.h" |
35 | #include "gxvalid.h" |
36 | #include "gxvcommn.h" |
37 | |
38 | |
39 | /************************************************************************** |
40 | * |
41 | * The macro FT_COMPONENT is used in trace mode. It is an implicit |
42 | * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
43 | * messages during execution. |
44 | */ |
45 | #undef FT_COMPONENT |
46 | #define FT_COMPONENT gxvmodule |
47 | |
48 | |
49 | static FT_Error |
50 | gxv_load_table( FT_Face face, |
51 | FT_Tag tag, |
52 | FT_Byte* volatile* table, |
53 | FT_ULong* table_len ) |
54 | { |
55 | FT_Error error; |
56 | FT_Memory memory = FT_FACE_MEMORY( face ); |
57 | |
58 | |
59 | error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); |
60 | if ( FT_ERR_EQ( error, Table_Missing ) ) |
61 | return FT_Err_Ok; |
62 | if ( error ) |
63 | goto Exit; |
64 | |
65 | if ( FT_QALLOC( *table, *table_len ) ) |
66 | goto Exit; |
67 | |
68 | error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); |
69 | |
70 | Exit: |
71 | return error; |
72 | } |
73 | |
74 | |
75 | #define GXV_TABLE_DECL( _sfnt ) \ |
76 | FT_Byte* volatile _sfnt = NULL; \ |
77 | FT_ULong len_ ## _sfnt = 0 |
78 | |
79 | #define GXV_TABLE_LOAD( _sfnt ) \ |
80 | FT_BEGIN_STMNT \ |
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 | FT_END_STMNT |
90 | |
91 | #define GXV_TABLE_VALIDATE( _sfnt ) \ |
92 | FT_BEGIN_STMNT \ |
93 | if ( _sfnt ) \ |
94 | { \ |
95 | ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \ |
96 | FT_VALIDATE_DEFAULT ); \ |
97 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) \ |
98 | gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \ |
99 | error = valid.error; \ |
100 | if ( error ) \ |
101 | goto Exit; \ |
102 | } \ |
103 | FT_END_STMNT |
104 | |
105 | #define GXV_TABLE_SET( _sfnt ) \ |
106 | if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) \ |
107 | tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt |
108 | |
109 | |
110 | static FT_Error |
111 | gxv_validate( FT_Face face, |
112 | FT_UInt gx_flags, |
113 | FT_Bytes tables[FT_VALIDATE_GX_LENGTH], |
114 | FT_UInt table_count ) |
115 | { |
116 | FT_Memory volatile memory = FT_FACE_MEMORY( face ); |
117 | |
118 | FT_Error error = FT_Err_Ok; |
119 | FT_ValidatorRec volatile valid; |
120 | |
121 | FT_UInt i; |
122 | |
123 | |
124 | GXV_TABLE_DECL( feat ); |
125 | GXV_TABLE_DECL( bsln ); |
126 | GXV_TABLE_DECL( trak ); |
127 | GXV_TABLE_DECL( just ); |
128 | GXV_TABLE_DECL( mort ); |
129 | GXV_TABLE_DECL( morx ); |
130 | GXV_TABLE_DECL( kern ); |
131 | GXV_TABLE_DECL( opbd ); |
132 | GXV_TABLE_DECL( prop ); |
133 | GXV_TABLE_DECL( lcar ); |
134 | |
135 | for ( i = 0; i < table_count; i++ ) |
136 | tables[i] = 0; |
137 | |
138 | /* load tables */ |
139 | GXV_TABLE_LOAD( feat ); |
140 | GXV_TABLE_LOAD( bsln ); |
141 | GXV_TABLE_LOAD( trak ); |
142 | GXV_TABLE_LOAD( just ); |
143 | GXV_TABLE_LOAD( mort ); |
144 | GXV_TABLE_LOAD( morx ); |
145 | GXV_TABLE_LOAD( kern ); |
146 | GXV_TABLE_LOAD( opbd ); |
147 | GXV_TABLE_LOAD( prop ); |
148 | GXV_TABLE_LOAD( lcar ); |
149 | |
150 | /* validate tables */ |
151 | GXV_TABLE_VALIDATE( feat ); |
152 | GXV_TABLE_VALIDATE( bsln ); |
153 | GXV_TABLE_VALIDATE( trak ); |
154 | GXV_TABLE_VALIDATE( just ); |
155 | GXV_TABLE_VALIDATE( mort ); |
156 | GXV_TABLE_VALIDATE( morx ); |
157 | GXV_TABLE_VALIDATE( kern ); |
158 | GXV_TABLE_VALIDATE( opbd ); |
159 | GXV_TABLE_VALIDATE( prop ); |
160 | GXV_TABLE_VALIDATE( lcar ); |
161 | |
162 | /* Set results */ |
163 | GXV_TABLE_SET( feat ); |
164 | GXV_TABLE_SET( mort ); |
165 | GXV_TABLE_SET( morx ); |
166 | GXV_TABLE_SET( bsln ); |
167 | GXV_TABLE_SET( just ); |
168 | GXV_TABLE_SET( kern ); |
169 | GXV_TABLE_SET( opbd ); |
170 | GXV_TABLE_SET( trak ); |
171 | GXV_TABLE_SET( prop ); |
172 | GXV_TABLE_SET( lcar ); |
173 | |
174 | Exit: |
175 | if ( error ) |
176 | { |
177 | FT_FREE( feat ); |
178 | FT_FREE( bsln ); |
179 | FT_FREE( trak ); |
180 | FT_FREE( just ); |
181 | FT_FREE( mort ); |
182 | FT_FREE( morx ); |
183 | FT_FREE( kern ); |
184 | FT_FREE( opbd ); |
185 | FT_FREE( prop ); |
186 | FT_FREE( lcar ); |
187 | } |
188 | |
189 | return error; |
190 | } |
191 | |
192 | |
193 | static FT_Error |
194 | classic_kern_validate( FT_Face face, |
195 | FT_UInt ckern_flags, |
196 | FT_Bytes* ckern_table ) |
197 | { |
198 | FT_Memory volatile memory = FT_FACE_MEMORY( face ); |
199 | |
200 | FT_Byte* volatile ckern = NULL; |
201 | FT_ULong len_ckern = 0; |
202 | |
203 | /* without volatile on `error' GCC 4.1.1. emits: */ |
204 | /* warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */ |
205 | /* this warning seems spurious but --- */ |
206 | FT_Error volatile error; |
207 | FT_ValidatorRec volatile valid; |
208 | |
209 | |
210 | *ckern_table = NULL; |
211 | |
212 | error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern ); |
213 | if ( error ) |
214 | goto Exit; |
215 | |
216 | if ( ckern ) |
217 | { |
218 | ft_validator_init( &valid, ckern, ckern + len_ckern, |
219 | FT_VALIDATE_DEFAULT ); |
220 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
221 | gxv_kern_validate_classic( ckern, face, |
222 | ckern_flags & FT_VALIDATE_CKERN, &valid ); |
223 | error = valid.error; |
224 | if ( error ) |
225 | goto Exit; |
226 | } |
227 | |
228 | *ckern_table = ckern; |
229 | |
230 | Exit: |
231 | if ( error ) |
232 | FT_FREE( ckern ); |
233 | |
234 | return error; |
235 | } |
236 | |
237 | |
238 | static |
239 | const FT_Service_GXvalidateRec gxvalid_interface = |
240 | { |
241 | gxv_validate /* validate */ |
242 | }; |
243 | |
244 | |
245 | static |
246 | const FT_Service_CKERNvalidateRec ckernvalid_interface = |
247 | { |
248 | classic_kern_validate /* validate */ |
249 | }; |
250 | |
251 | |
252 | static |
253 | const FT_ServiceDescRec gxvalid_services[] = |
254 | { |
255 | { FT_SERVICE_ID_GX_VALIDATE, &gxvalid_interface }, |
256 | { FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface }, |
257 | { NULL, NULL } |
258 | }; |
259 | |
260 | |
261 | static FT_Pointer |
262 | gxvalid_get_service( FT_Module module, |
263 | const char* service_id ) |
264 | { |
265 | FT_UNUSED( module ); |
266 | |
267 | return ft_service_list_lookup( gxvalid_services, service_id ); |
268 | } |
269 | |
270 | |
271 | FT_CALLBACK_TABLE_DEF |
272 | const FT_Module_Class gxv_module_class = |
273 | { |
274 | 0, |
275 | sizeof ( FT_ModuleRec ), |
276 | "gxvalid" , |
277 | 0x10000L, |
278 | 0x20000L, |
279 | |
280 | NULL, /* module-specific interface */ |
281 | |
282 | (FT_Module_Constructor)NULL, /* module_init */ |
283 | (FT_Module_Destructor) NULL, /* module_done */ |
284 | (FT_Module_Requester) gxvalid_get_service /* get_interface */ |
285 | }; |
286 | |
287 | |
288 | /* END */ |
289 | |