📄 harfbuzz-gpos.c
字号:
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 ) ) != HB_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 ) ) != HB_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 ERR(HB_Err_Invalid_SubTable_Format); } return HB_Err_Ok;Fail: _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable ); return error;}static void Free_Anchor( HB_Anchor* an ){ if ( an->PosFormat == 3 ) { _HB_OPEN_Free_Device( &an->af.af3.YDeviceTable ); _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable ); }}static HB_Error Get_Anchor( GPOS_Instance* gpi, HB_Anchor* an, HB_UShort glyph_index, HB_Fixed* x_value, HB_Fixed* y_value ){ HB_Error error = HB_Err_Ok; FT_Outline outline; HB_GPOSHeader* gpos = gpi->gpos; HB_UShort ap; HB_Short pixel_value; HB_UShort load_flags; HB_UShort x_ppem, y_ppem; HB_16Dot16 x_scale, y_scale; x_ppem = gpi->font->size->metrics.x_ppem; y_ppem = gpi->font->size->metrics.y_ppem; x_scale = gpi->font->size->metrics.x_scale; y_scale = gpi->font->size->metrics.y_scale; switch ( an->PosFormat ) { case 0: /* The special case of an empty AnchorTable */ default: 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->font, glyph_index, load_flags ); if ( error ) return error; if ( gpi->font->glyph->format != ft_glyph_format_outline ) return ERR(HB_Err_Invalid_SubTable); ap = an->af.af2.AnchorPoint; outline = gpi->font->glyph->outline; /* if n_points is set to zero, 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 ERR(HB_Err_Invalid_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->font, an->af.af4.XIdAnchor, x_value, gpos->data ); if ( error ) return error; error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor, y_value, gpos->data ); if ( error ) return error; break; } return error;}/* MarkArray */static HB_Error Load_MarkArray ( HB_MarkArray* ma, HB_Stream stream ){ HB_Error error; HB_UShort n, m, count; HB_UInt 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 ) ) != HB_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return HB_Err_Ok;Fail: for ( m = 0; m < n; m++ ) Free_Anchor( &mr[m].MarkAnchor ); FREE( mr ); return error;}static void Free_MarkArray( HB_MarkArray* ma ){ HB_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 ); FREE( mr ); }}/* LookupType 1 *//* SinglePosFormat1 *//* SinglePosFormat2 */static HB_Error Load_SinglePos( HB_GPOS_SubTable* st, HB_Stream stream ){ HB_Error error; HB_SinglePos* sp = &st->single; HB_UShort n, m, count, format; HB_UInt 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 ERR(HB_Err_Invalid_SubTable); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = _HB_OPEN_Load_Coverage( &sp->Coverage, stream ) ) != HB_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 ERR(HB_Err_Invalid_SubTable_Format); } return HB_Err_Ok;Fail1: for ( m = 0; m < n; m++ ) Free_ValueRecord( &vr[m], format ); FREE( vr );Fail2: _HB_OPEN_Free_Coverage( &sp->Coverage ); return error;}static void Free_SinglePos( HB_GPOS_SubTable* st ){ HB_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 ); 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; default: break; } _HB_OPEN_Free_Coverage( &sp->Coverage );}static HB_Error Lookup_SinglePos( GPOS_Instance* gpi, HB_GPOS_SubTable* st, HB_Buffer buffer, HB_UShort flags, HB_UShort context_length, int nesting_level ){ HB_UShort index, property; HB_Error error; HB_GPOSHeader* gpos = gpi->gpos; HB_SinglePos* sp = &st->single; HB_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 ERR(HB_Err_Invalid_SubTable); error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index], sp->ValueFormat, POSITION( buffer->in_pos ) ); if ( error ) return error; break; default: return ERR(HB_Err_Invalid_SubTable); } (buffer->in_pos)++; return HB_Err_Ok;}/* LookupType 2 *//* PairSet */static HB_Error Load_PairSet ( HB_PairSet* ps, HB_UShort format1, HB_UShort format2, HB_Stream stream ){ HB_Error error; HB_UShort n, m, count; HB_UInt 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 ); goto Fail; } } } return HB_Err_Ok;Fail: for ( m = 0; m < n; m++ ) { if ( format1 ) Free_ValueRecord( &pvr[m].Value1, format1 ); if ( format2 ) Free_ValueRecord( &pvr[m].Value2, format2 ); } FREE( pvr ); return error;}static void Free_PairSet( HB_PairSet* ps, HB_UShort format1, HB_UShort format2 ){ HB_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 ); if ( format2 ) Free_ValueRecord( &pvr[n].Value2, format2 ); } FREE( pvr ); }}/* PairPosFormat1 */static HB_Error Load_PairPos1( HB_PairPosFormat1* ppf1, HB_UShort format1, HB_UShort format2, HB_Stream stream ){ HB_Error error; HB_UShort n, m, count; HB_UInt cur_offset, new_offset, base_offset; HB_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, HB_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 ) ) != HB_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return HB_Err_Ok;Fail: for ( m = 0; m < n; m++ ) Free_PairSet( &ps[m], format1, format2 ); FREE( ps ); return error;}static void Free_PairPos1( HB_PairPosFormat1* ppf1, HB_UShort format1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -