📄 ftxgpos.c
字号:
error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index], sp->ValueFormat, POSITION( buffer->in_pos ) ); if ( error ) return error; break; default: return TTO_Err_Invalid_GPOS_SubTable; } (buffer->in_pos)++; return TT_Err_Ok; } /* LookupType 2 */ /* PairSet */ static FT_Error Load_PairSet ( TTO_PairSet* ps, FT_UShort format1, FT_UShort format2, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_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, stream ); if ( error ) goto Fail; } if ( format2 ) { error = Load_ValueRecord( &pvr[n].Value2, format2, base_offset, stream ); if ( error ) { if ( format1 ) Free_ValueRecord( &pvr[n].Value1, format1, memory ); goto Fail; } } } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) { if ( format1 ) Free_ValueRecord( &pvr[m].Value1, format1, memory ); if ( format2 ) Free_ValueRecord( &pvr[m].Value2, format2, memory ); } FREE( pvr ); return error; } static void Free_PairSet( TTO_PairSet* ps, FT_UShort format1, FT_UShort format2, FT_Memory memory ) { FT_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, memory ); if ( format2 ) Free_ValueRecord( &pvr[n].Value2, format2, memory ); } FREE( pvr ); } } /* PairPosFormat1 */ static FT_Error Load_PairPos1( TTO_PairPosFormat1* ppf1, FT_UShort format1, FT_UShort format2, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_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 ) ) return error; 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, stream ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Free_PairSet( &ps[m], format1, format2, memory ); FREE( ps ); return error; } static void Free_PairPos1( TTO_PairPosFormat1* ppf1, FT_UShort format1, FT_UShort format2, FT_Memory memory ) { FT_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, memory ); FREE( ps ); } } /* PairPosFormat2 */ static FT_Error Load_PairPos2( TTO_PairPosFormat2* ppf2, FT_UShort format1, FT_UShort format2, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort m, n, k, count1, count2; FT_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, stream ) ) != TT_Err_Ok ) return error; if ( FILE_Seek( new_offset2 ) || ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2, stream ) ) != TT_Err_Ok ) goto Fail3; (void)FILE_Seek( cur_offset ); ppf2->Class1Record = NULL; if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) ) goto Fail2; 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, stream ); if ( error ) goto Fail0; } if ( format2 ) { error = Load_ValueRecord( &c2r[n].Value2, format2, base_offset, stream ); if ( error ) { if ( format1 ) Free_ValueRecord( &c2r[n].Value1, format1, memory ); goto Fail0; } } } continue; Fail0: for ( k = 0; k < n; k++ ) { if ( format1 ) Free_ValueRecord( &c2r[k].Value1, format1, memory ); if ( format2 ) Free_ValueRecord( &c2r[k].Value2, format2, memory ); } goto Fail1; } return TT_Err_Ok; Fail1: for ( k = 0; k < m; k++ ) { c2r = c1r[k].Class2Record; for ( n = 0; n < count2; n++ ) { if ( format1 ) Free_ValueRecord( &c2r[n].Value1, format1, memory ); if ( format2 ) Free_ValueRecord( &c2r[n].Value2, format2, memory ); } FREE( c2r ); } FREE( c1r ); Fail2: Free_ClassDefinition( &ppf2->ClassDef2, memory ); Fail3: Free_ClassDefinition( &ppf2->ClassDef1, memory ); return error; } static void Free_PairPos2( TTO_PairPosFormat2* ppf2, FT_UShort format1, FT_UShort format2, FT_Memory memory ) { FT_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, memory ); if ( format2 ) Free_ValueRecord( &c2r[n].Value2, format2, memory ); } FREE( c2r ); } FREE( c1r ); Free_ClassDefinition( &ppf2->ClassDef2, memory ); Free_ClassDefinition( &ppf2->ClassDef1, memory ); } } FT_Error Load_PairPos( TTO_PairPos* pp, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort format1, format2; FT_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, stream ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); switch ( pp->PosFormat ) { case 1: error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream ); if ( error ) goto Fail; break; case 2: error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream ); if ( error ) goto Fail; break; default: return TTO_Err_Invalid_GPOS_SubTable_Format; } return TT_Err_Ok; Fail: Free_Coverage( &pp->Coverage, memory ); return error; } void Free_PairPos( TTO_PairPos* pp, FT_Memory memory ) { FT_UShort format1, format2; format1 = pp->ValueFormat1; format2 = pp->ValueFormat2; switch ( pp->PosFormat ) { case 1: Free_PairPos1( &pp->ppf.ppf1, format1, format2, memory ); break; case 2: Free_PairPos2( &pp->ppf.ppf2, format1, format2, memory ); break; } Free_Coverage( &pp->Coverage, memory ); } static FT_Error Lookup_PairPos1( GPOS_Instance* gpi, TTO_PairPosFormat1* ppf1, OTL_Buffer buffer, FT_UShort first_pos, FT_UShort index, FT_UShort format1, FT_UShort format2 ) { FT_Error error; FT_UShort numpvr, glyph2; TTO_PairValueRecord* pvr; if ( index >= ppf1->PairSetCount ) return TTO_Err_Invalid_GPOS_SubTable; pvr = ppf1->PairSet[index].PairValueRecord; if ( !pvr ) return TTO_Err_Invalid_GPOS_SubTable; glyph2 = IN_CURGLYPH(); for ( numpvr = ppf1->PairSet[index].PairValueCount; numpvr; numpvr--, pvr++ ) { if ( glyph2 == pvr->SecondGlyph ) { error = Get_ValueRecord( gpi, &pvr->Value1, format1, POSITION( first_pos ) ); if ( error ) return error; return Get_ValueRecord( gpi, &pvr->Value2, format2, POSITION( buffer->in_pos ) ); } } return TTO_Err_Not_Covered; } static FT_Error Lookup_PairPos2( GPOS_Instance* gpi, TTO_PairPosFormat2* ppf2, OTL_Buffer buffer, FT_UShort first_pos, FT_UShort format1, FT_UShort format2 ) { FT_Error error; FT_UShort cl1, cl2; TTO_Class1Record* c1r; TTO_Class2Record* c2r; error = Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ), &cl1, NULL ); if ( error && error != TTO_Err_Not_Covered ) return error; error = Get_Class( &ppf2->ClassDef2, IN_CURGLYPH(), &cl2, NULL ); if ( error && error != TTO_Err_Not_Covered ) return error; c1r = &ppf2->Class1Record[cl1]; if ( !c1r ) return TTO_Err_Invalid_GPOS_SubTable; c2r = &c1r->Class2Record[cl2]; error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) ); if ( error ) return error; return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) ); } static FT_Error Lookup_PairPos( GPOS_Instance* gpi, TTO_PairPos* pp, OTL_Buffer buffer, FT_UShort flags, FT_UShort context_length ) { FT_Error error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -