ttgload.c
来自「一个类似windows」· C语言 代码 · 共 1,925 行 · 第 1/5 页
C
1,925 行
{
FT_GlyphLoader gloader = load->gloader;
FT_Outline* outline = &gloader->current.outline;
FT_UInt n_points = outline->n_points;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
FT_UInt n_ins;
#endif
TT_GlyphZone zone = &load->zone;
FT_Error error = TT_Err_Ok;
FT_UNUSED( debug ); /* used by truetype interpreter only */
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
n_ins = load->glyph->control_len;
#endif
/* add shadow points */
/* Add two horizontal shadow points at n and n+1. */
/* We need the left side bearing and advance width. */
/* Add two vertical shadow points at n+2 and n+3. */
/* We need the top side bearing and advance height. */
{
FT_Vector* pp1;
FT_Vector* pp2;
FT_Vector* pp3;
FT_Vector* pp4;
/* pp1 = xMin - lsb */
pp1 = outline->points + n_points;
pp1->x = load->bbox.xMin - load->left_bearing;
pp1->y = 0;
/* pp2 = pp1 + aw */
pp2 = pp1 + 1;
pp2->x = pp1->x + load->advance;
pp2->y = 0;
/* pp3 = top side bearing */
pp3 = pp1 + 2;
pp3->x = 0;
pp3->y = load->top_bearing + load->bbox.yMax;
/* pp4 = pp3 - ah */
pp4 = pp1 + 3;
pp4->x = 0;
pp4->y = pp3->y - load->vadvance;
outline->tags[n_points ] = 0;
outline->tags[n_points + 1] = 0;
outline->tags[n_points + 2] = 0;
outline->tags[n_points + 3] = 0;
}
/* Note that we return four more points that are not */
/* part of the glyph outline. */
n_points += 4;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( ((TT_Face)load->face)->doblend )
{
/* Deltas apply to the unscaled data. */
FT_Vector* deltas;
FT_Memory memory = load->face->memory;
FT_StreamRec saved_stream = *(load->stream);
FT_UInt i;
/* TT_Vary_Get_Glyph_Deltas uses a frame, thus we have to save */
/* (and restore) the current one */
load->stream->cursor = 0;
load->stream->limit = 0;
error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(load->face),
load->glyph_index,
&deltas,
n_points );
*(load->stream) = saved_stream;
if ( error )
goto Exit;
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 */
/* set up zone for hinting */
tt_prepare_zone( zone, &gloader->current, 0, 0 );
/* eventually scale the glyph */
if ( !( load->load_flags & FT_LOAD_NO_SCALE ) )
{
FT_Vector* vec = zone->cur;
FT_Vector* limit = vec + n_points;
FT_Fixed x_scale = ((TT_Size)load->size)->metrics.x_scale;
FT_Fixed y_scale = ((TT_Size)load->size)->metrics.y_scale;
/* first scale the glyph points */
for ( ; vec < limit; vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
}
cur_to_org( n_points, zone );
/* eventually hint the glyph */
if ( IS_HINTED( load->load_flags ) )
{
FT_Pos x = zone->org[n_points-4].x;
x = FT_PIX_ROUND( x ) - x;
translate_array( n_points, zone->org, x, 0 );
org_to_cur( n_points, zone );
zone->cur[n_points - 3].x = FT_PIX_ROUND( zone->cur[n_points - 3].x );
zone->cur[n_points - 1].y = FT_PIX_ROUND( zone->cur[n_points - 1].y );
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
/* now consider hinting */
if ( n_ins > 0 )
{
error = TT_Set_CodeRange( load->exec, tt_coderange_glyph,
load->exec->glyphIns, n_ins );
if ( error )
goto Exit;
load->exec->is_composite = FALSE;
load->exec->pts = *zone;
load->exec->pts.n_points += 4;
error = TT_Run_Context( load->exec, debug );
if ( error && load->exec->pedantic_hinting )
goto Exit;
error = TT_Err_Ok; /* ignore bytecode errors in non-pedantic mode */
}
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
}
/* save glyph phantom points */
if ( !load->preserve_pps )
{
load->pp1 = zone->cur[n_points - 4];
load->pp2 = zone->cur[n_points - 3];
load->pp3 = zone->cur[n_points - 2];
load->pp4 = zone->cur[n_points - 1];
}
#if defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) || \
defined( TT_CONFIG_OPTION_GX_VAR_SUPPORT )
Exit:
#endif
return error;
}
/*************************************************************************/
/* */
/* <Function> */
/* load_truetype_glyph */
/* */
/* <Description> */
/* Loads a given truetype glyph. Handles composites and uses a */
/* TT_Loader object. */
/* */
static FT_Error
load_truetype_glyph( TT_Loader loader,
FT_UInt glyph_index,
FT_UInt recurse_count )
{
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
FT_Stream stream = loader->stream;
#endif
FT_Error error;
TT_Face face = (TT_Face)loader->face;
FT_ULong offset;
FT_Int contours_count;
FT_UInt num_points, count;
FT_Fixed x_scale, y_scale;
FT_GlyphLoader gloader = loader->gloader;
FT_Bool opened_frame = 0;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
FT_StreamRec inc_stream;
FT_Data glyph_data;
FT_Bool glyph_data_loaded = 0;
#endif
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Vector *deltas;
#endif
if ( recurse_count >= TT_MAX_COMPOSITE_RECURSE )
{
error = TT_Err_Invalid_Composite;
goto Exit;
}
/* check glyph index */
if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
{
error = TT_Err_Invalid_Glyph_Index;
goto Exit;
}
loader->glyph_index = glyph_index;
num_points = 0;
x_scale = 0x10000L;
y_scale = 0x10000L;
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
x_scale = ((TT_Size)loader->size)->metrics.x_scale;
y_scale = ((TT_Size)loader->size)->metrics.y_scale;
}
/* get metrics, horizontal and vertical */
{
FT_Short left_bearing = 0, top_bearing = 0;
FT_UShort advance_width = 0, advance_height = 0;
Get_HMetrics( face, glyph_index,
(FT_Bool)!( loader->load_flags &
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
&left_bearing,
&advance_width );
Get_VMetrics( face, glyph_index,
(FT_Bool)!( loader->load_flags &
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
&top_bearing,
&advance_height );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font see if there are */
/* overriding metrics for this glyph. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Incremental_MetricsRec metrics;
metrics.bearing_x = left_bearing;
metrics.bearing_y = 0;
metrics.advance = advance_width;
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, FALSE, &metrics );
if ( error )
goto Exit;
left_bearing = (FT_Short)metrics.bearing_x;
advance_width = (FT_UShort)metrics.advance;
}
# if 0
/* GWW: Do I do the same for vertical metrics ??? */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Incremental_MetricsRec metrics;
metrics.bearing_x = 0;
metrics.bearing_y = top_bearing;
metrics.advance = advance_height;
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, TRUE, &metrics );
if ( error )
goto Exit;
top_bearing = (FT_Short)metrics.bearing_y;
advance_height = (FT_UShort)metrics.advance;
}
# endif
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
loader->left_bearing = left_bearing;
loader->advance = advance_width;
loader->top_bearing = top_bearing;
loader->vadvance = advance_height;
if ( !loader->linear_def )
{
loader->linear_def = 1;
loader->linear = advance_width;
}
}
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* Set `offset' to the start of the glyph program relative to the */
/* start of the 'glyf' table, and `count' to the length of the */
/* glyph program in bytes. */
/* */
/* If we are loading glyph data via the incremental interface, set */
/* the loader stream to a memory stream reading the data returned */
/* by the interface. */
if ( face->root.internal->incremental_interface )
{
error = face->root.internal->incremental_interface->funcs->get_glyph_data(
face->root.internal->incremental_interface->object,
glyph_index, &glyph_data );
if ( error )
goto Exit;
glyph_data_loaded = 1;
offset = 0;
count = glyph_data.length;
FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
FT_Stream_OpenMemory( &inc_stream,
glyph_data.pointer, glyph_data.length );
loader->stream = &inc_stream;
}
else
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
offset = tt_face_get_location( face, glyph_index, &count );
if ( count == 0 )
{
/* as described by Frederic Loyer, these are spaces, and */
/* not the unknown glyph. */
loader->bbox.xMin = 0;
loader->bbox.xMax = 0;
loader->bbox.yMin = 0;
loader->bbox.yMax = 0;
loader->pp1.x = 0;
loader->pp2.x = loader->advance;
loader->pp3.y = 0;
loader->pp4.y = loader->pp3.y-loader->vadvance;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( ((TT_Face)(loader->face))->doblend )
{
/* this must be done before scaling */
FT_Memory memory = loader->face->memory;
error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),
glyph_index, &deltas, 4 );
if ( error )
goto Exit;
loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y;
loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y;
loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y;
loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y;
FT_FREE( deltas );
}
#endif
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?