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 <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
otv_load_table(FT_Face face,FT_Tag tag,FT_Byte * volatile * table,FT_ULong * table_len)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
otv_validate(FT_Face volatile face,FT_UInt ot_flags,FT_Bytes * ot_base,FT_Bytes * ot_gdef,FT_Bytes * ot_gpos,FT_Bytes * ot_gsub,FT_Bytes * ot_jstf)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
otvalid_get_service(FT_Module module,const char * service_id)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 */
283