📄 harfbuzz-gsub.c
字号:
HB_SubRule* sr; if ( srs->SubRule ) { count = srs->SubRuleCount; sr = srs->SubRule; for ( n = 0; n < count; n++ ) Free_SubRule( &sr[n] ); FREE( sr ); }}/* ContextSubstFormat1 */static HB_Error Load_ContextSubst1( HB_ContextSubstFormat1* csf1, HB_Stream stream ){ HB_Error error; HB_UShort n = 0, m, count; HB_UInt 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 ) ) != HB_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 ) ) != HB_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return HB_Err_Ok;Fail1: for ( m = 0; m < n; m++ ) Free_SubRuleSet( &srs[m] ); FREE( srs );Fail2: _HB_OPEN_Free_Coverage( &csf1->Coverage ); return error;}static void Free_ContextSubst1( HB_ContextSubstFormat1* csf1 ){ HB_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] ); FREE( srs ); } _HB_OPEN_Free_Coverage( &csf1->Coverage );}/* SubClassRule */static HB_Error Load_SubClassRule( HB_ContextSubstFormat2* csf2, HB_SubClassRule* scr, HB_Stream stream ){ HB_Error error; HB_UShort n, count; HB_UShort* c; HB_SubstLookupRecord* slr; HB_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, HB_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 HB_Err_Ok;Fail1: FREE( slr );Fail2: FREE( c ); return error;}static void Free_SubClassRule( HB_SubClassRule* scr ){ FREE( scr->SubstLookupRecord ); FREE( scr->Class );}/* SubClassSet */static HB_Error Load_SubClassSet( HB_ContextSubstFormat2* csf2, HB_SubClassSet* scs, HB_Stream stream ){ HB_Error error; HB_UShort n = 0, m, count; HB_UInt 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 ) ) != HB_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return HB_Err_Ok;Fail: for ( m = 0; m < n; m++ ) Free_SubClassRule( &scr[m] ); FREE( scr ); return error;}static void Free_SubClassSet( HB_SubClassSet* scs ){ HB_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] ); FREE( scr ); }}/* ContextSubstFormat2 */static HB_Error Load_ContextSubst2( HB_ContextSubstFormat2* csf2, HB_Stream stream ){ HB_Error error; HB_UShort n = 0, m, count; HB_UInt 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 ) ) != HB_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 ) ) != HB_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 ) ) != HB_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 HB_Err_Ok;Fail1: for ( m = 0; m < n; m++ ) Free_SubClassSet( &scs[m] ); FREE( scs );Fail2: _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );Fail3: _HB_OPEN_Free_Coverage( &csf2->Coverage ); return error;}static void Free_ContextSubst2( HB_ContextSubstFormat2* csf2 ){ HB_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] ); FREE( scs ); } _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef ); _HB_OPEN_Free_Coverage( &csf2->Coverage );}/* ContextSubstFormat3 */static HB_Error Load_ContextSubst3( HB_ContextSubstFormat3* csf3, HB_Stream stream ){ HB_Error error; HB_UShort n = 0, m, count; HB_UInt 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 ) ) != HB_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 HB_Err_Ok;Fail1: FREE( slr );Fail2: for ( m = 0; m < n; m++ ) _HB_OPEN_Free_Coverage( &c[m] ); FREE( c ); return error;}static void Free_ContextSubst3( HB_ContextSubstFormat3* csf3 ){ HB_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] ); FREE( c ); }}/* ContextSubst */static HB_Error Load_ContextSubst( HB_GSUB_SubTable* st, HB_Stream stream ){ HB_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 ERR(HB_Err_Invalid_SubTable_Format); } return HB_Err_Ok; /* never reached */}static void Free_ContextSubst( HB_GSUB_SubTable* st ){ HB_ContextSubst* cs = &st->context; switch ( cs->SubstFormat ) { case 1: Free_ContextSubst1( &cs->csf.csf1 ); break; case 2: Free_ContextSubst2( &cs->csf.csf2 ); break; case 3: Free_ContextSubst3( &cs->csf.csf3 ); break; default: break; }}static HB_Error Lookup_ContextSubst1( HB_GSUBHeader* gsub, HB_ContextSubstFormat1* csf1, HB_Buffer buffer, HB_UShort flags, HB_UShort context_length, int nesting_level ){ HB_UShort index, property; HB_UShort i, j, k, numsr; HB_Error error; HB_SubRule* sr; HB_GDEFHeader* gdef; gdef = gsub->gdef; if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) return error; error = _HB_OPEN_Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &index ); if ( error ) return error; sr = csf1->SubRuleSet[index].SubRule; numsr = csf1->SubRuleSet[index].SubRuleCount; for ( k = 0; k < numsr; k++ ) { if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount ) goto next_subrule; if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length ) goto next_subrule; /* context is too long */ for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ ) { while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) { if ( error && error != HB_Err_Not_Covered ) return error; if ( j + sr[k].GlyphCount - i == (HB_Int)buffer->in_length ) goto next_subrule; j++; } if ( IN_GLYPH( j ) != sr[k].Input[i - 1] ) goto next_subrule; } return Do_ContextSubst( gsub, sr[k].GlyphCount, sr[k].SubstCount, sr[k].SubstLookupRecord, buffer, nesting_level ); next_subrule: ; } return HB_Err_Not_Covered;}static HB_Error Lookup_ContextSubst2( HB_GSUBHeader* gsub, HB_ContextSubstFormat2* csf2, HB_Buffer buffer, HB_UShort flags, HB_UShort context_length, int nesting_level ){ HB_UShort index, property; HB_Error error; HB_UShort i, j, k, known_classes; HB_UShort* classes; HB_UShort* cl; HB_SubClassSet* scs; HB_SubClassRule* sr; HB_GDEFHeader* gdef; gdef = gsub->gdef;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -