📄 ftxgsub.c
字号:
(void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Gsub_Free_ChainSubRule( &csr[m], memory ); FREE( csr ); return error; } static void Gsub_Free_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs, FT_Memory memory ) { FT_UShort n, count; TTO_ChainSubRule* csr; if ( csrs->ChainSubRule ) { count = csrs->ChainSubRuleCount; csr = csrs->ChainSubRule; for ( n = 0; n < count; n++ ) Gsub_Free_ChainSubRule( &csr[n], memory ); FREE( csr ); } } /* ChainContextSubstFormat1 */ static FT_Error Load_ChainContextSubst1( TTO_ChainContextSubstFormat1* ccsf1, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n = 0, m, count; FT_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, stream ) ) != 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], stream ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( m = 0; m < n; m++ ) Gsub_Free_ChainSubRuleSet( &csrs[m], memory ); FREE( csrs ); Fail2: Free_Coverage( &ccsf1->Coverage, memory ); return error; } static void Gsub_Free_ChainContext1( TTO_ChainContextSubstFormat1* ccsf1, FT_Memory memory ) { FT_UShort n, count; TTO_ChainSubRuleSet* csrs; if ( ccsf1->ChainSubRuleSet ) { count = ccsf1->ChainSubRuleSetCount; csrs = ccsf1->ChainSubRuleSet; for ( n = 0; n < count; n++ ) Gsub_Free_ChainSubRuleSet( &csrs[n], memory ); FREE( csrs ); } Free_Coverage( &ccsf1->Coverage, memory ); } /* ChainSubClassRule */ static FT_Error Load_ChainSubClassRule( TTO_ChainContextSubstFormat2* ccsf2, TTO_ChainSubClassRule* cscr, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, count; FT_UShort* b; FT_UShort* i; FT_UShort* l; TTO_SubstLookupRecord* slr; FT_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, FT_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, FT_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, FT_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 Gsub_Free_ChainSubClassRule( TTO_ChainSubClassRule* cscr, FT_Memory memory ) { FREE( cscr->SubstLookupRecord ); FREE( cscr->Lookahead ); FREE( cscr->Input ); FREE( cscr->Backtrack ); } /* SubClassSet */ static FT_Error Load_ChainSubClassSet( TTO_ChainContextSubstFormat2* ccsf2, TTO_ChainSubClassSet* cscs, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n = 0, m, count; FT_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->ChainSubClassRule = NULL; if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count, TTO_ChainSubClassRule ) ) return error; cscr = cscs->ChainSubClassRule; 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_ChainSubClassRule( ccsf2, &cscr[n], stream ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Gsub_Free_ChainSubClassRule( &cscr[m], memory ); FREE( cscr ); return error; } static void Gsub_Free_ChainSubClassSet( TTO_ChainSubClassSet* cscs, FT_Memory memory ) { FT_UShort n, count; TTO_ChainSubClassRule* cscr; if ( cscs->ChainSubClassRule ) { count = cscs->ChainSubClassRuleCount; cscr = cscs->ChainSubClassRule; for ( n = 0; n < count; n++ ) Gsub_Free_ChainSubClassRule( &cscr[n], memory ); FREE( cscr ); } } static FT_Error Gsub_Load_EmptyOrClassDefinition( TTO_ClassDefinition* cd, FT_UShort limit, FT_ULong class_offset, FT_ULong base_offset, FT_Stream stream ) { FT_Error error; FT_ULong cur_offset; cur_offset = FILE_Pos(); if ( class_offset ) { if ( !FILE_Seek( class_offset + base_offset ) ) error = Load_ClassDefinition( cd, limit, stream ); } else error = Load_EmptyClassDefinition ( cd, stream ); if (error == TT_Err_Ok) (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */ return error; } /* ChainContextSubstFormat2 */ static FT_Error Load_ChainContextSubst2( TTO_ChainContextSubstFormat2* ccsf2, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n = 0, m, count; FT_ULong cur_offset, new_offset, base_offset; FT_ULong backtrack_offset, input_offset, lookahead_offset; TTO_ChainSubClassSet* cscs; base_offset = FILE_Pos() - 2; 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( &ccsf2->Coverage, stream ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 8L ) ) goto Fail5; backtrack_offset = GET_UShort(); input_offset = GET_UShort(); lookahead_offset = GET_UShort(); /* `ChainSubClassSetCount' is the upper limit for input class values, thus we read it now to make an additional safety check. No limit is known or needed for the other two class definitions */ count = ccsf2->ChainSubClassSetCount = GET_UShort(); FORGET_Frame(); if ( ( error = Gsub_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535, backtrack_offset, base_offset, stream ) ) != TT_Err_Ok ) goto Fail5; if ( ( error = Gsub_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count, input_offset, base_offset, stream ) ) != TT_Err_Ok ) goto Fail4; if ( ( error = Gsub_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535, lookahead_offset, base_offset, stream ) ) != TT_Err_Ok ) goto Fail3; ccsf2->ChainSubClassSet = NULL; ccsf2->MaxBacktrackLength = 0; ccsf2->MaxInputLength = 0; ccsf2->MaxLookaheadLength = 0; if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, TTO_ChainSubClassSet ) ) goto Fail2; cscs = ccsf2->ChainSubClassSet; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail1; new_offset = GET_UShort() + base_offset; FORGET_Frame(); if ( new_offset != base_offset ) /* not a NULL offset */ { cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_ChainSubClassSet( ccsf2, &cscs[n], stream ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } else { /* we create a ChainSubClassSet table with no entries */ ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0; ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL; } } return TT_Err_Ok; Fail1: for ( m = 0; m < n; m++ ) Gsub_Free_ChainSubClassSet( &cscs[m], memory ); FREE( cscs ); Fail2: Free_ClassDefinition( &ccsf2->LookaheadClassDef, memory ); Fail3: Free_ClassDefinition( &ccsf2->InputClassDef, memory ); Fail4: Free_ClassDefinition( &ccsf2->BacktrackClassDef, memory ); Fail5: Free_Coverage( &ccsf2->Coverage, memory ); return error; } static void Gsub_Free_ChainContext2( TTO_ChainContextSubstFormat2* ccsf2, FT_Memory memory ) { FT_UShort n, count; TTO_ChainSubClassSet* cscs; if ( ccsf2->ChainSubClassSet ) { count = ccsf2->ChainSubClassSetCount; cscs = ccsf2->ChainSubClassSet; for ( n = 0; n < count; n++ ) Gsub_Free_ChainSubClassSet( &cscs[n], memory ); FREE( cscs ); } Free_ClassDefinition( &ccsf2->LookaheadClassDef, memory ); Free_ClassDefinition( &ccsf2->InputClassDef, memory ); Free_ClassDefinition( &ccsf2->BacktrackClassDef, memory ); Free_Coverage( &ccsf2->Coverage, memory ); } /* ChainContextSubstFormat3 */ static FT_Error Load_ChainContextSubst3( TTO_ChainContextSubstFormat3* ccsf3, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, nb = 0, ni =0, nl = 0, m, count; FT_UShort backtra
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -