- Remove svn:needs-lock, svn:eol-type, and svn:eol-tyle properties.
[reactos.git] / reactos / lib / 3rdparty / freetype / src / gxvalid / gxvmod.c
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 */