📄 pfrgload.c
字号:
args_count = 4; args_format = format & 15; } /***********************************************************/ /* now read arguments */ /* */ cur = pos; for ( n = 0; n < args_count; n++ ) { FT_Int idx, delta; /* read the X argument */ switch ( args_format & 3 ) { case 0: /* 8-bit index */ PFR_CHECK( 1 ); idx = PFR_NEXT_BYTE( p ); cur->x = glyph->x_control[idx]; FT_TRACE7(( " cx#%d", idx )); break; case 1: /* 16-bit value */ PFR_CHECK( 2 ); cur->x = PFR_NEXT_SHORT( p ); FT_TRACE7(( " x.%d", cur->x )); break; case 2: /* 8-bit delta */ PFR_CHECK( 1 ); delta = PFR_NEXT_INT8( p ); cur->x = pos[3].x + delta; FT_TRACE7(( " dx.%d", delta )); break; default: FT_TRACE7(( " |" )); cur->x = pos[3].x; } /* read the Y argument */ switch ( ( args_format >> 2 ) & 3 ) { case 0: /* 8-bit index */ PFR_CHECK( 1 ); idx = PFR_NEXT_BYTE( p ); cur->y = glyph->y_control[idx]; FT_TRACE7(( " cy#%d", idx )); break; case 1: /* 16-bit absolute value */ PFR_CHECK( 2 ); cur->y = PFR_NEXT_SHORT( p ); FT_TRACE7(( " y.%d", cur->y )); break; case 2: /* 8-bit delta */ PFR_CHECK( 1 ); delta = PFR_NEXT_INT8( p ); cur->y = pos[3].y + delta; FT_TRACE7(( " dy.%d", delta )); break; default: FT_TRACE7(( " -" )); cur->y = pos[3].y; } /* read the additional format flag for the general curve */ if ( n == 0 && args_count == 4 ) { PFR_CHECK( 1 ); args_format = PFR_NEXT_BYTE( p ); args_count--; } else args_format >>= 4; /* save the previous point */ pos[3] = cur[0]; cur++; } FT_TRACE7(( "\n" )); /***********************************************************/ /* finally, execute instruction */ /* */ switch ( format >> 4 ) { case 0: /* end glyph => EXIT */ pfr_glyph_end( glyph ); goto Exit; case 1: /* line operations */ case 2: case 3: error = pfr_glyph_line_to( glyph, pos ); goto Test_Error; case 4: /* move to inside contour */ case 5: /* move to outside contour */ error = pfr_glyph_move_to( glyph, pos ); goto Test_Error; default: /* curve operations */ error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); Test_Error: /* test error condition */ if ( error ) goto Exit; } } /* for (;;) */ } Exit: return error; Too_Short: error = PFR_Err_Invalid_Table; FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); goto Exit; } /* load a composite/compound glyph */ static FT_Error pfr_glyph_load_compound( PFR_Glyph glyph, FT_Byte* p, FT_Byte* limit ) { FT_Error error = 0; FT_GlyphLoader loader = glyph->loader; FT_Memory memory = loader->memory; PFR_SubGlyph subglyph; FT_UInt flags, i, count, org_count; FT_Int x_pos, y_pos; PFR_CHECK( 1 ); flags = PFR_NEXT_BYTE( p ); /* test for composite glyphs */ FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) != 0 ); count = flags & 0x3F; /* ignore extra items when present */ /* */ if ( flags & PFR_GLYPH_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); if (error) goto Exit; } /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ /* the PFR format is dumb, using direct file offsets to point to the */ /* sub-glyphs (instead of glyph indices). Sigh. */ /* */ /* For now, we load the list of sub-glyphs into a different array */ /* but this will prevent us from using the auto-hinter at its best */ /* quality. */ /* */ org_count = glyph->num_subs; if ( org_count + count > glyph->max_subs ) { FT_UInt new_max = ( org_count + count + 3 ) & -4; if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) goto Exit; glyph->max_subs = new_max; } subglyph = glyph->subs + org_count; for ( i = 0; i < count; i++, subglyph++ ) { FT_UInt format; x_pos = 0; y_pos = 0; PFR_CHECK( 1 ); format = PFR_NEXT_BYTE( p ); /* read scale when available */ subglyph->x_scale = 0x10000L; if ( format & PFR_SUBGLYPH_XSCALE ) { PFR_CHECK( 2 ); subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; } subglyph->y_scale = 0x10000L; if ( format & PFR_SUBGLYPH_YSCALE ) { PFR_CHECK( 2 ); subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; } /* read offset */ switch ( format & 3 ) { case 1: PFR_CHECK( 2 ); x_pos = PFR_NEXT_SHORT( p ); break; case 2: PFR_CHECK( 1 ); x_pos += PFR_NEXT_INT8( p ); break; default: ; } switch ( ( format >> 2 ) & 3 ) { case 1: PFR_CHECK( 2 ); y_pos = PFR_NEXT_SHORT( p ); break; case 2: PFR_CHECK( 1 ); y_pos += PFR_NEXT_INT8( p ); break; default: ; } subglyph->x_delta = x_pos; subglyph->y_delta = y_pos; /* read glyph position and size now */ if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) { PFR_CHECK( 2 ); subglyph->gps_size = PFR_NEXT_USHORT( p ); } else { PFR_CHECK( 1 ); subglyph->gps_size = PFR_NEXT_BYTE( p ); } if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) { PFR_CHECK( 3 ); subglyph->gps_offset = PFR_NEXT_LONG( p ); } else { PFR_CHECK( 2 ); subglyph->gps_offset = PFR_NEXT_USHORT( p ); } glyph->num_subs++; } Exit: return error; Too_Short: error = PFR_Err_Invalid_Table; FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); goto Exit; } static FT_Error pfr_glyph_load_rec( PFR_Glyph glyph, FT_Stream stream, FT_ULong gps_offset, FT_ULong offset, FT_ULong size ) { FT_Error error; FT_Byte* p; FT_Byte* limit; if ( FT_STREAM_SEEK( gps_offset + offset ) || FT_FRAME_ENTER( size ) ) goto Exit; p = (FT_Byte*)stream->cursor; limit = p + size; if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) { FT_Int n, old_count, count; FT_GlyphLoader loader = glyph->loader; FT_Outline* base = &loader->base.outline; old_count = glyph->num_subs; /* this is a compound glyph - load it */ error = pfr_glyph_load_compound( glyph, p, limit ); FT_FRAME_EXIT(); if ( error ) goto Exit; count = glyph->num_subs - old_count; /* now, load each individual glyph */ for ( n = 0; n < count; n++ ) { FT_Int i, old_points, num_points; PFR_SubGlyph subglyph; subglyph = glyph->subs + old_count + n; old_points = base->n_points; error = pfr_glyph_load_rec( glyph, stream, gps_offset, subglyph->gps_offset, subglyph->gps_size ); if ( error ) goto Exit; /* note that `glyph->subs' might have been re-allocated */ subglyph = glyph->subs + old_count + n; num_points = base->n_points - old_points; /* translate and eventually scale the new glyph points */ if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) { FT_Vector* vec = base->points + old_points; for ( i = 0; i < num_points; i++, vec++ ) { vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + subglyph->x_delta; vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + subglyph->y_delta; } } else { FT_Vector* vec = loader->base.outline.points + old_points; for ( i = 0; i < num_points; i++, vec++ ) { vec->x += subglyph->x_delta; vec->y += subglyph->y_delta; } } /* proceed to next sub-glyph */ } } else { /* load a simple glyph */ error = pfr_glyph_load_simple( glyph, p, limit ); FT_FRAME_EXIT(); } Exit: return error; } FT_LOCAL_DEF( FT_Error ) pfr_glyph_load( PFR_Glyph glyph, FT_Stream stream, FT_ULong gps_offset, FT_ULong offset, FT_ULong size ) { /* initialize glyph loader */ FT_GlyphLoader_Rewind( glyph->loader ); glyph->num_subs = 0; /* load the glyph, recursively when needed */ return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -