📄 ftxgpos.c
字号:
/* MarkBasePosFormat1 */ FT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_ULong cur_offset, new_offset, base_offset; base_offset = FILE_Pos(); if ( ACCESS_Frame( 4L ) ) return error; mbp->PosFormat = GET_UShort(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &mbp->MarkCoverage, stream ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail3; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &mbp->BaseCoverage, stream ) ) != TT_Err_Ok ) goto Fail3; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 4L ) ) goto Fail2; mbp->ClassCount = GET_UShort(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != TT_Err_Ok ) goto Fail2; (void)FILE_Seek( cur_offset ); 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_BaseArray( &mbp->BaseArray, mbp->ClassCount, stream ) ) != TT_Err_Ok ) goto Fail1; return TT_Err_Ok; Fail1: Free_MarkArray( &mbp->MarkArray, memory ); Fail2: Free_Coverage( &mbp->BaseCoverage, memory ); Fail3: Free_Coverage( &mbp->MarkCoverage, memory ); return error; } void Free_MarkBasePos( TTO_MarkBasePos* mbp, FT_Memory memory ) { Free_BaseArray( &mbp->BaseArray, mbp->ClassCount, memory ); Free_MarkArray( &mbp->MarkArray, memory ); Free_Coverage( &mbp->BaseCoverage, memory ); Free_Coverage( &mbp->MarkCoverage, memory ); } static FT_Error Lookup_MarkBasePos( GPOS_Instance* gpi, TTO_MarkBasePos* mbp, OTL_Buffer buffer, FT_UShort flags, FT_UShort context_length ) { FT_UShort i, j, mark_index, base_index, property, class; FT_Pos x_mark_value, y_mark_value, x_base_value, y_base_value; FT_Error error; TTO_GPOSHeader* gpos = gpi->gpos; TTO_MarkArray* ma; TTO_BaseArray* ba; TTO_BaseRecord* br; TTO_Anchor* mark_anchor; TTO_Anchor* base_anchor; OTL_Position o; if ( context_length != 0xFFFF && context_length < 1 ) return TTO_Err_Not_Covered; if ( flags & IGNORE_BASE_GLYPHS ) return TTO_Err_Not_Covered; if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) return error; error = Coverage_Index( &mbp->MarkCoverage, IN_CURGLYPH(), &mark_index ); if ( error ) return error; /* now we search backwards for a non-mark glyph */ i = 1; j = buffer->in_pos - 1; while ( i <= buffer->in_pos ) { error = TT_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ), &property ); if ( error ) return error; if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) ) break; i++; j--; } /* The following assertion is too strong -- at least for mangal.ttf. */#if 0 if ( property != TTO_BASE_GLYPH ) return TTO_Err_Not_Covered;#endif if ( i > buffer->in_pos ) return TTO_Err_Not_Covered; error = Coverage_Index( &mbp->BaseCoverage, IN_GLYPH( j ), &base_index ); if ( error ) return error; ma = &mbp->MarkArray; if ( mark_index >= ma->MarkCount ) return TTO_Err_Invalid_GPOS_SubTable; class = ma->MarkRecord[mark_index].Class; mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor; if ( class >= mbp->ClassCount ) return TTO_Err_Invalid_GPOS_SubTable; ba = &mbp->BaseArray; if ( base_index >= ba->BaseCount ) return TTO_Err_Invalid_GPOS_SubTable; br = &ba->BaseRecord[base_index]; base_anchor = &br->BaseAnchor[class]; error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(), &x_mark_value, &y_mark_value ); if ( error ) return error; error = Get_Anchor( gpi, base_anchor, IN_GLYPH( j ), &x_base_value, &y_base_value ); if ( error ) return error; /* anchor points are not cumulative */ o = POSITION( buffer->in_pos ); o->x_pos = x_base_value - x_mark_value; o->y_pos = y_base_value - y_mark_value; o->x_advance = 0; o->y_advance = 0; o->back = i; (buffer->in_pos)++; return TT_Err_Ok; } /* LookupType 5 */ /* LigatureAttach */ static FT_Error Load_LigatureAttach( TTO_LigatureAttach* lat, FT_UShort num_classes, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort m, n, k, count; FT_ULong cur_offset, new_offset, base_offset; TTO_ComponentRecord* cr; TTO_Anchor* lan; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = lat->ComponentCount = GET_UShort(); FORGET_Frame(); lat->ComponentRecord = NULL; if ( ALLOC_ARRAY( lat->ComponentRecord, count, TTO_ComponentRecord ) ) return error; cr = lat->ComponentRecord; for ( m = 0; m < count; m++ ) { cr[m].LigatureAnchor = NULL; if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, TTO_Anchor ) ) goto Fail; lan = cr[m].LigatureAnchor; for ( n = 0; n < num_classes; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail0; new_offset = GET_UShort(); FORGET_Frame(); if ( new_offset ) { new_offset += base_offset; cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Anchor( &lan[n], stream ) ) != TT_Err_Ok ) goto Fail0; (void)FILE_Seek( cur_offset ); } else lan[n].PosFormat = 0; } continue; Fail0: for ( k = 0; k < n; k++ ) Free_Anchor( &lan[k], memory ); goto Fail; } return TT_Err_Ok; Fail: for ( k = 0; k < m; k++ ) { lan = cr[k].LigatureAnchor; for ( n = 0; n < num_classes; n++ ) Free_Anchor( &lan[n], memory ); FREE( lan ); } FREE( cr ); return error; } static void Free_LigatureAttach( TTO_LigatureAttach* lat, FT_UShort num_classes, FT_Memory memory ) { FT_UShort m, n, count; TTO_ComponentRecord* cr; TTO_Anchor* lan; if ( lat->ComponentRecord ) { count = lat->ComponentCount; cr = lat->ComponentRecord; for ( m = 0; m < count; m++ ) { lan = cr[m].LigatureAnchor; for ( n = 0; n < num_classes; n++ ) Free_Anchor( &lan[n], memory ); FREE( lan ); } FREE( cr ); } } /* LigatureArray */ static FT_Error Load_LigatureArray( TTO_LigatureArray* la, FT_UShort num_classes, 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_LigatureAttach* lat; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = la->LigatureCount = GET_UShort(); FORGET_Frame(); la->LigatureAttach = NULL; if ( ALLOC_ARRAY( la->LigatureAttach, count, TTO_LigatureAttach ) ) return error; lat = la->LigatureAttach; 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_LigatureAttach( &lat[n], num_classes, stream ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Free_LigatureAttach( &lat[m], num_classes, memory ); FREE( lat ); return error; } static void Free_LigatureArray( TTO_LigatureArray* la, FT_UShort num_classes, FT_Memory memory ) { FT_UShort n, count; TTO_LigatureAttach* lat; if ( la->LigatureAttach ) { count = la->LigatureCount; lat = la->LigatureAttach; for ( n = 0; n < count; n++ ) Free_LigatureAttach( &lat[n], num_classes, memory ); FREE( lat ); } } /* MarkLigPosFormat1 */ FT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_ULong cur_offset, new_offset, base_offset; base_offset = FILE_Pos(); if ( ACCESS_Frame( 4L ) ) return error; mlp->PosFormat = GET_UShort(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &mlp->MarkCoverage, stream ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 2L ) ) goto Fail3; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Coverage( &mlp->LigatureCoverage, stream ) ) != TT_Err_Ok ) goto Fail3; (void)FILE_Seek( cur_offset ); if ( ACCESS_Frame( 4L ) ) goto Fail2; mlp->ClassCount = GET_UShort(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != TT_Err_Ok ) goto Fail2; (void)FILE_Seek( cur_offset ); 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_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, stream ) ) != TT_Err_Ok ) goto Fail1; return TT_Err_Ok; Fail1: Free_MarkArray( &mlp->MarkArray, memory ); Fail2: Free_Coverage( &mlp->LigatureCoverage, memory ); Fail3: Free_Coverage( &mlp->MarkCoverage, memory ); return error; } void Free_MarkLigPos( TTO_MarkLigPos* mlp, FT_Memory memory) { Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, memory ); Free_MarkArray( &mlp->MarkArray, memory ); Free_Coverage( &mlp->LigatureCoverage, memory ); Free_Coverage( &mlp->MarkCoverage, memory ); } static FT_Error Lookup_MarkLigPos( GPOS_Instance* gpi, TTO_MarkLigPos* mlp, OTL_Buffer buffer, FT_UShort flags, FT_UShort context_length ) { FT_UShort i, j, mark_index, lig_index, property, class; FT_UShort mark_glyph; FT_Pos x_mark_value, y_mark_value, x_lig_value, y_lig_value; FT_Error error; TTO_GPOSHeader* gpos = gpi->gpos; TTO_MarkArray* ma; TTO_LigatureArray* la; TTO_LigatureAttach* lat; TTO_ComponentRecord* cr; FT_UShort comp_index; TTO_Anchor* mark_anchor; TTO_Anchor* lig_anchor; OTL_Position o; if ( context_length != 0xFFFF && context_length < 1 ) return TTO_Err_Not_Covered; if ( flags & IGNORE_LIGATURES ) return TTO_Err_Not_Covered; mark_glyph = IN_CURGLYPH(); if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) return error; error = C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -