📄 ftxgsub.c
字号:
if ( in->pos + csf3->GlyphCount > in->length ) return TTO_Err_Not_Covered; /* context is too long */ s_in = &in->string[in->pos]; c = csf3->Coverage; for ( i = 1, j = 1; i < csf3->GlyphCount; i++, j++ ) { while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) { if ( error && error != TTO_Err_Not_Covered ) return error; if ( in->pos + j < in->length ) j++; else return TTO_Err_Not_Covered; } error = Coverage_Index( &c[i], s_in[j], &index ); if ( error ) return error; } return Do_ContextSubst( gsub, csf3->GlyphCount, csf3->SubstCount, csf3->SubstLookupRecord, in, out, nesting_level ); } static TT_Error Lookup_ContextSubst( TTO_GSUBHeader* gsub, TTO_ContextSubst* cs, TTO_GSUB_String* in, TTO_GSUB_String* out, UShort flags, UShort context_length, int nesting_level ) { switch ( cs->SubstFormat ) { case 1: return Lookup_ContextSubst1( gsub, &cs->csf.csf1, in, out, flags, context_length, nesting_level ); case 2: return Lookup_ContextSubst2( gsub, &cs->csf.csf2, in, out, flags, context_length, nesting_level ); case 3: return Lookup_ContextSubst3( gsub, &cs->csf.csf3, in, out, flags, context_length, nesting_level ); default: return TTO_Err_Invalid_GSUB_SubTable_Format; } return TT_Err_Ok; /* never reached */ } /* LookupType 6 */ /* ChainSubRule */ static TT_Error Load_ChainSubRule( TTO_ChainSubRule* csr, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; UShort* b; UShort* i; UShort* l; TTO_SubstLookupRecord* slr; if ( ACCESS_Frame( 2L ) ) return error; csr->BacktrackGlyphCount = GET_UShort(); FORGET_Frame(); csr->Backtrack = NULL; count = csr->BacktrackGlyphCount; if ( ALLOC_ARRAY( csr->Backtrack, count, UShort ) ) return error; b = csr->Backtrack; if ( ACCESS_Frame( count * 2L ) ) goto Fail4; for ( n = 0; n < count; n++ ) b[n] = GET_UShort(); FORGET_Frame(); if ( ACCESS_Frame( 2L ) ) goto Fail4; csr->InputGlyphCount = GET_UShort(); FORGET_Frame(); csr->Input = NULL; count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ if ( ALLOC_ARRAY( csr->Input, count, UShort ) ) goto Fail4; i = csr->Input; if ( ACCESS_Frame( count * 2L ) ) goto Fail3; for ( n = 0; n < count; n++ ) i[n] = GET_UShort(); FORGET_Frame(); if ( ACCESS_Frame( 2L ) ) goto Fail3; csr->LookaheadGlyphCount = GET_UShort(); FORGET_Frame(); csr->Lookahead = NULL; count = csr->LookaheadGlyphCount; if ( ALLOC_ARRAY( csr->Lookahead, count, UShort ) ) goto Fail3; l = csr->Lookahead; if ( ACCESS_Frame( count * 2L ) ) goto Fail2; for ( n = 0; n < count; n++ ) l[n] = GET_UShort(); FORGET_Frame(); if ( ACCESS_Frame( 2L ) ) goto Fail2; csr->SubstCount = GET_UShort(); FORGET_Frame(); csr->SubstLookupRecord = NULL; count = csr->SubstCount; if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) goto Fail2; slr = csr->SubstLookupRecord; if ( ACCESS_Frame( count * 4L ) ) goto Fail1; for ( n = 0; n < count; n++ ) { slr[n].SequenceIndex = GET_UShort(); slr[n].LookupListIndex = GET_UShort(); } FORGET_Frame(); return TT_Err_Ok; Fail1: FREE( slr ); Fail2: FREE( l ); Fail3: FREE( i ); Fail4: FREE( b ); return error; } static void Free_ChainSubRule( TTO_ChainSubRule* csr ) { FREE( csr->SubstLookupRecord ); FREE( csr->Lookahead ); FREE( csr->Input ); FREE( csr->Backtrack ); } /* ChainSubRuleSet */ static TT_Error Load_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_ChainSubRule* csr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = csrs->ChainSubRuleCount = GET_UShort(); FORGET_Frame(); csrs->ChainSubRule = NULL; if ( ALLOC_ARRAY( csrs->ChainSubRule, count, TTO_ChainSubRule ) ) return error; csr = csrs->ChainSubRule; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_ChainSubRule( &csr[n], input ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( n = 0; n < count; n++ ) Free_ChainSubRule( &csr[n] ); FREE( csr ); return error; } static void Free_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs ) { UShort n, count; TTO_ChainSubRule* csr; if ( csrs->ChainSubRule ) { count = csrs->ChainSubRuleCount; csr = csrs->ChainSubRule; for ( n = 0; n < count; n++ ) Free_ChainSubRule( &csr[n] ); FREE( csr ); } } /* ChainContextSubstFormat1 */ static TT_Error Load_ChainContextSubst1( TTO_ChainContextSubstFormat1* ccsf1, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_ChainSubRuleSet* csrs; base_offset = FILE_Pos() - 2L; if ( ACCESS_Frame( 2L ) ) return error; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &ccsf1->Coverage, input ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail2; count = ccsf1->ChainSubRuleSetCount = GET_UShort(); FORGET_Frame(); ccsf1->ChainSubRuleSet = NULL; if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, TTO_ChainSubRuleSet ) ) goto Fail2; csrs = ccsf1->ChainSubRuleSet; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail1; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_ChainSubRuleSet( &csrs[n], input ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( n = 0; n < count; n++ ) Free_ChainSubRuleSet( &csrs[n] ); FREE( csrs ); Fail2: Free_Coverage( &ccsf1->Coverage ); return error; } static void Free_ChainContext1( TTO_ChainContextSubstFormat1* ccsf1 ) { UShort n, count; TTO_ChainSubRuleSet* csrs; if ( ccsf1->ChainSubRuleSet ) { count = ccsf1->ChainSubRuleSetCount; csrs = ccsf1->ChainSubRuleSet; for ( n = 0; n < count; n++ ) Free_ChainSubRuleSet( &csrs[n] ); FREE( csrs ); } Free_Coverage( &ccsf1->Coverage ); } /* ChainSubClassRule */ static TT_Error Load_ChainSubClassRule( TTO_ChainContextSubstFormat2* ccsf2, TTO_ChainSubClassRule* cscr, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; UShort* b; UShort* i; UShort* l; TTO_SubstLookupRecord* slr; Bool* d; if ( ACCESS_Frame( 2L ) ) return error; cscr->BacktrackGlyphCount = GET_UShort(); FORGET_Frame(); if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength ) ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount; cscr->Backtrack = NULL; count = cscr->BacktrackGlyphCount; if ( ALLOC_ARRAY( cscr->Backtrack, count, UShort ) ) return error; b = cscr->Backtrack; d = ccsf2->BacktrackClassDef.Defined; if ( ACCESS_Frame( count * 2L ) ) goto Fail4; for ( n = 0; n < count; n++ ) { b[n] = GET_UShort(); /* We check whether the specific class is used at all. If not, class 0 is used instead. */ if ( !d[b[n]] ) b[n] = 0; } FORGET_Frame(); if ( ACCESS_Frame( 2L ) ) goto Fail4; cscr->InputGlyphCount = GET_UShort(); FORGET_Frame(); if ( cscr->InputGlyphCount > ccsf2->MaxInputLength ) ccsf2->MaxInputLength = cscr->InputGlyphCount; cscr->Input = NULL; count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ if ( ALLOC_ARRAY( cscr->Input, count, UShort ) ) goto Fail4; i = cscr->Input; d = ccsf2->InputClassDef.Defined; if ( ACCESS_Frame( count * 2L ) ) goto Fail3; for ( n = 0; n < count; n++ ) { i[n] = GET_UShort(); if ( !d[i[n]] ) i[n] = 0; } FORGET_Frame(); if ( ACCESS_Frame( 2L ) ) goto Fail3; cscr->LookaheadGlyphCount = GET_UShort(); FORGET_Frame(); if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength ) ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount; cscr->Lookahead = NULL; count = cscr->LookaheadGlyphCount; if ( ALLOC_ARRAY( cscr->Lookahead, count, UShort ) ) goto Fail3; l = cscr->Lookahead; d = ccsf2->LookaheadClassDef.Defined; if ( ACCESS_Frame( count * 2L ) ) goto Fail2; for ( n = 0; n < count; n++ ) { l[n] = GET_UShort(); if ( !d[l[n]] ) l[n] = 0; } FORGET_Frame(); if ( ACCESS_Frame( 2L ) ) goto Fail2; cscr->SubstCount = GET_UShort(); FORGET_Frame(); cscr->SubstLookupRecord = NULL; count = cscr->SubstCount; if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) goto Fail2; slr = cscr->SubstLookupRecord; if ( ACCESS_Frame( count * 4L ) ) goto Fail1; for ( n = 0; n < count; n++ ) { slr[n].SequenceIndex = GET_UShort(); slr[n].LookupListIndex = GET_UShort(); } FORGET_Frame(); return TT_Err_Ok; Fail1: FREE( slr ); Fail2: FREE( l ); Fail3: FREE( i ); Fail4: FREE( b ); return error; } static void Free_ChainSubClassRule( TTO_ChainSubClassRule* cscr ) { FREE( cscr->SubstLookupRecord ); FREE( cscr->Lookahead ); FREE( cscr->Input ); FREE( cscr->Backtrack ); } /* SubClassSet */ static TT_Error Load_ChainSubClassSet( TTO_ChainContextSubstFormat2* ccsf2, TTO_ChainSubClassSet* cscs, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_ChainSubClassRule* cscr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = cscs->ChainSubClassRuleCount = GET_UShort(); FORGET_Frame(); cscs->ChainSubClass
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -