📄 harfbuzz-gpos.c
字号:
an->af.af1.YCoordinate = GET_Short(); FORGET_Frame(); break; case 2: if ( ACCESS_Frame( 6L ) ) return error; an->af.af2.XCoordinate = GET_Short(); an->af.af2.YCoordinate = GET_Short(); an->af.af2.AnchorPoint = GET_UShort(); FORGET_Frame(); break; case 3: if ( ACCESS_Frame( 6L ) ) return error; an->af.af3.XCoordinate = GET_Short(); an->af.af3.YCoordinate = GET_Short(); new_offset = GET_UShort(); FORGET_Frame(); if ( new_offset ) { new_offset += base_offset; cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = _HB_OPEN_Load_Device( &an->af.af3.XDeviceTable, stream ) ) != FT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); } else { an->af.af3.XDeviceTable.StartSize = 0; an->af.af3.XDeviceTable.EndSize = 0; an->af.af3.XDeviceTable.DeltaValue = NULL; } if ( ACCESS_Frame( 2L ) ) goto Fail; new_offset = GET_UShort(); FORGET_Frame(); if ( new_offset ) { new_offset += base_offset; cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = _HB_OPEN_Load_Device( &an->af.af3.YDeviceTable, stream ) ) != FT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } else { an->af.af3.YDeviceTable.StartSize = 0; an->af.af3.YDeviceTable.EndSize = 0; an->af.af3.YDeviceTable.DeltaValue = NULL; } break; case 4: if ( ACCESS_Frame( 4L ) ) return error; an->af.af4.XIdAnchor = GET_UShort(); an->af.af4.YIdAnchor = GET_UShort(); FORGET_Frame(); break; default: return HB_Err_Invalid_GPOS_SubTable_Format; } return FT_Err_Ok;Fail: _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable, memory ); return error;}static void Free_Anchor( HB_Anchor* an, FT_Memory memory){ if ( an->PosFormat == 3 ) { _HB_OPEN_Free_Device( &an->af.af3.YDeviceTable, memory ); _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable, memory ); }}static FT_Error Get_Anchor( GPOS_Instance* gpi, HB_Anchor* an, FT_UShort glyph_index, FT_Pos* x_value, FT_Pos* y_value ){ FT_Error error = FT_Err_Ok; FT_Outline outline; HB_GPOSHeader* gpos = gpi->gpos; FT_UShort ap; FT_Short pixel_value; FT_UShort load_flags; FT_UShort x_ppem, y_ppem; FT_Fixed x_scale, y_scale; x_ppem = gpi->face->size->metrics.x_ppem; y_ppem = gpi->face->size->metrics.y_ppem; x_scale = gpi->face->size->metrics.x_scale; y_scale = gpi->face->size->metrics.y_scale; switch ( an->PosFormat ) { case 0: /* The special case of an empty AnchorTable */ return HB_Err_Not_Covered; case 1: *x_value = x_scale * an->af.af1.XCoordinate / 0x10000; *y_value = y_scale * an->af.af1.YCoordinate / 0x10000; break; case 2: /* glyphs must be scaled */ load_flags = gpi->load_flags & ~FT_LOAD_NO_SCALE; if ( !gpi->dvi ) { error = (gpos->gfunc)( gpi->face, glyph_index, load_flags ); if ( error ) return error; if ( gpi->face->glyph->format != ft_glyph_format_outline ) return HB_Err_Invalid_GPOS_SubTable; ap = an->af.af2.AnchorPoint; outline = gpi->face->glyph->outline; /* if outline.n_points is set to zero by gfunc(), we use the design coordinate value pair. This can happen e.g. for sbit glyphs */ if ( !outline.n_points ) goto no_contour_point; if ( ap >= outline.n_points ) return HB_Err_Invalid_GPOS_SubTable; *x_value = outline.points[ap].x; *y_value = outline.points[ap].y; } else { no_contour_point: *x_value = x_scale * an->af.af3.XCoordinate / 0x10000; *y_value = y_scale * an->af.af3.YCoordinate / 0x10000; } break; case 3: if ( !gpi->dvi ) { _HB_OPEN_Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value ); *x_value = pixel_value << 6; _HB_OPEN_Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value ); *y_value = pixel_value << 6; } else *x_value = *y_value = 0; *x_value += x_scale * an->af.af3.XCoordinate / 0x10000; *y_value += y_scale * an->af.af3.YCoordinate / 0x10000; break; case 4: error = (gpos->mmfunc)( gpi->face, an->af.af4.XIdAnchor, x_value, gpos->data ); if ( error ) return error; error = (gpos->mmfunc)( gpi->face, an->af.af4.YIdAnchor, y_value, gpos->data ); if ( error ) return error; break; } return error;}/* MarkArray */static FT_Error Load_MarkArray ( HB_MarkArray* ma, FT_Stream stream ){ FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_ULong cur_offset, new_offset, base_offset; HB_MarkRecord* mr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = ma->MarkCount = GET_UShort(); FORGET_Frame(); ma->MarkRecord = NULL; if ( ALLOC_ARRAY( ma->MarkRecord, count, HB_MarkRecord ) ) return error; mr = ma->MarkRecord; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 4L ) ) goto Fail; mr[n].Class = GET_UShort(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != FT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return FT_Err_Ok;Fail: for ( m = 0; m < n; m++ ) Free_Anchor( &mr[m].MarkAnchor, memory ); FREE( mr ); return error;}static void Free_MarkArray( HB_MarkArray* ma, FT_Memory memory ){ FT_UShort n, count; HB_MarkRecord* mr; if ( ma->MarkRecord ) { count = ma->MarkCount; mr = ma->MarkRecord; for ( n = 0; n < count; n++ ) Free_Anchor( &mr[n].MarkAnchor, memory ); FREE( mr ); }}/* LookupType 1 *//* SinglePosFormat1 *//* SinglePosFormat2 */static FT_Error Load_SinglePos( HB_GPOS_SubTable* st, FT_Stream stream ){ FT_Error error; FT_Memory memory = stream->memory; HB_SinglePos* sp = &st->single; FT_UShort n, m, count, format; FT_ULong cur_offset, new_offset, base_offset; HB_ValueRecord* vr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 6L ) ) return error; sp->PosFormat = GET_UShort(); new_offset = GET_UShort() + base_offset; format = sp->ValueFormat = GET_UShort(); FORGET_Frame(); if ( !format ) return HB_Err_Invalid_GPOS_SubTable; cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = _HB_OPEN_Load_Coverage( &sp->Coverage, stream ) ) != FT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); switch ( sp->PosFormat ) { case 1: error = Load_ValueRecord( &sp->spf.spf1.Value, format, base_offset, stream ); if ( error ) goto Fail2; break; case 2: if ( ACCESS_Frame( 2L ) ) goto Fail2; count = sp->spf.spf2.ValueCount = GET_UShort(); FORGET_Frame(); sp->spf.spf2.Value = NULL; if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, HB_ValueRecord ) ) goto Fail2; vr = sp->spf.spf2.Value; for ( n = 0; n < count; n++ ) { error = Load_ValueRecord( &vr[n], format, base_offset, stream ); if ( error ) goto Fail1; } break; default: return HB_Err_Invalid_GPOS_SubTable_Format; } return FT_Err_Ok;Fail1: for ( m = 0; m < n; m++ ) Free_ValueRecord( &vr[m], format, memory ); FREE( vr );Fail2: _HB_OPEN_Free_Coverage( &sp->Coverage, memory ); return error;}static void Free_SinglePos( HB_GPOS_SubTable* st, FT_Memory memory ){ FT_UShort n, count, format; HB_SinglePos* sp = &st->single; HB_ValueRecord* v; format = sp->ValueFormat; switch ( sp->PosFormat ) { case 1: Free_ValueRecord( &sp->spf.spf1.Value, format, memory ); 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, memory ); FREE( v ); } break; } _HB_OPEN_Free_Coverage( &sp->Coverage, memory );}static FT_Error Lookup_DefaultPos( GPOS_Instance* gpi, HB_GPOS_SubTable* st, HB_Buffer buffer, FT_UShort flags, FT_UShort context_length, int nesting_level ){ FT_UNUSED(gpi); FT_UNUSED(st); FT_UNUSED(buffer); FT_UNUSED(flags); FT_UNUSED(context_length); FT_UNUSED(nesting_level); return HB_Err_Not_Covered;}static FT_Error Lookup_SinglePos( GPOS_Instance* gpi, HB_GPOS_SubTable* st, HB_Buffer buffer, FT_UShort flags, FT_UShort context_length, int nesting_level ){ FT_UShort index, property; FT_Error error; HB_GPOSHeader* gpos = gpi->gpos; HB_SinglePos* sp = &st->single; FT_UNUSED(nesting_level); if ( context_length != 0xFFFF && context_length < 1 ) return HB_Err_Not_Covered; if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) return error; error = _HB_OPEN_Coverage_Index( &sp->Coverage, IN_CURGLYPH(), &index ); if ( error ) return error; switch ( sp->PosFormat ) { case 1: error = Get_ValueRecord( gpi, &sp->spf.spf1.Value, sp->ValueFormat, POSITION( buffer->in_pos ) ); if ( error ) return error; break; case 2: if ( index >= sp->spf.spf2.ValueCount ) return HB_Err_Invalid_GPOS_SubTable; error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index], sp->ValueFormat, POSITION( buffer->in_pos ) ); if ( error ) return error; break; default: return HB_Err_Invalid_GPOS_SubTable; } (buffer->in_pos)++; return FT_Err_Ok;}/* LookupType 2 *//* PairSet */static FT_Error Load_PairSet ( HB_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; HB_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, HB_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 FT_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( HB_PairSet* ps, FT_UShort format1, FT_UShort format2, FT_Memory memory ){ FT_UShort n, count; HB_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( HB_PairPosFormat1* ppf1, FT_UShort format1, FT_UShort format2, FT_Stream stream ){ FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -