Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / freetype2 / src / src / gxvalid / gxvmort.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  gxvmort.c                                                              */
4 /*                                                                         */
5 /*    TrueTypeGX/AAT mort table validation (body).                         */
6 /*                                                                         */
7 /*  Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K.,       */
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 /*                                                                         */
20 /* gxvalid is derived from both gxlayout module and otvalid module.        */
21 /* Development of gxlayout is supported by the Information-technology      */
22 /* Promotion Agency(IPA), Japan.                                           */
23 /*                                                                         */
24 /***************************************************************************/
25
26
27 #include "gxvmort.h"
28 #include "gxvfeat.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_gxvmort
39
40
41   static void
42   gxv_mort_feature_validate( GXV_mort_feature  f,
43                              GXV_Validator     valid )
44   {
45     if ( f->featureType >= gxv_feat_registry_length )
46     {
47       GXV_TRACE(( "featureType %d is out of registered range, "
48                   "setting %d is unchecked\n",
49                   f->featureType, f->featureSetting ));
50       GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
51     }
52     else if ( !gxv_feat_registry[f->featureType].existence )
53     {
54       GXV_TRACE(( "featureType %d is within registered area "
55                   "but undefined, setting %d is unchecked\n",
56                   f->featureType, f->featureSetting ));
57       GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
58     }
59     else
60     {
61       FT_Byte  nSettings_max;
62
63
64       /* nSettings in gxvfeat.c is halved for exclusive on/off settings */
65       nSettings_max = gxv_feat_registry[f->featureType].nSettings;
66       if ( gxv_feat_registry[f->featureType].exclusive )
67         nSettings_max = (FT_Byte)( 2 * nSettings_max );
68
69       GXV_TRACE(( "featureType %d is registered", f->featureType ));
70       GXV_TRACE(( "setting %d", f->featureSetting ));
71
72       if ( f->featureSetting > nSettings_max )
73       {
74         GXV_TRACE(( "out of defined range %d", nSettings_max ));
75         GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
76       }
77       GXV_TRACE(( "\n" ));
78     }
79
80     /* TODO: enableFlags must be unique value in specified chain?  */
81   }
82
83
84   /*
85    * nFeatureFlags is typed to FT_ULong to accept that in
86    * mort (typed FT_UShort) and morx (typed FT_ULong).
87    */
88   FT_LOCAL_DEF( void )
89   gxv_mort_featurearray_validate( FT_Bytes       table,
90                                   FT_Bytes       limit,
91                                   FT_ULong       nFeatureFlags,
92                                   GXV_Validator  valid )
93   {
94     FT_Bytes  p = table;
95     FT_ULong  i;
96
97     GXV_mort_featureRec  f = GXV_MORT_FEATURE_OFF;
98
99
100     GXV_NAME_ENTER( "mort feature list" );
101     for ( i = 0; i < nFeatureFlags; i++ )
102     {
103       GXV_LIMIT_CHECK( 2 + 2 + 4 + 4 );
104       f.featureType    = FT_NEXT_USHORT( p );
105       f.featureSetting = FT_NEXT_USHORT( p );
106       f.enableFlags    = FT_NEXT_ULONG( p );
107       f.disableFlags   = FT_NEXT_ULONG( p );
108
109       gxv_mort_feature_validate( &f, valid );
110     }
111
112     if ( !IS_GXV_MORT_FEATURE_OFF( f ) )
113       FT_INVALID_DATA;
114
115     valid->subtable_length = p - table;
116     GXV_EXIT;
117   }
118
119
120   FT_LOCAL_DEF( void )
121   gxv_mort_coverage_validate( FT_UShort      coverage,
122                               GXV_Validator  valid )
123   {
124     FT_UNUSED( valid );
125
126     if ( coverage & 0x8000U )
127       GXV_TRACE(( " this subtable is for vertical text only\n" ));
128     else
129       GXV_TRACE(( " this subtable is for horizontal text only\n" ));
130
131     if ( coverage & 0x4000 )
132       GXV_TRACE(( " this subtable is applied to glyph array "
133                   "in descending order\n" ));
134     else
135       GXV_TRACE(( " this subtable is applied to glyph array "
136                   "in ascending order\n" ));
137
138     if ( coverage & 0x2000 )
139       GXV_TRACE(( " this subtable is forcibly applied to "
140                   "vertical/horizontal text\n" ));
141
142     if ( coverage & 0x1FF8 )
143       GXV_TRACE(( " coverage has non-zero bits in reserved area\n" ));
144   }
145
146
147   static void
148   gxv_mort_subtables_validate( FT_Bytes       table,
149                                FT_Bytes       limit,
150                                FT_UShort      nSubtables,
151                                GXV_Validator  valid )
152   {
153     FT_Bytes  p = table;
154
155     GXV_Validate_Func fmt_funcs_table[] =
156     {
157       gxv_mort_subtable_type0_validate, /* 0 */
158       gxv_mort_subtable_type1_validate, /* 1 */
159       gxv_mort_subtable_type2_validate, /* 2 */
160       NULL,                             /* 3 */
161       gxv_mort_subtable_type4_validate, /* 4 */
162       gxv_mort_subtable_type5_validate, /* 5 */
163
164     };
165
166     GXV_Validate_Func  func;
167     FT_UShort          i;
168
169
170     GXV_NAME_ENTER( "subtables in a chain" );
171
172     for ( i = 0; i < nSubtables; i++ )
173     {
174       FT_UShort  length;
175       FT_UShort  coverage;
176 #ifdef GXV_LOAD_UNUSED_VARS
177       FT_ULong   subFeatureFlags;
178 #endif
179       FT_UInt    type;
180       FT_UInt    rest;
181
182
183       GXV_LIMIT_CHECK( 2 + 2 + 4 );
184       length          = FT_NEXT_USHORT( p );
185       coverage        = FT_NEXT_USHORT( p );
186 #ifdef GXV_LOAD_UNUSED_VARS
187       subFeatureFlags = FT_NEXT_ULONG( p );
188 #else
189       p += 4;
190 #endif
191
192       GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n",
193                   i + 1, nSubtables, length ));
194       type = coverage & 0x0007;
195       rest = length - ( 2 + 2 + 4 );
196
197       GXV_LIMIT_CHECK( rest );
198       gxv_mort_coverage_validate( coverage, valid );
199
200       if ( type > 5 )
201         FT_INVALID_FORMAT;
202
203       func = fmt_funcs_table[type];
204       if ( func == NULL )
205         GXV_TRACE(( "morx type %d is reserved\n", type ));
206
207       func( p, p + rest, valid );
208
209       p += rest;
210       /* TODO: validate subFeatureFlags */
211     }
212
213     valid->subtable_length = p - table;
214
215     GXV_EXIT;
216   }
217
218
219   static void
220   gxv_mort_chain_validate( FT_Bytes       table,
221                            FT_Bytes       limit,
222                            GXV_Validator  valid )
223   {
224     FT_Bytes   p = table;
225 #ifdef GXV_LOAD_UNUSED_VARS
226     FT_ULong   defaultFlags;
227 #endif
228     FT_ULong   chainLength;
229     FT_UShort  nFeatureFlags;
230     FT_UShort  nSubtables;
231
232
233     GXV_NAME_ENTER( "mort chain header" );
234
235     GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
236 #ifdef GXV_LOAD_UNUSED_VARS
237     defaultFlags  = FT_NEXT_ULONG( p );
238 #else
239     p += 4;
240 #endif
241     chainLength   = FT_NEXT_ULONG( p );
242     nFeatureFlags = FT_NEXT_USHORT( p );
243     nSubtables    = FT_NEXT_USHORT( p );
244
245     gxv_mort_featurearray_validate( p, table + chainLength,
246                                     nFeatureFlags, valid );
247     p += valid->subtable_length;
248     gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid );
249     valid->subtable_length = chainLength;
250
251     /* TODO: validate defaultFlags */
252     GXV_EXIT;
253   }
254
255
256   FT_LOCAL_DEF( void )
257   gxv_mort_validate( FT_Bytes      table,
258                      FT_Face       face,
259                      FT_Validator  ftvalid )
260   {
261     GXV_ValidatorRec  validrec;
262     GXV_Validator     valid = &validrec;
263     FT_Bytes          p     = table;
264     FT_Bytes          limit = 0;
265     FT_ULong          version;
266     FT_ULong          nChains;
267     FT_ULong          i;
268
269
270     valid->root = ftvalid;
271     valid->face = face;
272     limit       = valid->root->limit;
273
274     FT_TRACE3(( "validating `mort' table\n" ));
275     GXV_INIT;
276
277     GXV_LIMIT_CHECK( 4 + 4 );
278     version = FT_NEXT_ULONG( p );
279     nChains = FT_NEXT_ULONG( p );
280
281     if (version != 0x00010000UL)
282       FT_INVALID_FORMAT;
283
284     for ( i = 0; i < nChains; i++ )
285     {
286       GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains ));
287       GXV_32BIT_ALIGNMENT_VALIDATE( p - table );
288       gxv_mort_chain_validate( p, limit, valid );
289       p += valid->subtable_length;
290     }
291
292     FT_TRACE4(( "\n" ));
293   }
294
295
296 /* END */