Sync with trunk head (part 1 or 2)
[reactos.git] / lib / 3rdparty / freetype / src / gxvalid / gxvmorx.c
1 /***************************************************************************/
2 /* */
3 /* gxvmorx.c */
4 /* */
5 /* TrueTypeGX/AAT morx 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 "gxvmorx.h"
28
29
30 /*************************************************************************/
31 /* */
32 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
33 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
34 /* messages during execution. */
35 /* */
36 #undef FT_COMPONENT
37 #define FT_COMPONENT trace_gxvmorx
38
39
40 static void
41 gxv_morx_subtables_validate( FT_Bytes table,
42 FT_Bytes limit,
43 FT_UShort nSubtables,
44 GXV_Validator valid )
45 {
46 FT_Bytes p = table;
47
48 GXV_Validate_Func fmt_funcs_table[] =
49 {
50 gxv_morx_subtable_type0_validate, /* 0 */
51 gxv_morx_subtable_type1_validate, /* 1 */
52 gxv_morx_subtable_type2_validate, /* 2 */
53 NULL, /* 3 */
54 gxv_morx_subtable_type4_validate, /* 4 */
55 gxv_morx_subtable_type5_validate, /* 5 */
56
57 };
58
59 GXV_Validate_Func func;
60
61 FT_UShort i;
62
63
64 GXV_NAME_ENTER( "subtables in a chain" );
65
66 for ( i = 0; i < nSubtables; i++ )
67 {
68 FT_ULong length;
69 FT_ULong coverage;
70 FT_ULong subFeatureFlags;
71 FT_UInt type;
72 FT_UInt rest;
73
74
75 GXV_LIMIT_CHECK( 4 + 4 + 4 );
76 length = FT_NEXT_ULONG( p );
77 coverage = FT_NEXT_ULONG( p );
78 subFeatureFlags = FT_NEXT_ULONG( p );
79
80 GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n",
81 i + 1, nSubtables, length ));
82
83 type = coverage & 0x0007;
84 rest = length - ( 4 + 4 + 4 );
85 GXV_LIMIT_CHECK( rest );
86
87 /* morx coverage consists of mort_coverage & 16bit padding */
88 gxv_mort_coverage_validate( (FT_UShort)( ( coverage >> 16 ) | coverage ),
89 valid );
90 if ( type > 5 )
91 FT_INVALID_FORMAT;
92
93 func = fmt_funcs_table[type];
94 if ( func == NULL )
95 GXV_TRACE(( "morx type %d is reserved\n", type ));
96
97 func( p, p + rest, valid );
98
99 p += rest;
100 }
101
102 valid->subtable_length = p - table;
103
104 GXV_EXIT;
105 }
106
107
108 static void
109 gxv_morx_chain_validate( FT_Bytes table,
110 FT_Bytes limit,
111 GXV_Validator valid )
112 {
113 FT_Bytes p = table;
114 FT_ULong defaultFlags;
115 FT_ULong chainLength;
116 FT_ULong nFeatureFlags;
117 FT_ULong nSubtables;
118
119
120 GXV_NAME_ENTER( "morx chain header" );
121
122 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
123 defaultFlags = FT_NEXT_ULONG( p );
124 chainLength = FT_NEXT_ULONG( p );
125 nFeatureFlags = FT_NEXT_ULONG( p );
126 nSubtables = FT_NEXT_ULONG( p );
127
128 /* feature-array of morx is same with that of mort */
129 gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid );
130 p += valid->subtable_length;
131
132 if ( nSubtables >= 0x10000 )
133 FT_INVALID_DATA;
134
135 gxv_morx_subtables_validate( p, table + chainLength,
136 (FT_UShort)nSubtables, valid );
137
138 valid->subtable_length = chainLength;
139
140 GXV_EXIT;
141 }
142
143
144 FT_LOCAL_DEF( void )
145 gxv_morx_validate( FT_Bytes table,
146 FT_Face face,
147 FT_Validator ftvalid )
148 {
149 GXV_ValidatorRec validrec;
150 GXV_Validator valid = &validrec;
151 FT_Bytes p = table;
152 FT_Bytes limit = 0;
153 FT_ULong version;
154 FT_ULong nChains;
155 FT_ULong i;
156
157
158 valid->root = ftvalid;
159 valid->face = face;
160
161 FT_TRACE3(( "validating `morx' table\n" ));
162 GXV_INIT;
163
164 GXV_LIMIT_CHECK( 4 + 4 );
165 version = FT_NEXT_ULONG( p );
166 nChains = FT_NEXT_ULONG( p );
167
168 if ( version != 0x00020000UL )
169 FT_INVALID_FORMAT;
170
171 for ( i = 0; i < nChains; i++ )
172 {
173 GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains ));
174 GXV_32BIT_ALIGNMENT_VALIDATE( p - table );
175 gxv_morx_chain_validate( p, limit, valid );
176 p += valid->subtable_length;
177 }
178
179 FT_TRACE4(( "\n" ));
180 }
181
182
183 /* END */