?? otvgpos.c
字號:
ValueFormat1, ValueFormat2, valid ); } break; case 2: /* PairPosFormat2 */ { FT_UInt Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2; FT_UInt ClassCount1, ClassCount2, len_value1, len_value2, count; OTV_LIMIT_CHECK( 14 ); Coverage = FT_NEXT_USHORT( p ); ValueFormat1 = FT_NEXT_USHORT( p ); ValueFormat2 = FT_NEXT_USHORT( p ); ClassDef1 = FT_NEXT_USHORT( p ); ClassDef2 = FT_NEXT_USHORT( p ); ClassCount1 = FT_NEXT_USHORT( p ); ClassCount2 = FT_NEXT_USHORT( p ); OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 )); OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 )); len_value1 = otv_value_length( ValueFormat1 ); len_value2 = otv_value_length( ValueFormat2 ); otv_Coverage_validate( table + Coverage, valid ); otv_ClassDef_validate( table + ClassDef1, valid ); otv_ClassDef_validate( table + ClassDef2, valid ); OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * ( len_value1 + len_value2 ) ); /* Class1Record */ for ( ; ClassCount1 > 0; ClassCount1-- ) { /* Class2Record */ for ( count = ClassCount2; count > 0; count-- ) { if ( ValueFormat1 ) /* Value1 */ otv_ValueRecord_validate( p, ValueFormat1, valid ); p += len_value1; if ( ValueFormat2 ) /* Value2 */ otv_ValueRecord_validate( p, ValueFormat2, valid ); p += len_value2; } } } break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS LOOKUP TYPE 3 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ static void otv_CursivePos_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt PosFormat; OTV_NAME_ENTER( "CursivePos" ); OTV_LIMIT_CHECK( 2 ); PosFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", PosFormat )); switch ( PosFormat ) { case 1: /* CursivePosFormat1 */ { FT_UInt table_size; FT_UInt Coverage, EntryExitCount; OTV_OPTIONAL_TABLE( EntryAnchor ); OTV_OPTIONAL_TABLE( ExitAnchor ); OTV_LIMIT_CHECK( 4 ); Coverage = FT_NEXT_USHORT( p ); EntryExitCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); otv_Coverage_validate( table + Coverage, valid ); OTV_LIMIT_CHECK( EntryExitCount * 4 ); table_size = EntryExitCount * 4 + 4; /* EntryExitRecord */ for ( ; EntryExitCount > 0; EntryExitCount-- ) { OTV_OPTIONAL_OFFSET( EntryAnchor ); OTV_OPTIONAL_OFFSET( ExitAnchor ); OTV_SIZE_CHECK( EntryAnchor ); if ( EntryAnchor ) otv_Anchor_validate( table + EntryAnchor, valid ); OTV_SIZE_CHECK( ExitAnchor ); if ( ExitAnchor ) otv_Anchor_validate( table + ExitAnchor, valid ); } } break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS LOOKUP TYPE 4 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->extra2 (0) */ static void otv_MarkBasePos_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt PosFormat; OTV_NAME_ENTER( "MarkBasePos" ); OTV_LIMIT_CHECK( 2 ); PosFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", PosFormat )); switch ( PosFormat ) { case 1: valid->extra2 = 0; OTV_NEST2( MarkBasePosFormat1, BaseArray ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS LOOKUP TYPE 5 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->extra2 (1) */ static void otv_MarkLigPos_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt PosFormat; OTV_NAME_ENTER( "MarkLigPos" ); OTV_LIMIT_CHECK( 2 ); PosFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", PosFormat )); switch ( PosFormat ) { case 1: valid->extra2 = 1; OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS LOOKUP TYPE 6 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->extra2 (0) */ static void otv_MarkMarkPos_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt PosFormat; OTV_NAME_ENTER( "MarkMarkPos" ); OTV_LIMIT_CHECK( 2 ); PosFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", PosFormat )); switch ( PosFormat ) { case 1: valid->extra2 = 0; OTV_NEST2( MarkMarkPosFormat1, Mark2Array ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS LOOKUP TYPE 7 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->extra1 (lookup count) */ static void otv_ContextPos_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt PosFormat; OTV_NAME_ENTER( "ContextPos" ); OTV_LIMIT_CHECK( 2 ); PosFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", PosFormat )); switch ( PosFormat ) { 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( ContextPosFormat1, PosRuleSet, PosRule ); 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( ContextPosFormat2, PosClassSet, PosClassRule ); OTV_RUN( table, valid ); break; case 3: OTV_NEST1( ContextPosFormat3 ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS LOOKUP TYPE 8 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->extra1 (lookup count) */ static void otv_ChainContextPos_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt PosFormat; OTV_NAME_ENTER( "ChainContextPos" ); OTV_LIMIT_CHECK( 2 ); PosFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", PosFormat )); switch ( PosFormat ) { 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( ChainContextPosFormat1, ChainPosRuleSet, ChainPosRule ); 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( ChainContextPosFormat2, ChainPosClassSet, ChainPosClassRule ); OTV_RUN( table, valid ); break; case 3: OTV_NEST1( ChainContextPosFormat3 ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS LOOKUP TYPE 9 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* uses valid->type_funcs */ static void otv_ExtensionPos_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt PosFormat; OTV_NAME_ENTER( "ExtensionPos" ); OTV_LIMIT_CHECK( 2 ); PosFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", PosFormat )); switch ( PosFormat ) { case 1: /* ExtensionPosFormat1 */ { 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 >= 9 ) FT_INVALID_DATA; validate = valid->type_funcs[ExtensionLookupType - 1]; validate( table + ExtensionOffset, valid ); } break; default: FT_INVALID_DATA; } OTV_EXIT; } static const OTV_Validate_Func otv_gpos_validate_funcs[9] = { otv_SinglePos_validate, otv_PairPos_validate, otv_CursivePos_validate, otv_MarkBasePos_validate, otv_MarkLigPos_validate, otv_MarkMarkPos_validate, otv_ContextPos_validate, otv_ChainContextPos_validate, otv_ExtensionPos_validate }; /* sets valid->type_count */ /* sets valid->type_funcs */ FT_LOCAL_DEF( void ) otv_GPOS_subtable_validate( FT_Bytes table, OTV_Validator valid ) { valid->type_count = 9; valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; otv_Lookup_validate( table, valid ); } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GPOS TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* sets valid->glyph_count */ FT_LOCAL_DEF( void ) otv_GPOS_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 GPOS 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 = 9; valid->type_funcs = (OTV_Validate_Func*)otv_gpos_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 */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -