1 /***************************************************************************/
2 /*                                                                         */
3 /*  gxvmod.c                                                               */
4 /*                                                                         */
5 /*    FreeType's TrueTypeGX/AAT validation module implementation (body).   */
6 /*                                                                         */
7 /*  Copyright 2004-2006, 2013                                              */
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
gxv_load_table(FT_Face face,FT_Tag tag,FT_Byte * volatile * table,FT_ULong * table_len)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 ( FT_ERR_EQ( error, Table_Missing ) )
62       return FT_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
gxv_validate(FT_Face face,FT_UInt gx_flags,FT_Bytes tables[FT_VALIDATE_GX_LENGTH],FT_UInt table_count)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 = FT_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
classic_kern_validate(FT_Face face,FT_UInt ckern_flags,FT_Bytes * ckern_table)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;
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
gxvalid_get_service(FT_Module module,const char * service_id)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 */
286