?? ftxgpos.c
字號:
if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, TTO_ValueRecord ) ) goto Fail2; vr = sp->spf.spf2.Value; for ( n = 0; n < count; n++ ) { error = Load_ValueRecord( &vr[n], format, base_offset, input ); if ( error ) goto Fail1; } break; default: return TTO_Err_Invalid_GPOS_SubTable_Format; } return TT_Err_Ok; Fail1: for ( n = 0; n < count; n++ ) Free_ValueRecord( &vr[n], format ); FREE( vr ); Fail2: Free_Coverage( &sp->Coverage ); return error; } void Free_SinglePos( TTO_SinglePos* sp ) { UShort n, count, format; TTO_ValueRecord* v; format = sp->ValueFormat; switch ( sp->PosFormat ) { case 1: Free_ValueRecord( &sp->spf.spf1.Value, format ); break; case 2: if ( sp->spf.spf2.Value ) { count = sp->spf.spf2.ValueCount; v = sp->spf.spf2.Value; for ( n = 0; n < count; n++ ) Free_ValueRecord( &v[n], format ); FREE( v ); } break; } Free_Coverage( &sp->Coverage ); } static TT_Error Lookup_SinglePos( GPOS_Instance* gpi, TTO_SinglePos* sp, TTO_GSUB_String* in, TTO_GPOS_Data* out, UShort flags, UShort context_length ) { UShort index, property; TT_Error error; TTO_GPOSHeader* gpos = gpi->gpos; if ( context_length != 0xFFFF && context_length < 1 ) return TTO_Err_Not_Covered; if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) ) return error; error = Coverage_Index( &sp->Coverage, in->string[in->pos], &index ); if ( error ) return error; switch ( sp->PosFormat ) { case 1: error = Get_ValueRecord( gpi, &sp->spf.spf1.Value, sp->ValueFormat, &out[in->pos] ); if ( error ) return error; break; case 2: if ( index >= sp->spf.spf2.ValueCount ) return TTO_Err_Invalid_GPOS_SubTable; error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index], sp->ValueFormat, &out[in->pos] ); if ( error ) return error; break; default: return TTO_Err_Invalid_GPOS_SubTable; } (in->pos)++; return TT_Err_Ok; } /* LookupType 2 */ /* PairSet */ static TT_Error Load_PairSet ( TTO_PairSet* ps, UShort format1, UShort format2, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong base_offset; TTO_PairValueRecord* pvr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = ps->PairValueCount = GET_UShort(); FORGET_Frame(); ps->PairValueRecord = NULL; if ( ALLOC_ARRAY( ps->PairValueRecord, count, TTO_PairValueRecord ) ) return error; pvr = ps->PairValueRecord; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail; pvr[n].SecondGlyph = GET_UShort(); FORGET_Frame(); if ( format1 ) { error = Load_ValueRecord( &pvr[n].Value1, format1, base_offset, input ); if ( error ) goto Fail; } if ( format2 ) { error = Load_ValueRecord( &pvr[n].Value2, format2, base_offset, input ); if ( error ) goto Fail; } } return TT_Err_Ok; Fail: for ( n = 0; n < count; n++ ) { if ( format1 ) Free_ValueRecord( &pvr[n].Value1, format1 ); if ( format2 ) Free_ValueRecord( &pvr[n].Value2, format2 ); } FREE( pvr ); return error; } static void Free_PairSet( TTO_PairSet* ps, UShort format1, UShort format2 ) { UShort n, count; TTO_PairValueRecord* pvr; if ( ps->PairValueRecord ) { count = ps->PairValueCount; pvr = ps->PairValueRecord; for ( n = 0; n < count; n++ ) { if ( format1 ) Free_ValueRecord( &pvr[n].Value1, format1 ); if ( format2 ) Free_ValueRecord( &pvr[n].Value2, format2 ); } FREE( pvr ); } } /* PairPosFormat1 */ static TT_Error Load_PairPos1( TTO_PairPosFormat1* ppf1, UShort format1, UShort format2, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort n, count; ULong cur_offset, new_offset, base_offset; TTO_PairSet* ps; base_offset = FILE_Pos() - 8L; if ( ACCESS_Frame( 2L ) ) return error; count = ppf1->PairSetCount = GET_UShort(); FORGET_Frame(); ppf1->PairSet = NULL; if ( ALLOC_ARRAY( ppf1->PairSet, count, TTO_PairSet ) ) goto Fail; ps = ppf1->PairSet; 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_PairSet( &ps[n], format1, format2, input ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( n = 0; n < count; n++ ) Free_PairSet( &ps[n], format1, format2 ); FREE( ps ); return error; } static void Free_PairPos1( TTO_PairPosFormat1* ppf1, UShort format1, UShort format2 ) { UShort n, count; TTO_PairSet* ps; if ( ppf1->PairSet ) { count = ppf1->PairSetCount; ps = ppf1->PairSet; for ( n = 0; n < count; n++ ) Free_PairSet( &ps[n], format1, format2 ); FREE( ps ); } } /* PairPosFormat2 */ static TT_Error Load_PairPos2( TTO_PairPosFormat2* ppf2, UShort format1, UShort format2, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort m, n, count1, count2; ULong cur_offset, new_offset1, new_offset2, base_offset; TTO_Class1Record* c1r; TTO_Class2Record* c2r; base_offset = FILE_Pos() - 8L; if ( ACCESS_Frame( 8L ) ) return error; new_offset1 = GET_UShort() + base_offset; new_offset2 = GET_UShort() + base_offset; /* `Class1Count' and `Class2Count' are the upper limits for class values, thus we read it now to make additional safety checks. */ count1 = ppf2->Class1Count = GET_UShort(); count2 = ppf2->Class2Count = GET_UShort(); FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset1 ) || ( error = Load_ClassDefinition( &ppf2->ClassDef1, count1, input ) ) != TT_Err_Ok ) return error; if ( FILE_Seek( new_offset2 ) || ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2, input ) ) != TT_Err_Ok ) goto Fail2; (void)FILE_Seek( cur_offset ); ppf2->Class1Record = NULL; if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) ) goto Fail1; c1r = ppf2->Class1Record; for ( m = 0; m < count1; m++ ) { c1r[m].Class2Record = NULL; if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, TTO_Class2Record ) ) goto Fail1; c2r = c1r[m].Class2Record; for ( n = 0; n < count2; n++ ) { if ( format1 ) { error = Load_ValueRecord( &c2r[n].Value1, format1, base_offset, input ); if ( error ) goto Fail1; } if ( format2 ) { error = Load_ValueRecord( &c2r[n].Value2, format2, base_offset, input ); if ( error ) goto Fail1; } } } return TT_Err_Ok; Fail1: for ( m = 0; m < count1; m++ ) { c2r = c1r[m].Class2Record; for ( n = 0; n < count2; n++ ) { if ( format1 ) Free_ValueRecord( &c2r[n].Value1, format1 ); if ( format2 ) Free_ValueRecord( &c2r[n].Value2, format2 ); } FREE( c2r ); } FREE( c1r ); Free_ClassDefinition( &ppf2->ClassDef2 ); Fail2: Free_ClassDefinition( &ppf2->ClassDef1 ); return error; } static void Free_PairPos2( TTO_PairPosFormat2* ppf2, UShort format1, UShort format2 ) { UShort m, n, count1, count2; TTO_Class1Record* c1r; TTO_Class2Record* c2r; if ( ppf2->Class1Record ) { c1r = ppf2->Class1Record; count1 = ppf2->Class1Count; count2 = ppf2->Class2Count; for ( m = 0; m < count1; m++ ) { c2r = c1r[m].Class2Record; for ( n = 0; n < count2; n++ ) { if ( format1 ) Free_ValueRecord( &c2r[n].Value1, format1 ); if ( format2 ) Free_ValueRecord( &c2r[n].Value2, format2 ); } FREE( c2r ); } FREE( c1r ); Free_ClassDefinition( &ppf2->ClassDef2 ); Free_ClassDefinition( &ppf2->ClassDef1 ); } } TT_Error Load_PairPos( TTO_PairPos* pp, PFace input ) { DEFINE_LOAD_LOCALS( input->stream ); UShort format1, format2; ULong cur_offset, new_offset, base_offset; base_offset = FILE_Pos(); if ( ACCESS_Frame( 8L ) ) return error; pp->PosFormat = GET_UShort(); new_offset = GET_UShort() + base_offset; format1 = pp->ValueFormat1 = GET_UShort(); format2 = pp->ValueFormat2 = GET_UShort(); FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &pp->Coverage, input ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); switch ( pp->PosFormat ) { case 1: error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, input ); if ( error ) goto Fail; break; case 2: error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, input ); if ( error ) goto Fail; break; default: return TTO_Err_Invalid_GPOS_SubTable_Format; } return TT_Err_Ok; Fail: Free_Coverage( &pp->Coverage ); return error; } void Free_PairPos( TTO_PairPos* pp ) { UShort format1, format2; format1 = pp->ValueFormat1; format2 = pp->ValueFormat2; switch ( pp->PosFormat ) { case 1: Free_PairPos1( &pp->ppf.ppf1, format1, format2 ); break; case 2: Free_PairPos2( &pp->ppf.ppf2, format1, format2 ); break; } Free_Coverage( &pp->Coverage ); } static TT_Error Lookup_PairPos1( GPOS_Instance* gpi, TTO_PairPosFormat1* ppf1, TTO_GSUB_String* in, TTO_GPOS_Data* out, UShort first_pos, UShort index, UShort format1, UShort format2 ) { TT_Error error; UShort numpvr, glyph2; TTO_PairValueRecord* pvr; if ( index >= ppf1->PairSetCount ) return TTO_Err_Invalid_GPOS_SubTable; pvr = ppf1->PairSet[index].PairValueRecord;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -