30#define FT_COMPONENT otvgsub
44 otv_SingleSubst_validate( FT_Bytes table,
45 OTV_Validator otvalid )
51 OTV_NAME_ENTER(
"SingleSubst" );
54 SubstFormat = FT_NEXT_USHORT( p );
56 OTV_TRACE((
" (format %u)\n", SubstFormat ));
58 switch ( SubstFormat )
64 FT_UInt first_cov, last_cov;
65 FT_UInt first_idx, last_idx;
69 Coverage = table + FT_NEXT_USHORT( p );
70 DeltaGlyphID = FT_NEXT_SHORT( p );
72 otv_Coverage_validate( Coverage, otvalid, -1 );
74 first_cov = otv_Coverage_get_first( Coverage );
75 last_cov = otv_Coverage_get_last( Coverage );
78 first_idx = (FT_UInt)( (FT_Int)first_cov + DeltaGlyphID ) & 0xFFFFU;
79 last_idx = (FT_UInt)( (FT_Int)last_cov + DeltaGlyphID ) & 0xFFFFU;
85 if ( first_idx > last_idx )
88 if ( last_idx >= otvalid->glyph_count )
95 FT_UInt Coverage, GlyphCount;
99 Coverage = FT_NEXT_USHORT( p );
100 GlyphCount = FT_NEXT_USHORT( p );
102 OTV_TRACE((
" (GlyphCount = %u)\n", GlyphCount ));
104 otv_Coverage_validate( table + Coverage,
106 (FT_Int)GlyphCount );
108 OTV_LIMIT_CHECK( GlyphCount * 2 );
111 for ( ; GlyphCount > 0; GlyphCount-- )
112 if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count )
136 otv_MultipleSubst_validate( FT_Bytes table,
137 OTV_Validator otvalid )
143 OTV_NAME_ENTER(
"MultipleSubst" );
145 OTV_LIMIT_CHECK( 2 );
146 SubstFormat = FT_NEXT_USHORT( p );
148 OTV_TRACE((
" (format %u)\n", SubstFormat ));
150 switch ( SubstFormat )
153 otvalid->extra1 = otvalid->glyph_count;
154 OTV_NEST2( MultipleSubstFormat1, Sequence );
155 OTV_RUN( table, otvalid );
177 otv_AlternateSubst_validate( FT_Bytes table,
178 OTV_Validator otvalid )
184 OTV_NAME_ENTER(
"AlternateSubst" );
186 OTV_LIMIT_CHECK( 2 );
187 SubstFormat = FT_NEXT_USHORT( p );
189 OTV_TRACE((
" (format %u)\n", SubstFormat ));
191 switch ( SubstFormat )
194 otvalid->extra1 = otvalid->glyph_count;
195 OTV_NEST2( AlternateSubstFormat1, AlternateSet );
196 OTV_RUN( table, otvalid );
215#define LigatureFunc otv_Ligature_validate
220 otv_Ligature_validate( FT_Bytes table,
221 OTV_Validator otvalid )
224 FT_UInt LigatureGlyph, CompCount;
229 OTV_LIMIT_CHECK( 4 );
230 LigatureGlyph = FT_NEXT_USHORT( p );
231 if ( LigatureGlyph >= otvalid->glyph_count )
234 CompCount = FT_NEXT_USHORT( p );
236 OTV_TRACE((
" (CompCount = %u)\n", CompCount ));
238 if ( CompCount == 0 )
243 OTV_LIMIT_CHECK( CompCount * 2 );
252 otv_LigatureSubst_validate( FT_Bytes table,
253 OTV_Validator otvalid )
259 OTV_NAME_ENTER(
"LigatureSubst" );
261 OTV_LIMIT_CHECK( 2 );
262 SubstFormat = FT_NEXT_USHORT( p );
264 OTV_TRACE((
" (format %u)\n", SubstFormat ));
266 switch ( SubstFormat )
269 OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
270 OTV_RUN( table, otvalid );
292 otv_ContextSubst_validate( FT_Bytes table,
293 OTV_Validator otvalid )
299 OTV_NAME_ENTER(
"ContextSubst" );
301 OTV_LIMIT_CHECK( 2 );
302 SubstFormat = FT_NEXT_USHORT( p );
304 OTV_TRACE((
" (format %u)\n", SubstFormat ));
306 switch ( SubstFormat )
313 otvalid->extra1 = otvalid->lookup_count;
314 OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule );
315 OTV_RUN( table, otvalid );
323 OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule );
324 OTV_RUN( table, otvalid );
328 OTV_NEST1( ContextSubstFormat3 );
329 OTV_RUN( table, otvalid );
351 otv_ChainContextSubst_validate( FT_Bytes table,
352 OTV_Validator otvalid )
358 OTV_NAME_ENTER(
"ChainContextSubst" );
360 OTV_LIMIT_CHECK( 2 );
361 SubstFormat = FT_NEXT_USHORT( p );
363 OTV_TRACE((
" (format %u)\n", SubstFormat ));
365 switch ( SubstFormat )
372 otvalid->extra1 = otvalid->lookup_count;
373 OTV_NEST3( ChainContextSubstFormat1,
374 ChainSubRuleSet, ChainSubRule );
375 OTV_RUN( table, otvalid );
383 OTV_NEST3( ChainContextSubstFormat2,
384 ChainSubClassSet, ChainSubClassRule );
385 OTV_RUN( table, otvalid );
389 OTV_NEST1( ChainContextSubstFormat3 );
390 OTV_RUN( table, otvalid );
412 otv_ExtensionSubst_validate( FT_Bytes table,
413 OTV_Validator otvalid )
419 OTV_NAME_ENTER(
"ExtensionSubst" );
421 OTV_LIMIT_CHECK( 2 );
422 SubstFormat = FT_NEXT_USHORT( p );
424 OTV_TRACE((
" (format %u)\n", SubstFormat ));
426 switch ( SubstFormat )
430 FT_UInt ExtensionLookupType;
431 FT_ULong ExtensionOffset;
432 OTV_Validate_Func validate;
435 OTV_LIMIT_CHECK( 6 );
436 ExtensionLookupType = FT_NEXT_USHORT( p );
437 ExtensionOffset = FT_NEXT_ULONG( p );
439 if ( ExtensionLookupType == 0 ||
440 ExtensionLookupType == 7 ||
441 ExtensionLookupType > 8 )
444 validate = otvalid->type_funcs[ExtensionLookupType - 1];
445 validate( table + ExtensionOffset, otvalid );
468 otv_ReverseChainSingleSubst_validate( FT_Bytes table,
469 OTV_Validator otvalid )
471 FT_Bytes p = table, Coverage;
473 FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount;
476 OTV_NAME_ENTER(
"ReverseChainSingleSubst" );
478 OTV_LIMIT_CHECK( 2 );
479 SubstFormat = FT_NEXT_USHORT( p );
481 OTV_TRACE((
" (format %u)\n", SubstFormat ));
483 switch ( SubstFormat )
486 OTV_LIMIT_CHECK( 4 );
487 Coverage = table + FT_NEXT_USHORT( p );
488 BacktrackGlyphCount = FT_NEXT_USHORT( p );
490 OTV_TRACE((
" (BacktrackGlyphCount = %u)\n", BacktrackGlyphCount ));
492 otv_Coverage_validate( Coverage, otvalid, -1 );
494 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
496 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
497 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 );
499 LookaheadGlyphCount = FT_NEXT_USHORT( p );
501 OTV_TRACE((
" (LookaheadGlyphCount = %u)\n", LookaheadGlyphCount ));
503 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
505 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
506 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 );
508 GlyphCount = FT_NEXT_USHORT( p );
510 OTV_TRACE((
" (GlyphCount = %u)\n", GlyphCount ));
512 if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
515 OTV_LIMIT_CHECK( GlyphCount * 2 );
518 for ( ; GlyphCount > 0; GlyphCount-- )
519 if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count )
532 static const OTV_Validate_Func otv_gsub_validate_funcs[8] =
534 otv_SingleSubst_validate,
535 otv_MultipleSubst_validate,
536 otv_AlternateSubst_validate,
537 otv_LigatureSubst_validate,
538 otv_ContextSubst_validate,
539 otv_ChainContextSubst_validate,
540 otv_ExtensionSubst_validate,
541 otv_ReverseChainSingleSubst_validate
558 otv_GSUB_validate( FT_Bytes table,
560 FT_Validator ftvalid )
562 OTV_ValidatorRec otvalidrec;
563 OTV_Validator otvalid = &otvalidrec;
567 FT_UInt ScriptList, FeatureList, LookupList;
569 OTV_OPTIONAL_TABLE32( featureVariations );
572 otvalid->root = ftvalid;
574 FT_TRACE3((
"validating GSUB table\n" ));
577 OTV_LIMIT_CHECK( 4 );
579 if ( FT_NEXT_USHORT( p ) != 1 )
582 version = FT_NEXT_USHORT( p );
588 OTV_LIMIT_CHECK( 6 );
592 OTV_LIMIT_CHECK( 10 );
600 ScriptList = FT_NEXT_USHORT( p );
601 FeatureList = FT_NEXT_USHORT( p );
602 LookupList = FT_NEXT_USHORT( p );
604 otvalid->type_count = 8;
605 otvalid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs;
606 otvalid->glyph_count = glyph_count;
608 otv_LookupList_validate( table + LookupList,
610 otv_FeatureList_validate( table + FeatureList, table + LookupList,
612 otv_ScriptList_validate( table + ScriptList, table + FeatureList,
617 OTV_OPTIONAL_OFFSET32( featureVariations );
618 OTV_SIZE_CHECK32( featureVariations );
619 if ( featureVariations )
620 OTV_TRACE((
" [omitting featureVariations validation]\n" ));