Imported Upstream version 2.13.2
[platform/upstream/freetype2.git] / src / gxvalid / gxvmod.c
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 */