aboutsummaryrefslogtreecommitdiff
path: root/freetype/src/truetype/ttgload.c
diff options
context:
space:
mode:
Diffstat (limited to 'freetype/src/truetype/ttgload.c')
-rw-r--r--freetype/src/truetype/ttgload.c103
1 files changed, 59 insertions, 44 deletions
diff --git a/freetype/src/truetype/ttgload.c b/freetype/src/truetype/ttgload.c
index 728fbc932..e660f6d17 100644
--- a/freetype/src/truetype/ttgload.c
+++ b/freetype/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType Glyph Loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -317,7 +317,7 @@
if ( n_ins > face->max_profile.maxSizeOfInstructions )
{
- FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions (%d)\n",
+ FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n",
n_ins ));
error = TT_Err_Too_Many_Hints;
goto Fail;
@@ -325,7 +325,7 @@
if ( ( limit - p ) < n_ins )
{
- FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" ));
+ FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
error = TT_Err_Too_Many_Hints;
goto Fail;
}
@@ -633,7 +633,13 @@
#ifdef TT_USE_BYTECODE_INTERPRETER
- n_ins = loader->glyph->control_len;
+ if ( loader->glyph->control_len > 0xFFFFL )
+ {
+ FT_TRACE1(( "TT_Hint_Glyph: too long instructions " ));
+ FT_TRACE1(( "(0x%lx byte) is truncated\n",
+ loader->glyph->control_len ));
+ }
+ n_ins = (FT_UInt)( loader->glyph->control_len );
#endif
origin = zone->cur[zone->n_points - 4].x;
@@ -680,6 +686,9 @@
FT_Bool debug;
FT_Error error;
+ FT_GlyphLoader gloader = loader->gloader;
+ FT_Outline current_outline = gloader->current.outline;
+
error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
loader->exec->glyphIns, n_ins );
@@ -695,6 +704,10 @@
error = TT_Run_Context( loader->exec, debug );
if ( error && loader->exec->pedantic_hinting )
return error;
+
+ /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
+ current_outline.tags[0] |=
+ ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
}
#endif
@@ -929,15 +942,15 @@
/* 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_Int32)FT_MulFix( subglyph->transform.xx,
+ subglyph->transform.xx ) +
+ (FT_Int32)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 ) );
+ (FT_Int32)FT_MulFix( subglyph->transform.yy,
+ subglyph->transform.yy ) +
+ (FT_Int32)FT_MulFix( subglyph->transform.yx,
+ subglyph->transform.yx ) );
x = FT_MulFix( x, mac_xscale );
@@ -1030,7 +1043,7 @@
/* check it */
if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions )
{
- FT_TRACE0(( "TT_Process_Composite_Glyph: Too many instructions (%d)\n",
+ FT_TRACE0(( "TT_Process_Composite_Glyph: too many instructions (%d)\n",
n_ins ));
return TT_Err_Too_Many_Hints;
@@ -1053,8 +1066,7 @@
/* Some points are likely touched during execution of */
/* instructions on components. So let's untouch them. */
for ( i = start_point; i < loader->zone.n_points; i++ )
- loader->zone.tags[i] &= ~( FT_CURVE_TAG_TOUCH_X |
- FT_CURVE_TAG_TOUCH_Y );
+ loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
loader->zone.n_points += 4;
@@ -1247,7 +1259,7 @@
{
if ( !loader->glyf_offset )
{
- FT_TRACE2(( "no `glyf' table but non-zero `loca' entry!\n" ));
+ FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
@@ -1388,8 +1400,11 @@
{
if ( subglyph->flags & ARGS_ARE_XY_VALUES )
{
- subglyph->arg1 += deltas[i].x;
- subglyph->arg2 += deltas[i].y;
+ /* XXX: overflow check for subglyph->{arg1,arg2}. */
+ /* deltas[i].{x,y} must be within signed 16-bit, */
+ /* but the restriction of summed delta is not clear */
+ subglyph->arg1 += (FT_Int16)deltas[i].x;
+ subglyph->arg2 += (FT_Int16)deltas[i].y;
}
}
@@ -1579,17 +1594,35 @@
glyph->metrics.horiBearingY = bbox.yMax;
glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
- /* Now take care of vertical metrics. In the case where there is */
- /* no vertical information within the font (relatively common), make */
- /* up some metrics by `hand'... */
+ /* adjust advance width to the value contained in the hdmx table */
+ if ( !face->postscript.isFixedPitch &&
+ IS_HINTED( loader->load_flags ) )
+ {
+ FT_Byte* widthp;
+
+
+ widthp = tt_face_get_device_metrics( face,
+ size->root.metrics.x_ppem,
+ glyph_index );
+
+ if ( widthp )
+ glyph->metrics.horiAdvance = *widthp << 6;
+ }
+
+ /* set glyph dimensions */
+ glyph->metrics.width = bbox.xMax - bbox.xMin;
+ glyph->metrics.height = bbox.yMax - bbox.yMin;
+ /* Now take care of vertical metrics. In the case where there is */
+ /* no vertical information within the font (relatively common), */
+ /* create some metrics manually */
{
FT_Pos top; /* scaled vertical top side bearing */
FT_Pos advance; /* scaled vertical advance height */
/* Get the unscaled top bearing and advance height. */
- if ( face->vertical_info &&
+ if ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 )
{
top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
@@ -1671,30 +1704,12 @@
/* XXX: for now, we have no better algorithm for the lsb, but it */
/* should work fine. */
/* */
- glyph->metrics.vertBearingX = ( bbox.xMin - bbox.xMax ) / 2;
+ glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -
+ glyph->metrics.horiAdvance / 2;
glyph->metrics.vertBearingY = top;
glyph->metrics.vertAdvance = advance;
}
- /* adjust advance width to the value contained in the hdmx table */
- if ( !face->postscript.isFixedPitch &&
- IS_HINTED( loader->load_flags ) )
- {
- FT_Byte* widthp;
-
-
- widthp = tt_face_get_device_metrics( face,
- size->root.metrics.x_ppem,
- glyph_index );
-
- if ( widthp )
- glyph->metrics.horiAdvance = *widthp << 6;
- }
-
- /* set glyph dimensions */
- glyph->metrics.width = bbox.xMax - bbox.xMin;
- glyph->metrics.height = bbox.yMax - bbox.yMin;
-
return 0;
}
@@ -1851,7 +1866,7 @@
loader->glyf_offset = 0;
else if ( error )
{
- FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
+ FT_ERROR(( "tt_loader_init: could not access glyph table\n" ));
return error;
}
else
@@ -1998,7 +2013,7 @@
break;
}
}
- else
+ else
glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
}