39#define FT_COMPONENT gxvmort
44 FT_UShort substitutionTable;
45 FT_UShort substitutionTable_length;
47 } GXV_mort_subtable_type1_StateOptRec,
48 *GXV_mort_subtable_type1_StateOptRecData;
50#define GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE \
51 ( GXV_STATETABLE_HEADER_SIZE + 2 )
55 gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes table,
57 GXV_Validator gxvalid )
61 GXV_mort_subtable_type1_StateOptRecData optdata =
62 (GXV_mort_subtable_type1_StateOptRecData)gxvalid->statetable.optdata;
66 optdata->substitutionTable = FT_NEXT_USHORT( p );
71 gxv_mort_subtable_type1_subtable_setup( FT_UShort table_size,
75 FT_UShort* classTable_length_p,
76 FT_UShort* stateArray_length_p,
77 FT_UShort* entryTable_length_p,
78 GXV_Validator gxvalid )
84 GXV_mort_subtable_type1_StateOptRecData optdata =
85 (GXV_mort_subtable_type1_StateOptRecData)gxvalid->statetable.optdata;
91 o[3] = optdata->substitutionTable;
92 l[0] = classTable_length_p;
93 l[1] = stateArray_length_p;
94 l[2] = entryTable_length_p;
95 l[3] = &( optdata->substitutionTable_length );
97 gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, gxvalid );
102 gxv_mort_subtable_type1_offset_to_subst_validate(
104 const FT_String* tag,
106 GXV_Validator gxvalid )
108 FT_UShort substTable;
109 FT_UShort substTable_limit;
116 ((GXV_mort_subtable_type1_StateOptRec *)
117 (gxvalid->statetable.optdata))->substitutionTable;
119 (FT_UShort)( substTable +
120 ((GXV_mort_subtable_type1_StateOptRec *)
121 (gxvalid->statetable.optdata))->substitutionTable_length );
123 gxvalid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 );
124 gxvalid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
125 gxvalid->max_gid = (FT_UShort)( FT_MAX( gxvalid->max_gid,
126 gxvalid->face->num_glyphs ) );
135 gxv_mort_subtable_type1_entry_validate(
138 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
141 GXV_Validator gxvalid )
143#ifdef GXV_LOAD_UNUSED_VARS
145 FT_UShort dontAdvance;
149 FT_Short currentOffset;
155#ifdef GXV_LOAD_UNUSED_VARS
156 setMark = (FT_UShort)( flags >> 15 );
157 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
159 reserved = (FT_UShort)( flags & 0x3FFF );
161 markOffset = (FT_Short)( glyphOffset_p->ul >> 16 );
162 currentOffset = (FT_Short)( glyphOffset_p->ul );
166 GXV_TRACE((
" non-zero bits found in reserved range\n" ));
167 GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
170 gxv_mort_subtable_type1_offset_to_subst_validate( markOffset,
175 gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset,
183 gxv_mort_subtable_type1_substTable_validate( FT_Bytes table,
185 GXV_Validator gxvalid )
188 FT_UShort num_gids = (FT_UShort)(
189 ((GXV_mort_subtable_type1_StateOptRec *)
190 (gxvalid->statetable.optdata))->substitutionTable_length / 2 );
194 GXV_NAME_ENTER(
"validating contents of substitutionTable" );
195 for ( i = 0; i < num_gids; i++ )
200 GXV_LIMIT_CHECK( 2 );
201 dst_gid = FT_NEXT_USHORT( p );
203 if ( dst_gid >= 0xFFFFU )
206 if ( dst_gid < gxvalid->min_gid || gxvalid->max_gid < dst_gid )
208 GXV_TRACE((
"substTable include a strange gid[%d]=%d >"
209 " out of define range (%d..%d)\n",
210 i, dst_gid, gxvalid->min_gid, gxvalid->max_gid ));
211 GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
225 gxv_mort_subtable_type1_validate( FT_Bytes table,
227 GXV_Validator gxvalid )
231 GXV_mort_subtable_type1_StateOptRec st_rec;
234 GXV_NAME_ENTER(
"mort chain subtable type1 (Contextual Glyph Subst)" );
236 GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE );
238 gxvalid->statetable.optdata =
240 gxvalid->statetable.optdata_load_func =
241 gxv_mort_subtable_type1_substitutionTable_load;
242 gxvalid->statetable.subtable_setup_func =
243 gxv_mort_subtable_type1_subtable_setup;
244 gxvalid->statetable.entry_glyphoffset_fmt =
245 GXV_GLYPHOFFSET_ULONG;
246 gxvalid->statetable.entry_validate_func =
248 gxv_mort_subtable_type1_entry_validate;
249 gxv_StateTable_validate( p, limit, gxvalid );
251 gxv_mort_subtable_type1_substTable_validate(
252 table + st_rec.substitutionTable,
253 table + st_rec.substitutionTable + st_rec.substitutionTable_length,