📄 ftxgsub.c
字号:
} /* LookupType 5 */ /* SubRule */ static FT_Error Load_SubRule( TTO_SubRule* sr, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, count; FT_UShort* i; TTO_SubstLookupRecord* slr; if ( ACCESS_Frame( 4L ) ) return error; sr->GlyphCount = GET_UShort(); sr->SubstCount = GET_UShort(); FORGET_Frame(); sr->Input = NULL; count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */ if ( ALLOC_ARRAY( sr->Input, count, FT_UShort ) ) return error; i = sr->Input; if ( ACCESS_Frame( count * 2L ) ) goto Fail2; for ( n = 0; n < count; n++ ) i[n] = GET_UShort(); FORGET_Frame(); sr->SubstLookupRecord = NULL; count = sr->SubstCount; if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) goto Fail2; slr = sr->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( i ); return error; } static void Free_SubRule( TTO_SubRule* sr, FT_Memory memory ) { FREE( sr->SubstLookupRecord ); FREE( sr->Input ); } /* SubRuleSet */ static FT_Error Load_SubRuleSet( TTO_SubRuleSet* srs, 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_SubRule* sr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = srs->SubRuleCount = GET_UShort(); FORGET_Frame(); srs->SubRule = NULL; if ( ALLOC_ARRAY( srs->SubRule, count, TTO_SubRule ) ) return error; sr = srs->SubRule; 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_SubRule( &sr[n], stream ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Free_SubRule( &sr[m], memory ); FREE( sr ); return error; } static void Free_SubRuleSet( TTO_SubRuleSet* srs, FT_Memory memory ) { FT_UShort n, count; TTO_SubRule* sr; if ( srs->SubRule ) { count = srs->SubRuleCount; sr = srs->SubRule; for ( n = 0; n < count; n++ ) Free_SubRule( &sr[n], memory ); FREE( sr ); } } /* ContextSubstFormat1 */ static FT_Error Load_ContextSubst1( TTO_ContextSubstFormat1* csf1, 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_SubRuleSet* srs; 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( &csf1->Coverage, stream ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail2; count = csf1->SubRuleSetCount = GET_UShort(); FORGET_Frame(); csf1->SubRuleSet = NULL; if ( ALLOC_ARRAY( csf1->SubRuleSet, count, TTO_SubRuleSet ) ) goto Fail2; srs = csf1->SubRuleSet; 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_SubRuleSet( &srs[n], stream ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( m = 0; m < n; m++ ) Free_SubRuleSet( &srs[m], memory ); FREE( srs ); Fail2: Free_Coverage( &csf1->Coverage, memory ); return error; } static void Gsub_Free_Context1( TTO_ContextSubstFormat1* csf1, FT_Memory memory ) { FT_UShort n, count; TTO_SubRuleSet* srs; if ( csf1->SubRuleSet ) { count = csf1->SubRuleSetCount; srs = csf1->SubRuleSet; for ( n = 0; n < count; n++ ) Free_SubRuleSet( &srs[n], memory ); FREE( srs ); } Free_Coverage( &csf1->Coverage, memory ); } /* SubClassRule */ static FT_Error Load_SubClassRule( TTO_ContextSubstFormat2* csf2, TTO_SubClassRule* scr, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, count; FT_UShort* c; TTO_SubstLookupRecord* slr; FT_Bool* d; if ( ACCESS_Frame( 4L ) ) return error; scr->GlyphCount = GET_UShort(); scr->SubstCount = GET_UShort(); if ( scr->GlyphCount > csf2->MaxContextLength ) csf2->MaxContextLength = scr->GlyphCount; FORGET_Frame(); scr->Class = NULL; count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */ if ( ALLOC_ARRAY( scr->Class, count, FT_UShort ) ) return error; c = scr->Class; d = csf2->ClassDef.Defined; if ( ACCESS_Frame( count * 2L ) ) goto Fail2; for ( n = 0; n < count; n++ ) { c[n] = GET_UShort(); /* We check whether the specific class is used at all. If not, class 0 is used instead. */ if ( !d[c[n]] ) c[n] = 0; } FORGET_Frame(); scr->SubstLookupRecord = NULL; count = scr->SubstCount; if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) goto Fail2; slr = scr->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( c ); return error; } static void Free_SubClassRule( TTO_SubClassRule* scr, FT_Memory memory ) { FREE( scr->SubstLookupRecord ); FREE( scr->Class ); } /* SubClassSet */ static FT_Error Load_SubClassSet( TTO_ContextSubstFormat2* csf2, TTO_SubClassSet* scs, 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_SubClassRule* scr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = scs->SubClassRuleCount = GET_UShort(); FORGET_Frame(); scs->SubClassRule = NULL; if ( ALLOC_ARRAY( scs->SubClassRule, count, TTO_SubClassRule ) ) return error; scr = scs->SubClassRule; 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_SubClassRule( csf2, &scr[n], stream ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Free_SubClassRule( &scr[m], memory ); FREE( scr ); return error; } static void Free_SubClassSet( TTO_SubClassSet* scs, FT_Memory memory ) { FT_UShort n, count; TTO_SubClassRule* scr; if ( scs->SubClassRule ) { count = scs->SubClassRuleCount; scr = scs->SubClassRule; for ( n = 0; n < count; n++ ) Free_SubClassRule( &scr[n], memory ); FREE( scr ); } } /* ContextSubstFormat2 */ static FT_Error Load_ContextSubst2( TTO_ContextSubstFormat2* csf2, 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_SubClassSet* scs; 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( &csf2->Coverage, stream ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 4L ) ) goto Fail3; new_offset = GET_UShort() + base_offset; /* `SubClassSetCount' is the upper limit for class values, thus we read it now to make an additional safety check. */ count = csf2->SubClassSetCount = GET_UShort(); FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_ClassDefinition( &csf2->ClassDef, count, stream ) ) != TT_Err_Ok ) goto Fail3; (void)FILE_Seek( cur_offset ); csf2->SubClassSet = NULL; csf2->MaxContextLength = 0; if ( ALLOC_ARRAY( csf2->SubClassSet, count, TTO_SubClassSet ) ) goto Fail2; scs = csf2->SubClassSet; 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_SubClassSet( csf2, &scs[n], stream ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } else { /* we create a SubClassSet table with no entries */ csf2->SubClassSet[n].SubClassRuleCount = 0; csf2->SubClassSet[n].SubClassRule = NULL; } } return TT_Err_Ok; Fail1: for ( m = 0; m < n; m++ ) Free_SubClassSet( &scs[m], memory ); FREE( scs ); Fail2: Free_ClassDefinition( &csf2->ClassDef, memory ); Fail3: Free_Coverage( &csf2->Coverage, memory ); return error; } static void Gsub_Free_Context2( TTO_ContextSubstFormat2* csf2, FT_Memory memory ) { FT_UShort n, count; TTO_SubClassSet* scs; if ( csf2->SubClassSet ) { count = csf2->SubClassSetCount; scs = csf2->SubClassSet; for ( n = 0; n < count; n++ ) Free_SubClassSet( &scs[n], memory ); FREE( scs ); } Free_ClassDefinition( &csf2->ClassDef, memory ); Free_Coverage( &csf2->Coverage, memory ); } /* ContextSubstFormat3 */ static FT_Error Load_ContextSubst3( TTO_ContextSubstFormat3* csf3, 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_Coverage* c; TTO_SubstLookupRecord* slr; base_offset = FILE_Pos() - 2L; if ( ACCESS_Frame( 4L ) ) return error; csf3->GlyphCount = GET_UShort(); csf3->SubstCount = GET_UShort(); FORGET_Frame();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -