📄 ftxgsub.c
字号:
{ FREE( sub ); return error; } for ( n = 0; n < count; n++ ) sub[n] = GET_UShort(); FORGET_Frame(); } return TT_Err_Ok; } static void Free_Sequence( TTO_Sequence* s ) { FREE( s->Substitute ); } /* MultipleSubstFormat1 */ TT_Error Load_MultipleSubst( TTO_MultipleSubst* ms, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_Sequence* s; base_offset = FILE_Pos(); if ( ACCESS_Frame( 4L ) ) return error; ms->SubstFormat = GET_UShort(); /* should be 1 */ new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &ms->Coverage, input ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail2; count = ms->SequenceCount = GET_UShort(); FORGET_Frame(); ms->Sequence = NULL; if ( ALLOC_ARRAY( ms->Sequence, count, TTO_Sequence ) ) goto Fail2; s = ms->Sequence; 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_Sequence( &s[n], input ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( n = 0; n < count; n++ ) Free_Sequence( &s[n] ); FREE( s ); Fail2: Free_Coverage( &ms->Coverage ); return error; } void Free_MultipleSubst( TTO_MultipleSubst* ms ) { UShort n, count; TTO_Sequence* s; if ( ms->Sequence ) { count = ms->SequenceCount; s = ms->Sequence; for ( n = 0; n < count; n++ ) Free_Sequence( &s[n] ); FREE( s ); } Free_Coverage( &ms->Coverage ); } static TT_Error Lookup_MultipleSubst( TTO_MultipleSubst* ms, TTO_GSUB_String* in, TTO_GSUB_String* out, UShort flags, UShort context_length, TTO_GDEFHeader* gdef ) { TT_Error error; UShort index, property, n, count; UShort* s; if ( context_length != 0xFFFF && context_length < 1 ) return TTO_Err_Not_Covered; if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) return error; error = Coverage_Index( &ms->Coverage, in->string[in->pos], &index ); if ( error ) return error; if ( index >= ms->SequenceCount ) return TTO_Err_Invalid_GSUB_SubTable; count = ms->Sequence[index].GlyphCount; s = ms->Sequence[index].Substitute; if ( ADD_String( in, 1, out, count, s ) ) return error; if ( gdef && gdef->NewGlyphClasses ) { /* this is a guess only ... */ if ( property == TTO_LIGATURE ) property = TTO_BASE_GLYPH; for ( n = 0; n < count; n++ ) { error = Add_Glyph_Property( gdef, s[n], property ); if ( error && error != TTO_Err_Not_Covered ) return error; } } return TT_Err_Ok; } /* LookupType 3 */ /* AlternateSet */ static TT_Error Load_AlternateSet( TTO_AlternateSet* as, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; UShort* a; if ( ACCESS_Frame( 2L ) ) return error; count = as->GlyphCount = GET_UShort(); FORGET_Frame(); as->Alternate = NULL; if ( ALLOC_ARRAY( as->Alternate, count, UShort ) ) return error; a = as->Alternate; if ( ACCESS_Frame( count * 2L ) ) { FREE( a ); return error; } for ( n = 0; n < count; n++ ) a[n] = GET_UShort(); FORGET_Frame(); return TT_Err_Ok; } static void Free_AlternateSet( TTO_AlternateSet* as ) { FREE( as->Alternate ); } /* AlternateSubstFormat1 */ TT_Error Load_AlternateSubst( TTO_AlternateSubst* as, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_AlternateSet* aset; base_offset = FILE_Pos(); if ( ACCESS_Frame( 4L ) ) return error; as->SubstFormat = GET_UShort(); /* should be 1 */ new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &as->Coverage, input ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail2; count = as->AlternateSetCount = GET_UShort(); FORGET_Frame(); as->AlternateSet = NULL; if ( ALLOC_ARRAY( as->AlternateSet, count, TTO_AlternateSet ) ) goto Fail2; aset = as->AlternateSet; 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_AlternateSet( &aset[n], input ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( n = 0; n < count; n++ ) Free_AlternateSet( &aset[n] ); FREE( aset ); Fail2: Free_Coverage( &as->Coverage ); return error; } void Free_AlternateSubst( TTO_AlternateSubst* as ) { UShort n, count; TTO_AlternateSet* aset; if ( as->AlternateSet ) { count = as->AlternateSetCount; aset = as->AlternateSet; for ( n = 0; n < count; n++ ) Free_AlternateSet( &aset[n] ); FREE( aset ); } Free_Coverage( &as->Coverage ); } static TT_Error Lookup_AlternateSubst( TTO_GSUBHeader* gsub, TTO_AlternateSubst* as, TTO_GSUB_String* in, TTO_GSUB_String* out, UShort flags, UShort context_length, TTO_GDEFHeader* gdef ) { TT_Error error; UShort index, alt_index, property; TTO_AlternateSet aset; if ( context_length != 0xFFFF && context_length < 1 ) return TTO_Err_Not_Covered; if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) return error; error = Coverage_Index( &as->Coverage, in->string[in->pos], &index ); if ( error ) return error; aset = as->AlternateSet[index]; /* we use a user-defined callback function to get the alternate index */ if ( gsub->alt ) alt_index = (gsub->alt)( out->pos, in->string[in->pos], aset.GlyphCount, aset.Alternate, gsub->data ); else alt_index = 0; if ( ADD_String( in, 1, out, 1, &aset.Alternate[alt_index] ) ) return error; if ( gdef && gdef->NewGlyphClasses ) { /* we inherit the old glyph class to the substituted glyph */ error = Add_Glyph_Property( gdef, aset.Alternate[alt_index], property ); if ( error && error != TTO_Err_Not_Covered ) return error; } return TT_Err_Ok; } /* LookupType 4 */ /* Ligature */ static TT_Error Load_Ligature( TTO_Ligature* l, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; UShort* c; if ( ACCESS_Frame( 4L ) ) return error; l->LigGlyph = GET_UShort(); l->ComponentCount = GET_UShort(); FORGET_Frame(); l->Component = NULL; count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */ if ( ALLOC_ARRAY( l->Component, count, UShort ) ) return error; c = l->Component; if ( ACCESS_Frame( count * 2L ) ) { FREE( c ); return error; } for ( n = 0; n < count; n++ ) c[n] = GET_UShort(); FORGET_Frame(); return TT_Err_Ok; } static void Free_Ligature( TTO_Ligature* l ) { FREE( l->Component ); } /* LigatureSet */ static TT_Error Load_LigatureSet( TTO_LigatureSet* ls, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_Ligature* l; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = ls->LigatureCount = GET_UShort(); FORGET_Frame(); ls->Ligature = NULL; if ( ALLOC_ARRAY( ls->Ligature, count, TTO_Ligature ) ) return error; l = ls->Ligature; 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_Ligature( &l[n], input ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( n = 0; n < count; n++ ) Free_Ligature( &l[n] ); FREE( l ); return error; } static void Free_LigatureSet( TTO_LigatureSet* ls ) { UShort n, count; TTO_Ligature* l; if ( ls->Ligature ) { count = ls->LigatureCount; l = ls->Ligature; for ( n = 0; n < count; n++ ) Free_Ligature( &l[n] ); FREE( l ); } } /* LigatureSubstFormat1 */ TT_Error Load_LigatureSubst( TTO_LigatureSubst* ls, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_LigatureSet* lset; base_offset = FILE_Pos(); if ( ACCESS_Frame( 4L ) ) return error; ls->SubstFormat = GET_UShort(); /* should be 1 */ new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &ls->Coverage, input ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail2; count = ls->LigatureSetCount = GET_UShort(); FORGET_Frame(); ls->LigatureSet = NULL; if ( ALLOC_ARRAY( ls->LigatureSet, count, TTO_LigatureSet ) ) goto Fail2; lset = ls->LigatureSet; 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_LigatureSet( &lset[n], input ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( n = 0; n < count; n++ ) Free_LigatureSet( &lset[n] ); FREE( lset ); Fail2: Free_Coverage( &ls->Coverage ); return error; } void Free_LigatureSubst( TTO_LigatureSubst* ls ) { UShort n, count; TTO_LigatureSet* lset; if ( ls->LigatureSet ) { count = ls->LigatureSetCount; lset = ls->LigatureSet; for ( n = 0; n < count; n++ ) Free_LigatureSet( &lset[n] ); FREE( lset ); } Free_Coverage( &ls->Coverage );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -