📄 harfbuzz-gsub.c
字号:
HB_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, HB_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 ) ) != FT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return FT_Err_Ok;Fail: for ( m = 0; m < n; m++ ) Free_SubRule( &sr[m], memory ); FREE( sr ); return error;}static void Free_SubRuleSet( HB_SubRuleSet* srs, FT_Memory memory ){ FT_UShort n, count; HB_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( HB_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; HB_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 = _HB_OPEN_Load_Coverage( &csf1->Coverage, stream ) ) != FT_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, HB_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 ) ) != FT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return FT_Err_Ok;Fail1: for ( m = 0; m < n; m++ ) Free_SubRuleSet( &srs[m], memory ); FREE( srs );Fail2: _HB_OPEN_Free_Coverage( &csf1->Coverage, memory ); return error;}static void Free_ContextSubst1( HB_ContextSubstFormat1* csf1, FT_Memory memory ){ FT_UShort n, count; HB_SubRuleSet* srs; if ( csf1->SubRuleSet ) { count = csf1->SubRuleSetCount; srs = csf1->SubRuleSet; for ( n = 0; n < count; n++ ) Free_SubRuleSet( &srs[n], memory ); FREE( srs ); } _HB_OPEN_Free_Coverage( &csf1->Coverage, memory );}/* SubClassRule */static FT_Error Load_SubClassRule( HB_ContextSubstFormat2* csf2, HB_SubClassRule* scr, FT_Stream stream ){ FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, count; FT_UShort* c; HB_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, HB_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 FT_Err_Ok;Fail1: FREE( slr );Fail2: FREE( c ); return error;}static void Free_SubClassRule( HB_SubClassRule* scr, FT_Memory memory ){ FREE( scr->SubstLookupRecord ); FREE( scr->Class );}/* SubClassSet */static FT_Error Load_SubClassSet( HB_ContextSubstFormat2* csf2, HB_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; HB_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, HB_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 ) ) != FT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return FT_Err_Ok;Fail: for ( m = 0; m < n; m++ ) Free_SubClassRule( &scr[m], memory ); FREE( scr ); return error;}static void Free_SubClassSet( HB_SubClassSet* scs, FT_Memory memory ){ FT_UShort n, count; HB_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( HB_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; HB_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 = _HB_OPEN_Load_Coverage( &csf2->Coverage, stream ) ) != FT_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 = _HB_OPEN_Load_ClassDefinition( &csf2->ClassDef, count, stream ) ) != FT_Err_Ok ) goto Fail3; (void)FILE_Seek( cur_offset ); csf2->SubClassSet = NULL; csf2->MaxContextLength = 0; if ( ALLOC_ARRAY( csf2->SubClassSet, count, HB_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 ) ) != FT_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 FT_Err_Ok;Fail1: for ( m = 0; m < n; m++ ) Free_SubClassSet( &scs[m], memory ); FREE( scs );Fail2: _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef, memory );Fail3: _HB_OPEN_Free_Coverage( &csf2->Coverage, memory ); return error;}static void Free_ContextSubst2( HB_ContextSubstFormat2* csf2, FT_Memory memory ){ FT_UShort n, count; HB_SubClassSet* scs; if ( csf2->SubClassSet ) { count = csf2->SubClassSetCount; scs = csf2->SubClassSet; for ( n = 0; n < count; n++ ) Free_SubClassSet( &scs[n], memory ); FREE( scs ); } _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef, memory ); _HB_OPEN_Free_Coverage( &csf2->Coverage, memory );}/* ContextSubstFormat3 */static FT_Error Load_ContextSubst3( HB_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; HB_Coverage* c; HB_SubstLookupRecord* slr; base_offset = FILE_Pos() - 2L; if ( ACCESS_Frame( 4L ) ) return error; csf3->GlyphCount = GET_UShort(); csf3->SubstCount = GET_UShort(); FORGET_Frame(); csf3->Coverage = NULL; count = csf3->GlyphCount; if ( ALLOC_ARRAY( csf3->Coverage, count, HB_Coverage ) ) return error; c = csf3->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 = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != FT_Err_Ok ) goto Fail2; (void)FILE_Seek( cur_offset ); } csf3->SubstLookupRecord = NULL; count = csf3->SubstCount; if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count, HB_SubstLookupRecord ) ) goto Fail2; slr = csf3->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 FT_Err_Ok;Fail1: FREE( slr );Fail2: for ( m = 0; m < n; m++ ) _HB_OPEN_Free_Coverage( &c[m], memory ); FREE( c ); return error;}static void Free_ContextSubst3( HB_ContextSubstFormat3* csf3, FT_Memory memory ){ FT_UShort n, count; HB_Coverage* c; FREE( csf3->SubstLookupRecord ); if ( csf3->Coverage ) { count = csf3->GlyphCount; c = csf3->Coverage; for ( n = 0; n < count; n++ ) _HB_OPEN_Free_Coverage( &c[n], memory ); FREE( c ); }}/* ContextSubst */static FT_Error Load_ContextSubst( HB_GSUB_SubTable* st, FT_Stream stream ){ FT_Error error; HB_ContextSubst* cs = &st->context; if ( ACCESS_Frame( 2L ) ) return error; cs->SubstFormat = GET_UShort(); FORGET_Frame(); switch ( cs->SubstFormat ) { case 1: return Load_ContextSubst1( &cs->csf.csf1, stream ); case 2: return Load_ContextSubst2( &cs->csf.csf2, stream ); case 3: return Load_ContextSubst3( &cs->csf.csf3, stream ); default: return HB_Err_Invalid_GSUB_SubTable_Format; } return FT_Err_Ok; /* never reached */}static void Free_ContextSubst( HB_GSUB_SubTable* st, FT_Memory memory ){ HB_ContextSubst* cs = &st->context; switch ( cs->SubstFormat ) { case 1: Free_ContextSubst1( &cs->csf.csf1, memory ); break; case 2: Free_ContextSubst2( &cs->csf.csf2, memory ); break; case 3: Free_ContextSubst3( &cs->csf.csf3, memory ); break; }}static FT_Error Lookup_ContextSubst1( HB_GSUBHeader* gsub, HB_ContextSubstFormat1* csf1, HB_Buffer buffer, FT_UShort flags, FT_UShort context_length, int nesting_level ){ FT_UShort index, property; FT_UShort i, j, k, numsr; FT_Error error; HB_SubRule* sr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -