📄 ttgload.c
字号:
} /* reading the Y coordinates */ vec = gloader->current.outline.points; vec_limit = vec + n_points; flag = (FT_Byte*)outline->tags; x = 0; for ( ; vec < vec_limit; vec++, flag++ ) { FT_Pos y = 0; if ( *flag & 4 ) { if ( p +1 > limit ) goto Invalid_Outline; y = (FT_Pos)FT_NEXT_BYTE( p ); if ( ( *flag & 32 ) == 0 ) y = -y; } else if ( ( *flag & 32 ) == 0 ) { if ( p + 2 > limit ) goto Invalid_Outline; y = (FT_Pos)FT_NEXT_SHORT( p ); } x += y; vec->y = x; } /* clear the touch tags */ for ( n = 0; n < n_points; n++ ) outline->tags[n] &= FT_CURVE_TAG_ON; outline->n_points = (FT_UShort)n_points; outline->n_contours = (FT_Short) n_contours; load->cursor = p; Fail: return error; Invalid_Outline: error = TT_Err_Invalid_Outline; goto Fail; } FT_CALLBACK_DEF( FT_Error ) TT_Load_Composite_Glyph( TT_Loader loader ) { FT_Error error; FT_Byte* p = loader->cursor; FT_Byte* limit = loader->limit; FT_GlyphLoader gloader = loader->gloader; FT_SubGlyph subglyph; FT_UInt num_subglyphs; num_subglyphs = 0; do { FT_Fixed xx, xy, yy, yx; FT_UInt count; /* check that we can load a new subglyph */ error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 ); if ( error ) goto Fail; /* check space */ if ( p + 4 > limit ) goto Invalid_Composite; subglyph = gloader->current.subglyphs + num_subglyphs; subglyph->arg1 = subglyph->arg2 = 0; subglyph->flags = FT_NEXT_USHORT( p ); subglyph->index = FT_NEXT_USHORT( p ); /* check space */ count = 2; if ( subglyph->flags & ARGS_ARE_WORDS ) count += 2; if ( subglyph->flags & WE_HAVE_A_SCALE ) count += 2; else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) count += 4; else if ( subglyph->flags & WE_HAVE_A_2X2 ) count += 8; if ( p + count > limit ) goto Invalid_Composite; /* read arguments */ if ( subglyph->flags & ARGS_ARE_WORDS ) { subglyph->arg1 = FT_NEXT_SHORT( p ); subglyph->arg2 = FT_NEXT_SHORT( p ); } else { subglyph->arg1 = FT_NEXT_CHAR( p ); subglyph->arg2 = FT_NEXT_CHAR( p ); } /* read transform */ xx = yy = 0x10000L; xy = yx = 0; if ( subglyph->flags & WE_HAVE_A_SCALE ) { xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; yy = xx; } else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) { xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; } else if ( subglyph->flags & WE_HAVE_A_2X2 ) { xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; } subglyph->transform.xx = xx; subglyph->transform.xy = xy; subglyph->transform.yx = yx; subglyph->transform.yy = yy; num_subglyphs++; } while ( subglyph->flags & MORE_COMPONENTS ); gloader->current.num_subglyphs = num_subglyphs;#ifdef TT_USE_BYTECODE_INTERPRETER { FT_Stream stream = loader->stream; /* we must undo the FT_FRAME_ENTER in order to point to the */ /* composite instructions, if we find some. */ /* we will process them later... */ /* */ loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + p - limit ); }#endif loader->cursor = p; Fail: return error; Invalid_Composite: error = TT_Err_Invalid_Composite; goto Fail; } FT_LOCAL_DEF( void ) TT_Init_Glyph_Loading( TT_Face face ) { face->access_glyph_frame = TT_Access_Glyph_Frame; face->read_glyph_header = TT_Load_Glyph_Header; face->read_simple_glyph = TT_Load_Simple_Glyph; face->read_composite_glyph = TT_Load_Composite_Glyph; face->forget_glyph_frame = TT_Forget_Glyph_Frame; } static void tt_prepare_zone( TT_GlyphZone zone, FT_GlyphLoad load, FT_UInt start_point, FT_UInt start_contour ) { zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour ); zone->org = load->extra_points + start_point; zone->cur = load->outline.points + start_point; zone->orus = load->extra_points2 + start_point; zone->tags = (FT_Byte*)load->outline.tags + start_point; zone->contours = (FT_UShort*)load->outline.contours + start_contour; zone->first_point = (FT_UShort)start_point; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Hint_Glyph */ /* */ /* <Description> */ /* Hint the glyph using the zone prepared by the caller. Note that */ /* the zone is supposed to include four phantom points. */ /* */ static FT_Error TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) { TT_GlyphZone zone = &loader->zone; FT_Pos origin;#ifdef TT_USE_BYTECODE_INTERPRETER FT_UInt n_ins;#else FT_UNUSED( is_composite );#endif#ifdef TT_USE_BYTECODE_INTERPRETER n_ins = loader->glyph->control_len;#endif origin = zone->cur[zone->n_points - 4].x; origin = FT_PIX_ROUND( origin ) - origin; if ( origin ) translate_array( zone->n_points, zone->cur, origin, 0 );#ifdef TT_USE_BYTECODE_INTERPRETER /* save original point position in org */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );#endif /* round pp2 and pp4 */ zone->cur[zone->n_points - 3].x = FT_PIX_ROUND( zone->cur[zone->n_points - 3].x ); zone->cur[zone->n_points - 1].y = FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );#ifdef TT_USE_BYTECODE_INTERPRETER if ( n_ins > 0 ) { FT_Bool debug; FT_Error error; error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, loader->exec->glyphIns, n_ins ); if ( error ) return error; loader->exec->is_composite = is_composite; loader->exec->pts = *zone; debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && ((TT_Size)loader->size)->debug ); error = TT_Run_Context( loader->exec, debug ); if ( error && loader->exec->pedantic_hinting ) return error; }#endif /* save glyph phantom points */ if ( !loader->preserve_pps ) { loader->pp1 = zone->cur[zone->n_points - 4]; loader->pp2 = zone->cur[zone->n_points - 3]; loader->pp3 = zone->cur[zone->n_points - 2]; loader->pp4 = zone->cur[zone->n_points - 1]; } return TT_Err_Ok; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Process_Simple_Glyph */ /* */ /* <Description> */ /* Once a simple glyph has been loaded, it needs to be processed. */ /* Usually, this means scaling and hinting through bytecode */ /* interpretation. */ /* */ static FT_Error TT_Process_Simple_Glyph( TT_Loader loader ) { FT_GlyphLoader gloader = loader->gloader; FT_Error error = TT_Err_Ok; FT_Outline* outline; FT_Int n_points; outline = &gloader->current.outline; n_points = outline->n_points; /* set phantom points */ outline->points[n_points ] = loader->pp1; outline->points[n_points + 1] = loader->pp2; outline->points[n_points + 2] = loader->pp3; outline->points[n_points + 3] = loader->pp4; outline->tags[n_points ] = 0; outline->tags[n_points + 1] = 0; outline->tags[n_points + 2] = 0; outline->tags[n_points + 3] = 0; n_points += 4;#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT if ( ((TT_Face)loader->face)->doblend ) { /* Deltas apply to the unscaled data. */ FT_Vector* deltas; FT_Memory memory = loader->face->memory; FT_Int i; error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), loader->glyph_index, &deltas, n_points ); if ( error ) return error; for ( i = 0; i < n_points; ++i ) { outline->points[i].x += deltas[i].x; outline->points[i].y += deltas[i].y; } FT_FREE( deltas ); }#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ if ( IS_HINTED( loader->load_flags ) ) { tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, loader->zone.n_points + 4 ); } /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { FT_Vector* vec = outline->points; FT_Vector* limit = outline->points + n_points; FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; for ( ; vec < limit; vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } loader->pp1 = outline->points[n_points - 4]; loader->pp2 = outline->points[n_points - 3]; loader->pp3 = outline->points[n_points - 2]; loader->pp4 = outline->points[n_points - 1]; } if ( IS_HINTED( loader->load_flags ) ) { loader->zone.n_points += 4; error = TT_Hint_Glyph( loader, 0 ); } return error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -