17 |
/***************************************************************************/ |
/***************************************************************************/ |
18 |
|
|
19 |
/***************************************************************************/ |
/***************************************************************************/ |
20 |
|
/* */ |
21 |
/* gxvalid is derived from both gxlayout module and otvalid module. */ |
/* gxvalid is derived from both gxlayout module and otvalid module. */ |
22 |
/* Development of gxlayout was support of Information-technology Promotion */ |
/* Development of gxlayout is supported by the Information-technology */ |
23 |
/* Agency(IPA), Japan. */ |
/* Promotion Agency(IPA), Japan. */ |
24 |
|
/* */ |
25 |
/***************************************************************************/ |
/***************************************************************************/ |
26 |
|
|
27 |
|
|
28 |
#include "gxvmort.h" |
#include "gxvmort.h" |
29 |
|
|
30 |
|
|
31 |
/*************************************************************************/ |
/*************************************************************************/ |
32 |
/* */ |
/* */ |
33 |
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
50 |
} GXV_mort_subtable_type2_StateOptRec, |
} GXV_mort_subtable_type2_StateOptRec, |
51 |
*GXV_mort_subtable_type2_StateOptRecData; |
*GXV_mort_subtable_type2_StateOptRecData; |
52 |
|
|
53 |
#define GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ( GXV_STATETABLE_HEADER_SIZE + 2 + 2 + 2 ) |
#define GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE \ |
54 |
|
GXV_STATETABLE_HEADER_SIZE + 2 + 2 + 2 |
55 |
|
|
56 |
|
|
57 |
static void |
static void |
58 |
gxv_mort_subtable_type2_opttable_load( FT_Bytes table, |
gxv_mort_subtable_type2_opttable_load( FT_Bytes table, |
60 |
GXV_Validator valid ) |
GXV_Validator valid ) |
61 |
{ |
{ |
62 |
FT_Bytes p = table; |
FT_Bytes p = table; |
63 |
GXV_mort_subtable_type2_StateOptRecData optdata = valid->statetable.optdata; |
GXV_mort_subtable_type2_StateOptRecData optdata = |
64 |
|
valid->statetable.optdata; |
65 |
|
|
66 |
|
|
67 |
GXV_LIMIT_CHECK( 2 + 2 + 2 ); |
GXV_LIMIT_CHECK( 2 + 2 + 2 ); |
69 |
optdata->componentTable = FT_NEXT_USHORT( p ); |
optdata->componentTable = FT_NEXT_USHORT( p ); |
70 |
optdata->ligatureTable = FT_NEXT_USHORT( p ); |
optdata->ligatureTable = FT_NEXT_USHORT( p ); |
71 |
|
|
72 |
GXV_TRACE(( "offset to ligActionTable=0x%04x\n", optdata->ligActionTable )); |
GXV_TRACE(( "offset to ligActionTable=0x%04x\n", |
73 |
GXV_TRACE(( "offset to componentTable=0x%04x\n", optdata->componentTable )); |
optdata->ligActionTable )); |
74 |
GXV_TRACE(( "offset to ligatureTable=0x%04x\n", optdata->ligatureTable )); |
GXV_TRACE(( "offset to componentTable=0x%04x\n", |
75 |
|
optdata->componentTable )); |
76 |
|
GXV_TRACE(( "offset to ligatureTable=0x%04x\n", |
77 |
|
optdata->ligatureTable )); |
78 |
} |
} |
79 |
|
|
80 |
|
|
81 |
static void |
static void |
82 |
gxv_mort_subtable_type2_subtable_setup( FT_UShort table_size, |
gxv_mort_subtable_type2_subtable_setup( FT_UShort table_size, |
83 |
FT_UShort classTable, |
FT_UShort classTable, |
91 |
FT_UShort o[6]; |
FT_UShort o[6]; |
92 |
FT_UShort *l[6]; |
FT_UShort *l[6]; |
93 |
FT_UShort buff[7]; |
FT_UShort buff[7]; |
94 |
GXV_mort_subtable_type2_StateOptRecData optdata = valid->statetable.optdata; |
|
95 |
|
GXV_mort_subtable_type2_StateOptRecData optdata = |
96 |
|
valid->statetable.optdata; |
97 |
|
|
98 |
|
|
99 |
GXV_NAME_ENTER( "subtable boundaries setup" ); |
GXV_NAME_ENTER( "subtable boundaries setup" ); |
114 |
gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid ); |
gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid ); |
115 |
|
|
116 |
GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n", |
GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n", |
117 |
classTable, *classTable_length_p)); |
classTable, *classTable_length_p )); |
118 |
GXV_TRACE(( "stateArray: offset=0x%04x length=0x%04x\n", |
GXV_TRACE(( "stateArray: offset=0x%04x length=0x%04x\n", |
119 |
stateArray, *stateArray_length_p)); |
stateArray, *stateArray_length_p )); |
120 |
GXV_TRACE(( "entryTable: offset=0x%04x length=0x%04x\n", |
GXV_TRACE(( "entryTable: offset=0x%04x length=0x%04x\n", |
121 |
entryTable, *entryTable_length_p)); |
entryTable, *entryTable_length_p )); |
122 |
GXV_TRACE(( "ligActionTable: offset=0x%04x length=0x%04x\n", |
GXV_TRACE(( "ligActionTable: offset=0x%04x length=0x%04x\n", |
123 |
optdata->ligActionTable, |
optdata->ligActionTable, |
124 |
optdata->ligActionTable_length)); |
optdata->ligActionTable_length )); |
125 |
GXV_TRACE(( "componentTable: offset=0x%04x length=0x%04x\n", |
GXV_TRACE(( "componentTable: offset=0x%04x length=0x%04x\n", |
126 |
optdata->componentTable, |
optdata->componentTable, |
127 |
optdata->componentTable_length)); |
optdata->componentTable_length )); |
128 |
GXV_TRACE(( "ligatureTable: offset=0x%04x length=0x%04x\n", |
GXV_TRACE(( "ligatureTable: offset=0x%04x length=0x%04x\n", |
129 |
optdata->ligatureTable, |
optdata->ligatureTable, |
130 |
optdata->ligatureTable_length)); |
optdata->ligatureTable_length )); |
131 |
|
|
132 |
GXV_EXIT; |
GXV_EXIT; |
133 |
} |
} |
134 |
|
|
135 |
|
|
|
|
|
136 |
static void |
static void |
137 |
gxv_mort_subtable_type2_ligActionOffset_validate( FT_Bytes table, |
gxv_mort_subtable_type2_ligActionOffset_validate( |
138 |
FT_UShort ligActionOffset, |
FT_Bytes table, |
139 |
GXV_Validator valid ) |
FT_UShort ligActionOffset, |
140 |
|
GXV_Validator valid ) |
141 |
{ |
{ |
142 |
/* access ligActionTable */ |
/* access ligActionTable */ |
143 |
GXV_mort_subtable_type2_StateOptRecData optdata = valid->statetable.optdata; |
GXV_mort_subtable_type2_StateOptRecData optdata = |
144 |
|
valid->statetable.optdata; |
145 |
|
|
146 |
FT_Bytes lat_base = table + optdata->ligActionTable; |
FT_Bytes lat_base = table + optdata->ligActionTable; |
147 |
FT_Bytes p = table + ligActionOffset; |
FT_Bytes p = table + ligActionOffset; |
148 |
FT_Bytes lat_limit = lat_base + optdata->ligActionTable; |
FT_Bytes lat_limit = lat_base + optdata->ligActionTable; |
152 |
if ( p < lat_base ) |
if ( p < lat_base ) |
153 |
{ |
{ |
154 |
GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n", |
GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n", |
155 |
ligActionOffset, lat_base - p )); |
ligActionOffset, lat_base - p )); |
156 |
|
|
157 |
/* FontValidator, ftxvalidator, ftxdumperfuser warns but continues */ |
/* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ |
158 |
if ( valid->root->level >= FT_VALIDATE_PARANOID ) |
if ( valid->root->level >= FT_VALIDATE_PARANOID ) |
159 |
FT_INVALID_OFFSET; |
FT_INVALID_OFFSET; |
160 |
} |
} |
161 |
else if ( lat_limit < p ) |
else if ( lat_limit < p ) |
162 |
{ |
{ |
163 |
GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n", |
GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n", |
164 |
ligActionOffset, p - lat_limit )); |
ligActionOffset, p - lat_limit )); |
165 |
|
|
166 |
/* FontValidator, ftxvalidator, ftxdumperfuser warns but continues */ |
/* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ |
167 |
if ( valid->root->level >= FT_VALIDATE_PARANOID ) |
if ( valid->root->level >= FT_VALIDATE_PARANOID ) |
168 |
FT_INVALID_OFFSET; |
FT_INVALID_OFFSET; |
169 |
} |
} |
177 |
|
|
178 |
|
|
179 |
lig_action = FT_NEXT_ULONG( p ); |
lig_action = FT_NEXT_ULONG( p ); |
180 |
last = (lig_action & 0x80000000) / 0x80000000; |
last = (lig_action & 0x80000000UL) / 0x80000000UL; |
181 |
store = (lig_action & 0x40000000) / 0x40000000; |
store = (lig_action & 0x40000000UL) / 0x40000000UL; |
182 |
offset = lig_action & 0x3FFFFFFF; |
offset = lig_action & 0x3FFFFFFFUL; |
183 |
} |
} |
184 |
} |
} |
185 |
|
|
186 |
|
|
187 |
static void |
static void |
188 |
gxv_mort_subtable_type2_entry_validate( FT_Byte state, |
gxv_mort_subtable_type2_entry_validate( |
189 |
FT_UShort flags, |
FT_Byte state, |
190 |
GXV_StateTable_GlyphOffsetDesc glyphOffset, |
FT_UShort flags, |
191 |
FT_Bytes table, |
GXV_StateTable_GlyphOffsetDesc glyphOffset, |
192 |
FT_Bytes limit, |
FT_Bytes table, |
193 |
GXV_Validator valid ) |
FT_Bytes limit, |
194 |
|
GXV_Validator valid ) |
195 |
{ |
{ |
196 |
FT_UShort setComponent; |
FT_UShort setComponent; |
197 |
FT_UShort dontAdvance; |
FT_UShort dontAdvance; |
198 |
FT_UShort offset; |
FT_UShort offset; |
199 |
|
|
200 |
|
FT_UNUSED( state ); |
201 |
|
FT_UNUSED( glyphOffset ); |
202 |
|
FT_UNUSED( limit ); |
203 |
|
|
204 |
setComponent = ( flags & 0x8000 ) / 0x8000; |
|
205 |
dontAdvance = ( flags & 0x4000 ) / 0x4000; |
setComponent = ( flags & 0x8000U ) / 0x8000U; |
206 |
|
dontAdvance = ( flags & 0x4000 ) / 0x4000; |
207 |
offset = flags & 0x3FFF; |
offset = flags & 0x3FFF; |
208 |
|
|
209 |
if ( 0 < offset ) |
if ( 0 < offset ) |
210 |
gxv_mort_subtable_type2_ligActionOffset_validate( table, offset, valid ); |
gxv_mort_subtable_type2_ligActionOffset_validate( table, offset, |
211 |
|
valid ); |
212 |
} |
} |
213 |
|
|
214 |
|
|
215 |
static void |
static void |
216 |
gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes table, |
gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes table, |
217 |
GXV_Validator valid ) |
GXV_Validator valid ) |
218 |
{ |
{ |
219 |
GXV_mort_subtable_type2_StateOptRecData optdata = valid->statetable.optdata; |
GXV_mort_subtable_type2_StateOptRecData optdata = |
220 |
|
valid->statetable.optdata; |
221 |
|
|
222 |
FT_Bytes p = table + optdata->ligatureTable; |
FT_Bytes p = table + optdata->ligatureTable; |
223 |
FT_Bytes limit = table + optdata->ligatureTable |
FT_Bytes limit = table + optdata->ligatureTable |
224 |
+ optdata->ligatureTable_length; |
+ optdata->ligatureTable_length; |
225 |
|
|
226 |
|
|
227 |
GXV_NAME_ENTER( "mort chain subtable type2 - substitutionTable" ); |
GXV_NAME_ENTER( "mort chain subtable type2 - substitutionTable" ); |
228 |
if ( 0 != optdata->ligatureTable ) |
if ( 0 != optdata->ligatureTable ) |
229 |
{ |
{ |
240 |
GXV_EXIT; |
GXV_EXIT; |
241 |
} |
} |
242 |
|
|
243 |
|
|
244 |
static void |
static void |
245 |
gxv_mort_subtable_type2_validate( FT_Bytes table, |
gxv_mort_subtable_type2_validate( FT_Bytes table, |
246 |
FT_Bytes limit, |
FT_Bytes limit, |
247 |
GXV_Validator valid ) |
GXV_Validator valid ) |
248 |
{ |
{ |
249 |
FT_Bytes p = table; |
FT_Bytes p = table; |
250 |
|
|
251 |
GXV_mort_subtable_type2_StateOptRec lig_rec; |
GXV_mort_subtable_type2_StateOptRec lig_rec; |
252 |
|
|
253 |
|
|
255 |
|
|
256 |
GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); |
GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); |
257 |
|
|
258 |
valid->statetable.optdata = &lig_rec; |
valid->statetable.optdata = |
259 |
valid->statetable.optdata_load_func = gxv_mort_subtable_type2_opttable_load; |
&lig_rec; |
260 |
valid->statetable.subtable_setup_func = gxv_mort_subtable_type2_subtable_setup; |
valid->statetable.optdata_load_func = |
261 |
valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; |
gxv_mort_subtable_type2_opttable_load; |
262 |
valid->statetable.entry_validate_func = gxv_mort_subtable_type2_entry_validate; |
valid->statetable.subtable_setup_func = |
263 |
|
gxv_mort_subtable_type2_subtable_setup; |
264 |
|
valid->statetable.entry_glyphoffset_fmt = |
265 |
|
GXV_GLYPHOFFSET_NONE; |
266 |
|
valid->statetable.entry_validate_func = |
267 |
|
gxv_mort_subtable_type2_entry_validate; |
268 |
|
|
269 |
gxv_StateTable_validate( p, limit, valid ); |
gxv_StateTable_validate( p, limit, valid ); |
270 |
|
|
271 |
p += valid->subtable_length; |
p += valid->subtable_length; |
272 |
gxv_mort_subtable_type2_ligatureTable_validate( table, valid ); |
gxv_mort_subtable_type2_ligatureTable_validate( table, valid ); |
273 |
|
|
274 |
valid->subtable_length = ( p - table ); |
valid->subtable_length = p - table; |
275 |
|
|
276 |
GXV_EXIT; |
GXV_EXIT; |
277 |
} |
} |
278 |
|
|