?? otvgsub.c
字號:
switch ( SubstFormat ) { case 1: /* no need to check glyph indices/classes used as input for these */ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ valid->extra1 = valid->lookup_count; OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule ); OTV_RUN( table, valid ); break; case 2: /* no need to check glyph indices/classes used as input for these */ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule ); OTV_RUN( table, valid ); break; case 3: OTV_NEST1( ContextSubstFormat3 ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GSUB LOOKUP TYPE 6 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->extra1 (lookup count) */ static void otv_ChainContextSubst_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt SubstFormat; OTV_NAME_ENTER( "ChainContextSubst" ); OTV_LIMIT_CHECK( 2 ); SubstFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", SubstFormat )); switch ( SubstFormat ) { case 1: /* no need to check glyph indices/classes used as input for these */ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ valid->extra1 = valid->lookup_count; OTV_NEST3( ChainContextSubstFormat1, ChainSubRuleSet, ChainSubRule ); OTV_RUN( table, valid ); break; case 2: /* no need to check glyph indices/classes used as input for these */ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ OTV_NEST3( ChainContextSubstFormat2, ChainSubClassSet, ChainSubClassRule ); OTV_RUN( table, valid ); break; case 3: OTV_NEST1( ChainContextSubstFormat3 ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GSUB LOOKUP TYPE 7 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* uses valid->type_funcs */ static void otv_ExtensionSubst_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt SubstFormat; OTV_NAME_ENTER( "ExtensionSubst" ); OTV_LIMIT_CHECK( 2 ); SubstFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", SubstFormat )); switch ( SubstFormat ) { case 1: /* ExtensionSubstFormat1 */ { FT_UInt ExtensionLookupType, ExtensionOffset; OTV_Validate_Func validate; OTV_LIMIT_CHECK( 6 ); ExtensionLookupType = FT_NEXT_USHORT( p ); ExtensionOffset = FT_NEXT_ULONG( p ); if ( ExtensionLookupType == 0 || ExtensionLookupType == 7 || ExtensionLookupType > 8 ) FT_INVALID_DATA; validate = valid->type_funcs[ExtensionLookupType - 1]; validate( table + ExtensionOffset, valid ); } break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GSUB LOOKUP TYPE 8 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* uses valid->glyph_count */ static void otv_ReverseChainSingleSubst_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table, Coverage; FT_UInt SubstFormat; FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount; OTV_NAME_ENTER( "ReverseChainSingleSubst" ); OTV_LIMIT_CHECK( 2 ); SubstFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", SubstFormat )); switch ( SubstFormat ) { case 1: /* ReverseChainSingleSubstFormat1 */ OTV_LIMIT_CHECK( 4 ); Coverage = table + FT_NEXT_USHORT( p ); BacktrackGlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); otv_Coverage_validate( Coverage, valid ); OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); GlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) FT_INVALID_DATA; OTV_LIMIT_CHECK( GlyphCount * 2 ); /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) FT_INVALID_DATA; break; default: FT_INVALID_DATA; } OTV_EXIT; } static const OTV_Validate_Func otv_gsub_validate_funcs[8] = { otv_SingleSubst_validate, otv_MultipleSubst_validate, otv_AlternateSubst_validate, otv_LigatureSubst_validate, otv_ContextSubst_validate, otv_ChainContextSubst_validate, otv_ExtensionSubst_validate, otv_ReverseChainSingleSubst_validate }; /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GSUB TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->type_count */ /* sets valid->type_funcs */ /* sets valid->glyph_count */ FT_LOCAL_DEF( void ) otv_GSUB_validate( FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid ) { OTV_ValidatorRec validrec; OTV_Validator valid = &validrec; FT_Bytes p = table; FT_UInt ScriptList, FeatureList, LookupList; valid->root = ftvalid; FT_TRACE3(( "validating GSUB table\n" )); OTV_INIT; OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ FT_INVALID_DATA; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); LookupList = FT_NEXT_USHORT( p ); valid->type_count = 8; valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; valid->glyph_count = glyph_count; otv_LookupList_validate( table + LookupList, valid ); otv_FeatureList_validate( table + FeatureList, table + LookupList, valid ); otv_ScriptList_validate( table + ScriptList, table + FeatureList, valid ); FT_TRACE4(( "\n" )); }/* END */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -