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_ValidatorRec volatile valid; |
---|
86 | |
---|
87 | |
---|
88 | base = gdef = gpos = gsub = jstf = math = NULL; |
---|
89 | len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; |
---|
90 | |
---|
91 | /* load tables */ |
---|
92 | |
---|
93 | if ( ot_flags & FT_VALIDATE_BASE ) |
---|
94 | { |
---|
95 | error = otv_load_table( face, TTAG_BASE, &base, &len_base ); |
---|
96 | if ( error ) |
---|
97 | goto Exit; |
---|
98 | } |
---|
99 | |
---|
100 | if ( ot_flags & FT_VALIDATE_GDEF ) |
---|
101 | { |
---|
102 | error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef ); |
---|
103 | if ( error ) |
---|
104 | goto Exit; |
---|
105 | } |
---|
106 | |
---|
107 | if ( ot_flags & FT_VALIDATE_GPOS ) |
---|
108 | { |
---|
109 | error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos ); |
---|
110 | if ( error ) |
---|
111 | goto Exit; |
---|
112 | } |
---|
113 | |
---|
114 | if ( ot_flags & FT_VALIDATE_GSUB ) |
---|
115 | { |
---|
116 | error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub ); |
---|
117 | if ( error ) |
---|
118 | goto Exit; |
---|
119 | } |
---|
120 | |
---|
121 | if ( ot_flags & FT_VALIDATE_JSTF ) |
---|
122 | { |
---|
123 | error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf ); |
---|
124 | if ( error ) |
---|
125 | goto Exit; |
---|
126 | } |
---|
127 | |
---|
128 | if ( ot_flags & FT_VALIDATE_MATH ) |
---|
129 | { |
---|
130 | error = otv_load_table( face, TTAG_MATH, &math, &len_math ); |
---|
131 | if ( error ) |
---|
132 | goto Exit; |
---|
133 | } |
---|
134 | |
---|
135 | /* validate tables */ |
---|
136 | |
---|
137 | if ( base ) |
---|
138 | { |
---|
139 | ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); |
---|
140 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
---|
141 | otv_BASE_validate( base, &valid ); |
---|
142 | error = valid.error; |
---|
143 | if ( error ) |
---|
144 | goto Exit; |
---|
145 | } |
---|
146 | |
---|
147 | if ( gpos ) |
---|
148 | { |
---|
149 | ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); |
---|
150 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
---|
151 | otv_GPOS_validate( gpos, face->num_glyphs, &valid ); |
---|
152 | error = valid.error; |
---|
153 | if ( error ) |
---|
154 | goto Exit; |
---|
155 | } |
---|
156 | |
---|
157 | if ( gsub ) |
---|
158 | { |
---|
159 | ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); |
---|
160 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
---|
161 | otv_GSUB_validate( gsub, face->num_glyphs, &valid ); |
---|
162 | error = valid.error; |
---|
163 | if ( error ) |
---|
164 | goto Exit; |
---|
165 | } |
---|
166 | |
---|
167 | if ( gdef ) |
---|
168 | { |
---|
169 | ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); |
---|
170 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
---|
171 | otv_GDEF_validate( gdef, gsub, gpos, face->num_glyphs, &valid ); |
---|
172 | error = valid.error; |
---|
173 | if ( error ) |
---|
174 | goto Exit; |
---|
175 | } |
---|
176 | |
---|
177 | if ( jstf ) |
---|
178 | { |
---|
179 | ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); |
---|
180 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
---|
181 | otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid ); |
---|
182 | error = valid.error; |
---|
183 | if ( error ) |
---|
184 | goto Exit; |
---|
185 | } |
---|
186 | |
---|
187 | if ( math ) |
---|
188 | { |
---|
189 | ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); |
---|
190 | if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
---|
191 | otv_MATH_validate( math, face->num_glyphs, &valid ); |
---|
192 | error = valid.error; |
---|
193 | if ( error ) |
---|
194 | goto Exit; |
---|
195 | } |
---|
196 | |
---|
197 | *ot_base = (FT_Bytes)base; |
---|
198 | *ot_gdef = (FT_Bytes)gdef; |
---|
199 | *ot_gpos = (FT_Bytes)gpos; |
---|
200 | *ot_gsub = (FT_Bytes)gsub; |
---|
201 | *ot_jstf = (FT_Bytes)jstf; |
---|
202 | |
---|
203 | Exit: |
---|
204 | if ( error ) { |
---|
205 | FT_Memory memory = FT_FACE_MEMORY( face ); |
---|
206 | |
---|
207 | |
---|
208 | FT_FREE( base ); |
---|
209 | FT_FREE( gdef ); |
---|
210 | FT_FREE( gpos ); |
---|
211 | FT_FREE( gsub ); |
---|
212 | FT_FREE( jstf ); |
---|
213 | } |
---|
214 | { |
---|
215 | FT_Memory memory = FT_FACE_MEMORY( face ); |
---|
216 | |
---|
217 | |
---|
218 | FT_FREE( math ); /* Can't return this as API is frozen */ |
---|
219 | } |
---|
220 | |
---|
221 | return error; |
---|
222 | } |
---|
223 | |
---|
224 | |
---|
225 | static |
---|
226 | const FT_Service_OTvalidateRec otvalid_interface = |
---|
227 | { |
---|
228 | otv_validate |
---|
229 | }; |
---|
230 | |
---|
231 | |
---|
232 | static |
---|
233 | const FT_ServiceDescRec otvalid_services[] = |
---|
234 | { |
---|
235 | { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface }, |
---|
236 | { NULL, NULL } |
---|
237 | }; |
---|
238 | |
---|
239 | |
---|
240 | static FT_Pointer |
---|
241 | otvalid_get_service( FT_Module module, |
---|
242 | const char* service_id ) |
---|
243 | { |
---|
244 | FT_UNUSED( module ); |
---|
245 | |
---|
246 | return ft_service_list_lookup( otvalid_services, service_id ); |
---|
247 | } |
---|
248 | |
---|
249 | |
---|
250 | FT_CALLBACK_TABLE_DEF |
---|
251 | const FT_Module_Class otv_module_class = |
---|
252 | { |
---|
253 | 0, |
---|
254 | sizeof( FT_ModuleRec ), |
---|
255 | "otvalid", |
---|
256 | 0x10000L, |
---|
257 | 0x20000L, |
---|
258 | |
---|
259 | 0, /* module-specific interface */ |
---|
260 | |
---|
261 | (FT_Module_Constructor)0, |
---|
262 | (FT_Module_Destructor) 0, |
---|
263 | (FT_Module_Requester) otvalid_get_service |
---|
264 | }; |
---|
265 | |
---|
266 | |
---|
267 | /* END */ |
---|