📄 ftxgpos.c
字号:
new_offset = GET_UShort() + base_offset; /* `PosClassSetCount' is the upper limit for class values, thus we read it now to make an additional safety check. */ count = cpf2->PosClassSetCount = GET_UShort(); FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_ClassDefinition( &cpf2->ClassDef, count, input ) ) != TT_Err_Ok ) goto Fail3; (void)FILE_Seek( cur_offset ); cpf2->PosClassSet = NULL; cpf2->MaxContextLength = 0; if ( ALLOC_ARRAY( cpf2->PosClassSet, count, TTO_PosClassSet ) ) goto Fail2; pcs = cpf2->PosClassSet; 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_PosClassSet( cpf2, &pcs[n], input ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } else { /* we create a PosClassSet table with no entries */ cpf2->PosClassSet[n].PosClassRuleCount = 0; cpf2->PosClassSet[n].PosClassRule = NULL; } } return TT_Err_Ok; Fail1: for ( n = 0; n < count; n++ ) Free_PosClassSet( &pcs[n] ); FREE( pcs ); Fail2: Free_ClassDefinition( &cpf2->ClassDef ); Fail3: Free_Coverage( &cpf2->Coverage ); return error; } static void Free_Context2( TTO_ContextPosFormat2* cpf2 ) { UShort n, count; TTO_PosClassSet* pcs; if ( cpf2->PosClassSet ) { count = cpf2->PosClassSetCount; pcs = cpf2->PosClassSet; for ( n = 0; n < count; n++ ) Free_PosClassSet( &pcs[n] ); FREE( pcs ); } Free_ClassDefinition( &cpf2->ClassDef ); Free_Coverage( &cpf2->Coverage ); } /* ContextPosFormat3 */ static TT_Error Load_ContextPos3( TTO_ContextPosFormat3* cpf3, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_Coverage* c; TTO_PosLookupRecord* plr; base_offset = FILE_Pos() - 2L; if ( ACCESS_Frame( 4L ) ) return error; cpf3->GlyphCount = GET_UShort(); cpf3->PosCount = GET_UShort(); FORGET_Frame(); cpf3->Coverage = NULL; count = cpf3->GlyphCount; if ( ALLOC_ARRAY( cpf3->Coverage, count, TTO_Coverage ) ) return error; c = cpf3->Coverage; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail2; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &c[n], input ) ) != TT_Err_Ok ) goto Fail2; (void)FILE_Seek( cur_offset ); } cpf3->PosLookupRecord = NULL; count = cpf3->PosCount; if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, TTO_PosLookupRecord ) ) goto Fail2; plr = cpf3->PosLookupRecord; if ( ACCESS_Frame( count * 4L ) ) goto Fail1; for ( n = 0; n < count; n++ ) { plr[n].SequenceIndex = GET_UShort(); plr[n].LookupListIndex = GET_UShort(); } FORGET_Frame(); return TT_Err_Ok; Fail1: FREE( plr ); Fail2: for ( n = 0; n < count; n++ ) Free_Coverage( &c[n] ); FREE( c ); return error; } static void Free_Context3( TTO_ContextPosFormat3* cpf3 ) { UShort n, count; TTO_Coverage* c; FREE( cpf3->PosLookupRecord ); if ( cpf3->Coverage ) { count = cpf3->GlyphCount; c = cpf3->Coverage; for ( n = 0; n < count; n++ ) Free_Coverage( &c[n] ); FREE( c ); } } /* ContextPos */ TT_Error Load_ContextPos( TTO_ContextPos* cp, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); if ( ACCESS_Frame( 2L ) ) return error; cp->PosFormat = GET_UShort(); FORGET_Frame(); switch ( cp->PosFormat ) { case 1: return Load_ContextPos1( &cp->cpf.cpf1, input ); case 2: return Load_ContextPos2( &cp->cpf.cpf2, input ); case 3: return Load_ContextPos3( &cp->cpf.cpf3, input ); default: return TTO_Err_Invalid_GPOS_SubTable_Format; } return TT_Err_Ok; /* never reached */ } void Free_ContextPos( TTO_ContextPos* cp ) { switch ( cp->PosFormat ) { case 1: Free_Context1( &cp->cpf.cpf1 ); break; case 2: Free_Context2( &cp->cpf.cpf2 ); break; case 3: Free_Context3( &cp->cpf.cpf3 ); break; } } /* LookupType 8 */ /* ChainPosRule */ static TT_Error Load_ChainPosRule( TTO_ChainPosRule* cpr, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; UShort* b; UShort* i; UShort* l; TTO_PosLookupRecord* plr; if ( ACCESS_Frame( 2L ) ) return error; cpr->BacktrackGlyphCount = GET_UShort(); FORGET_Frame(); cpr->Backtrack = NULL; count = cpr->BacktrackGlyphCount; if ( ALLOC_ARRAY( cpr->Backtrack, count, UShort ) ) return error; b = cpr->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; cpr->InputGlyphCount = GET_UShort(); FORGET_Frame(); cpr->Input = NULL; count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ if ( ALLOC_ARRAY( cpr->Input, count, UShort ) ) goto Fail4; i = cpr->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; cpr->LookaheadGlyphCount = GET_UShort(); FORGET_Frame(); cpr->Lookahead = NULL; count = cpr->LookaheadGlyphCount; if ( ALLOC_ARRAY( cpr->Lookahead, count, UShort ) ) goto Fail3; l = cpr->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; cpr->PosCount = GET_UShort(); FORGET_Frame(); cpr->PosLookupRecord = NULL; count = cpr->PosCount; if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, TTO_PosLookupRecord ) ) goto Fail2; plr = cpr->PosLookupRecord; if ( ACCESS_Frame( count * 4L ) ) goto Fail1; for ( n = 0; n < count; n++ ) { plr[n].SequenceIndex = GET_UShort(); plr[n].LookupListIndex = GET_UShort(); } FORGET_Frame(); return TT_Err_Ok; Fail1: FREE( plr ); Fail2: FREE( l ); Fail3: FREE( i ); Fail4: FREE( b ); return error; } static void Free_ChainPosRule( TTO_ChainPosRule* cpr ) { FREE( cpr->PosLookupRecord ); FREE( cpr->Lookahead ); FREE( cpr->Input ); FREE( cpr->Backtrack ); } /* ChainPosRuleSet */ static TT_Error Load_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_ChainPosRule* cpr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = cprs->ChainPosRuleCount = GET_UShort(); FORGET_Frame(); cprs->ChainPosRule = NULL; if ( ALLOC_ARRAY( cprs->ChainPosRule, count, TTO_ChainPosRule ) ) return error; cpr = cprs->ChainPosRule; 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_ChainPosRule( &cpr[n], input ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( n = 0; n < count; n++ ) Free_ChainPosRule( &cpr[n] ); FREE( cpr ); return error; } static void Free_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs ) { UShort n, count; TTO_ChainPosRule* cpr; if ( cprs->ChainPosRule ) { count = cprs->ChainPosRuleCount; cpr = cprs->ChainPosRule; for ( n = 0; n < count; n++ ) Free_ChainPosRule( &cpr[n] ); FREE( cpr ); } } /* ChainContextPosFormat1 */ static TT_Error Load_ChainContextPos1( TTO_ChainContextPosFormat1* ccpf1, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_ChainPosRuleSet* cprs; 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( &ccpf1->Coverage, input ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail2; count = ccpf1->ChainPosRuleSetCount = GET_UShort(); FORGET_Frame(); ccpf1->ChainPosRuleSet = NULL; if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, TTO_ChainPosRuleSet ) ) goto Fail2; cprs = ccpf1->ChainPosRuleSet; 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_ChainPosRuleSet( &cprs[n], input ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( n = 0; n < count; n++ ) Free_ChainPosRuleSet( &cprs[n] ); FREE( cprs ); Fail2: Free_Coverage( &ccpf1->Coverage ); return error; } static void Free_ChainContext1( TTO_ChainContextPosFormat1* ccpf1 ) { UShort n, count; TTO_ChainPosRuleSet* cprs; if ( ccpf1->ChainPosRuleSet ) { count = ccpf1->ChainPosRuleSetCount; cprs = ccpf1->ChainPosRuleSet; for ( n = 0; n < count; n++ ) Free_ChainPosRuleSet( &cprs[n] ); FREE( cprs ); } Free_Coverage( &ccpf1->Coverage ); } /* ChainPosClassRule */ static TT_Error Load_ChainPosClassRule( TTO_ChainContextPosFormat2* ccpf2, TTO_ChainPosClassRule* cpcr, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; UShort* b; UShort* i; UShort* l; TTO_PosLookupRecord* plr; Bool* d; if ( ACCESS_Frame( 2L ) ) return error; cpcr->BacktrackGlyphCount = GET_UShort(); FORGET_Frame(); if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength ) ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount; cpcr->Backtrack = NULL; count = cpcr->BacktrackGlyphCount; if ( ALLOC_ARRAY( cpcr->Backtrack, count, UShort ) ) return error; b = cpcr->Backtrack; d = ccpf2->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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -