ttgload.c
来自「一个类似windows」· C语言 代码 · 共 1,925 行 · 第 1/5 页
C
1,925 行
loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
}
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
if ( loader->exec )
loader->exec->glyphSize = 0;
#endif
error = TT_Err_Ok;
goto Exit;
}
loader->byte_len = (FT_Int)count;
offset = loader->glyf_offset + offset;
/* access glyph frame */
error = face->access_glyph_frame( loader, glyph_index, offset, count );
if ( error )
goto Exit;
opened_frame = 1;
/* read first glyph header */
error = face->read_glyph_header( loader );
if ( error )
goto Fail;
contours_count = loader->n_contours;
count -= 10;
loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
loader->pp1.y = 0;
loader->pp2.x = loader->pp1.x + loader->advance;
loader->pp2.y = 0;
loader->pp3.x = 0;
loader->pp3.y = loader->top_bearing + loader->bbox.yMax;
loader->pp4.x = 0;
loader->pp4.y = loader->pp3.y - loader->vadvance;
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
/* if it is a simple glyph, load it */
if ( contours_count >= 0 )
{
/* check that we can add the contours to the glyph */
error = FT_GlyphLoader_CheckPoints( gloader, 0, contours_count );
if ( error )
goto Fail;
error = face->read_simple_glyph( loader );
if ( error )
goto Fail;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
{
TT_Size size = (TT_Size)loader->size;
error = TT_Process_Simple_Glyph( loader,
(FT_Bool)( size && size->debug ) );
}
#else
error = TT_Process_Simple_Glyph( loader, 0 );
#endif
if ( error )
goto Fail;
FT_GlyphLoader_Add( gloader );
/* Note: We could have put the simple loader source there */
/* but the code is fat enough already :-) */
}
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
/* otherwise, load a composite! */
else if ( contours_count == -1 )
{
TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph;
FT_UInt start_point;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
FT_UInt start_contour;
FT_ULong ins_pos; /* position of composite instructions, if any */
#endif
/* for each subglyph, read composite header */
start_point = gloader->base.outline.n_points;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
start_contour = gloader->base.outline.n_contours;
#endif
error = face->read_composite_glyph( loader );
if ( error )
goto Fail;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
ins_pos = loader->ins_pos;
#endif
face->forget_glyph_frame( loader );
opened_frame = 0;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( face->doblend )
{
FT_Int i, limit;
FT_SubGlyph subglyph;
FT_Memory memory = face->root.memory;
/* this provides additional offsets */
/* for each component's translation */
if ( (error = TT_Vary_Get_Glyph_Deltas(
face,
glyph_index,
&deltas,
gloader->current.num_subglyphs + 4 )) != 0 )
goto Exit;
/* Note: No subglyph reallocation here, our pointers are stable. */
subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
limit = gloader->current.num_subglyphs;
for ( i = 0; i < limit; ++i, ++subglyph )
{
if ( subglyph->flags & ARGS_ARE_XY_VALUES )
{
subglyph->arg1 += deltas[i].x;
subglyph->arg2 += deltas[i].y;
}
}
loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y;
loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y;
loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y;
loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y;
FT_FREE( deltas );
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
}
/* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
/* `as is' in the glyph slot (the client application will be */
/* responsible for interpreting these data)... */
/* */
if ( loader->load_flags & FT_LOAD_NO_RECURSE )
{
/* set up remaining glyph fields */
FT_GlyphLoader_Add( gloader );
glyph->num_subglyphs = gloader->base.num_subglyphs;
glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
glyph->subglyphs = gloader->base.subglyphs;
goto Exit;
}
/*********************************************************************/
/*********************************************************************/
/*********************************************************************/
/* Now, read each subglyph independently. */
{
FT_Int n, num_base_points, num_new_points;
FT_SubGlyph subglyph = 0;
FT_UInt num_subglyphs = gloader->current.num_subglyphs;
FT_UInt num_base_subgs = gloader->base.num_subglyphs;
FT_GlyphLoader_Add( gloader );
for ( n = 0; n < (FT_Int)num_subglyphs; n++ )
{
FT_Vector pp1, pp2, pp3, pp4;
FT_Pos x, y;
/* Each time we call load_truetype_glyph in this loop, the */
/* value of `gloader.base.subglyphs' can change due to table */
/* reallocations. We thus need to recompute the subglyph */
/* pointer on each iteration. */
subglyph = gloader->base.subglyphs + num_base_subgs + n;
pp1 = loader->pp1;
pp2 = loader->pp2;
pp3 = loader->pp3;
pp4 = loader->pp4;
num_base_points = gloader->base.outline.n_points;
error = load_truetype_glyph( loader, subglyph->index,
recurse_count + 1 );
if ( error )
goto Fail;
/* restore subglyph pointer */
subglyph = gloader->base.subglyphs + num_base_subgs + n;
if ( subglyph->flags & USE_MY_METRICS )
{
pp1 = loader->pp1;
pp2 = loader->pp2;
pp3 = loader->pp3;
pp4 = loader->pp4;
}
else
{
loader->pp1 = pp1;
loader->pp2 = pp2;
loader->pp3 = pp3;
loader->pp4 = pp4;
}
num_points = gloader->base.outline.n_points;
num_new_points = num_points - num_base_points;
/* now perform the transform required for this subglyph */
if ( subglyph->flags & ( WE_HAVE_A_SCALE |
WE_HAVE_AN_XY_SCALE |
WE_HAVE_A_2X2 ) )
{
FT_Vector* cur = gloader->base.outline.points +
num_base_points;
FT_Vector* org = gloader->base.extra_points +
num_base_points;
FT_Vector* limit = cur + num_new_points;
for ( ; cur < limit; cur++, org++ )
{
FT_Vector_Transform( cur, &subglyph->transform );
FT_Vector_Transform( org, &subglyph->transform );
}
}
/* apply offset */
if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
{
FT_UInt k = subglyph->arg1;
FT_UInt l = subglyph->arg2;
FT_Vector* p1;
FT_Vector* p2;
if ( start_point + k >= (FT_UInt)num_base_points ||
l >= (FT_UInt)num_new_points )
{
error = TT_Err_Invalid_Composite;
goto Fail;
}
l += num_base_points;
p1 = gloader->base.outline.points + start_point + k;
p2 = gloader->base.outline.points + start_point + l;
x = p1->x - p2->x;
y = p1->y - p2->y;
}
else
{
x = subglyph->arg1;
y = subglyph->arg2;
/* Use a default value dependent on */
/* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */
/* fonts which don't set the xxx_COMPONENT_OFFSET bit. */
#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
if ( !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) &&
#else
if ( ( subglyph->flags & SCALED_COMPONENT_OFFSET ) &&
#endif
( subglyph->flags & ( WE_HAVE_A_SCALE |
WE_HAVE_AN_XY_SCALE |
WE_HAVE_A_2X2 )) )
{
#if 0
/*************************************************************************/
/* */
/* This algorithm is what Apple documents. But it doesn't work. */
/* */
int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
: -subglyph->transform.xx;
int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
: -subglyph->transform.yx;
int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
: -subglyph->transform.xy;
int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
: -subglyph->transform.yy;
int m = a > b ? a : b;
int n = c > d ? c : d;
if ( a - b <= 33 && a - b >= -33 )
m *= 2;
if ( c - d <= 33 && c - d >= -33 )
n *= 2;
x = FT_MulFix( x, m );
y = FT_MulFix( y, n );
#else /* 0 */
/*************************************************************************/
/* */
/* This algorithm is a guess and works much better than the above. */
/* */
FT_Fixed mac_xscale = FT_SqrtFixed(
FT_MulFix( subglyph->transform.xx,
subglyph->transform.xx ) +
FT_MulFix( subglyph->transform.xy,
subglyph->transform.xy) );
FT_Fixed mac_yscale = FT_SqrtFixed(
FT_MulFix( subglyph->transform.yy,
subglyph->transform.yy ) +
FT_MulFix( subglyph->transform.yx,
subglyph->transform.yx ) );
x = FT_MulFix( x, mac_xscale );
y = FT_MulFix( y, mac_yscale );
#endif /* 0 */
}
if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
{
x = FT_MulFix( x, x_scale );
y = FT_MulFix( y, y_scale );
if ( subglyph->flags & ROUND_XY_TO_GRID )
{
x = FT_PIX_ROUND( x );
y = FT_PIX_ROUND( y );
}
}
}
if ( x || y )
{
translate_array( num_new_points,
gloader->base.outline.points + num_base_points,
x, y );
translate_array( num_new_points,
gloader->base.extra_points + num_base_points,
x, y );
}
}
/*******************************************************************/
/*******************************************************************/
/*******************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?