[cff] 32bit integer overflow run-time errors 2/2 (#46149).
This commit handles the new engine. * include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG, NEG_INT32): New macros. * src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32. * src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init, cf2_hintmap_map, cf2_glyphpath_hintPoint, cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset, cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and NEG_INT32 where appropriate. * src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend, cf2_interpT2CharString): Ditto. Also add some other code where needed to avoid overflow.
This commit is contained in:
parent
9b710cd56e
commit
e66d7300fe
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
|||
2017-05-31 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[cff] 32bit integer overflow run-time errors 2/2 (#46149).
|
||||
|
||||
This commit handles the new engine.
|
||||
|
||||
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32,
|
||||
OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG,
|
||||
NEG_INT32): New macros.
|
||||
|
||||
* src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32.
|
||||
|
||||
* src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init,
|
||||
cf2_hintmap_map, cf2_glyphpath_hintPoint,
|
||||
cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset,
|
||||
cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use
|
||||
OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and
|
||||
NEG_INT32 where appropriate.
|
||||
|
||||
* src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend,
|
||||
cf2_interpT2CharString): Ditto.
|
||||
Also add some other code where needed to avoid overflow.
|
||||
|
||||
2017-05-30 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[cff] 32bit integer overflow run-time errors 1/2 (#46149).
|
||||
|
|
|
@ -423,6 +423,8 @@ FT_BEGIN_HEADER
|
|||
(FT_Int)( (FT_UInt)(a) - (FT_UInt)(b) )
|
||||
#define OVERFLOW_MUL_INT( a, b ) \
|
||||
(FT_Int)( (FT_UInt)(a) * (FT_UInt)(b) )
|
||||
#define NEG_INT( a ) \
|
||||
(FT_Int)( -(FT_UInt)(a) )
|
||||
|
||||
#define OVERFLOW_ADD_LONG( a, b ) \
|
||||
(FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) )
|
||||
|
@ -430,6 +432,17 @@ FT_BEGIN_HEADER
|
|||
(FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) )
|
||||
#define OVERFLOW_MUL_LONG( a, b ) \
|
||||
(FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) )
|
||||
#define NEG_LONG( a ) \
|
||||
(FT_Long)( -(FT_ULong)(a) )
|
||||
|
||||
#define OVERFLOW_ADD_INT32( a, b ) \
|
||||
(FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) )
|
||||
#define OVERFLOW_SUB_INT32( a, b ) \
|
||||
(FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) )
|
||||
#define OVERFLOW_MUL_INT32( a, b ) \
|
||||
(FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) )
|
||||
#define NEG_INT32( a ) \
|
||||
(FT_Int32)( -(FT_UInt32)(a) )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
|
|
@ -267,8 +267,10 @@
|
|||
|
||||
if ( *hinted )
|
||||
{
|
||||
*x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64;
|
||||
*y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64;
|
||||
*x_scale = OVERFLOW_ADD_INT32( decoder->builder.glyph->x_scale,
|
||||
32 ) / 64;
|
||||
*y_scale = OVERFLOW_ADD_INT32( decoder->builder.glyph->y_scale,
|
||||
32 ) / 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -74,8 +74,8 @@
|
|||
/* cross product of pt1 position from origin with pt2 position from */
|
||||
/* pt1; we reduce the precision so that the result fits into 32 bits */
|
||||
|
||||
return ( x1 >> 16 ) * ( ( y2 - y1 ) >> 16 ) -
|
||||
( y1 >> 16 ) * ( ( x2 - x1 ) >> 16 );
|
||||
return ( x1 >> 16 ) * ( OVERFLOW_SUB_INT32( y2, y1 ) >> 16 ) -
|
||||
( y1 >> 16 ) * ( OVERFLOW_SUB_INT32( x2, x1 ) >> 16 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,11 +185,11 @@
|
|||
/* darkening. Bottoms are not changed; tops are incremented by twice */
|
||||
/* `darkenY'. */
|
||||
if ( cf2_hint_isTop( hint ) )
|
||||
hint->csCoord += 2 * font->darkenY;
|
||||
hint->csCoord = OVERFLOW_ADD_INT32( hint->csCoord, 2 * font->darkenY );
|
||||
|
||||
hint->csCoord += hintOrigin;
|
||||
hint->scale = scale;
|
||||
hint->index = indexStemHint; /* index in original stem hint array */
|
||||
hint->csCoord = OVERFLOW_ADD_INT32( hint->csCoord, hintOrigin );
|
||||
hint->scale = scale;
|
||||
hint->index = indexStemHint; /* index in original stem hint array */
|
||||
|
||||
/* if original stem hint has been used, use the same position */
|
||||
if ( hint->flags != 0 && stemHint->used )
|
||||
|
@ -314,6 +314,7 @@
|
|||
/* start linear search from last hit */
|
||||
CF2_UInt i = hintmap->lastIndex;
|
||||
|
||||
|
||||
FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES );
|
||||
|
||||
/* search up */
|
||||
|
@ -330,9 +331,10 @@
|
|||
if ( i == 0 && csCoord < hintmap->edge[0].csCoord )
|
||||
{
|
||||
/* special case for points below first edge: use uniform scale */
|
||||
return FT_MulFix( csCoord - hintmap->edge[0].csCoord,
|
||||
hintmap->scale ) +
|
||||
hintmap->edge[0].dsCoord;
|
||||
return OVERFLOW_ADD_INT32(
|
||||
FT_MulFix( csCoord - hintmap->edge[0].csCoord,
|
||||
hintmap->scale ),
|
||||
hintmap->edge[0].dsCoord );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -340,9 +342,10 @@
|
|||
* Note: entries with duplicate csCoord are allowed.
|
||||
* Use edge[i], the highest entry where csCoord >= entry[i].csCoord
|
||||
*/
|
||||
return FT_MulFix( csCoord - hintmap->edge[i].csCoord,
|
||||
hintmap->edge[i].scale ) +
|
||||
hintmap->edge[i].dsCoord;
|
||||
return OVERFLOW_ADD_INT32(
|
||||
FT_MulFix( csCoord - hintmap->edge[i].csCoord,
|
||||
hintmap->edge[i].scale ),
|
||||
hintmap->edge[i].dsCoord );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -781,7 +784,7 @@
|
|||
cf2_arrstack_size( hStemHintArray ) +
|
||||
cf2_arrstack_size( vStemHintArray ) );
|
||||
if ( !cf2_hintmask_isValid( hintMask ) )
|
||||
return; /* too many stem hints */
|
||||
return; /* too many stem hints */
|
||||
}
|
||||
|
||||
/* begin by clearing the map */
|
||||
|
@ -797,7 +800,7 @@
|
|||
|
||||
/* Defense-in-depth. Should never return here. */
|
||||
if ( bitCount > hintMask->bitCount )
|
||||
return;
|
||||
return;
|
||||
|
||||
/* synthetic embox hints get highest priority */
|
||||
if ( font->blues.doEmBoxHints )
|
||||
|
@ -1095,16 +1098,20 @@
|
|||
FT_Vector pt; /* hinted point in upright DS */
|
||||
|
||||
|
||||
pt.x = FT_MulFix( glyphpath->scaleX, x ) +
|
||||
FT_MulFix( glyphpath->scaleC, y );
|
||||
pt.x = OVERFLOW_ADD_INT32( FT_MulFix( glyphpath->scaleX, x ),
|
||||
FT_MulFix( glyphpath->scaleC, y ) );
|
||||
pt.y = cf2_hintmap_map( hintmap, y );
|
||||
|
||||
ppt->x = FT_MulFix( glyphpath->font->outerTransform.a, pt.x ) +
|
||||
FT_MulFix( glyphpath->font->outerTransform.c, pt.y ) +
|
||||
glyphpath->fractionalTranslation.x;
|
||||
ppt->y = FT_MulFix( glyphpath->font->outerTransform.b, pt.x ) +
|
||||
FT_MulFix( glyphpath->font->outerTransform.d, pt.y ) +
|
||||
glyphpath->fractionalTranslation.y;
|
||||
ppt->x = OVERFLOW_ADD_INT32(
|
||||
FT_MulFix( glyphpath->font->outerTransform.a, pt.x ),
|
||||
OVERFLOW_ADD_INT32(
|
||||
FT_MulFix( glyphpath->font->outerTransform.c, pt.y ),
|
||||
glyphpath->fractionalTranslation.x ) );
|
||||
ppt->y = OVERFLOW_ADD_INT32(
|
||||
FT_MulFix( glyphpath->font->outerTransform.b, pt.x ),
|
||||
OVERFLOW_ADD_INT32(
|
||||
FT_MulFix( glyphpath->font->outerTransform.d, pt.y ),
|
||||
glyphpath->fractionalTranslation.y ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1154,12 +1161,12 @@
|
|||
CF2_Fixed denominator, s;
|
||||
|
||||
|
||||
u.x = CF2_CS_SCALE( u2->x - u1->x );
|
||||
u.y = CF2_CS_SCALE( u2->y - u1->y );
|
||||
v.x = CF2_CS_SCALE( v2->x - v1->x );
|
||||
v.y = CF2_CS_SCALE( v2->y - v1->y );
|
||||
w.x = CF2_CS_SCALE( v1->x - u1->x );
|
||||
w.y = CF2_CS_SCALE( v1->y - u1->y );
|
||||
u.x = CF2_CS_SCALE( OVERFLOW_SUB_INT32( u2->x, u1->x ) );
|
||||
u.y = CF2_CS_SCALE( OVERFLOW_SUB_INT32( u2->y, u1->y ) );
|
||||
v.x = CF2_CS_SCALE( OVERFLOW_SUB_INT32( v2->x, v1->x ) );
|
||||
v.y = CF2_CS_SCALE( OVERFLOW_SUB_INT32( v2->y, v1->y ) );
|
||||
w.x = CF2_CS_SCALE( OVERFLOW_SUB_INT32( v1->x, u1->x ) );
|
||||
w.y = CF2_CS_SCALE( OVERFLOW_SUB_INT32( v1->y, u1->y ) );
|
||||
|
||||
denominator = cf2_perp( u, v );
|
||||
|
||||
|
@ -1168,8 +1175,13 @@
|
|||
|
||||
s = FT_DivFix( cf2_perp( w, v ), denominator );
|
||||
|
||||
intersection->x = u1->x + FT_MulFix( s, u2->x - u1->x );
|
||||
intersection->y = u1->y + FT_MulFix( s, u2->y - u1->y );
|
||||
intersection->x = OVERFLOW_ADD_INT32(
|
||||
u1->x,
|
||||
FT_MulFix( s, OVERFLOW_SUB_INT32( u2->x, u1->x ) ) );
|
||||
intersection->y = OVERFLOW_ADD_INT32(
|
||||
u1->y,
|
||||
FT_MulFix( s, OVERFLOW_SUB_INT32( u2->y, u1->y ) ) );
|
||||
|
||||
|
||||
/*
|
||||
* Special case snapping for horizontal and vertical lines.
|
||||
|
@ -1180,25 +1192,35 @@
|
|||
*
|
||||
*/
|
||||
|
||||
if ( u1->x == u2->x &&
|
||||
cf2_fixedAbs( intersection->x - u1->x ) < glyphpath->snapThreshold )
|
||||
if ( u1->x == u2->x &&
|
||||
cf2_fixedAbs( OVERFLOW_SUB_INT32(
|
||||
intersection->x,
|
||||
u1->x ) ) < glyphpath->snapThreshold )
|
||||
intersection->x = u1->x;
|
||||
if ( u1->y == u2->y &&
|
||||
cf2_fixedAbs( intersection->y - u1->y ) < glyphpath->snapThreshold )
|
||||
if ( u1->y == u2->y &&
|
||||
cf2_fixedAbs( OVERFLOW_SUB_INT32(
|
||||
intersection->y,
|
||||
u1->y ) ) < glyphpath->snapThreshold )
|
||||
intersection->y = u1->y;
|
||||
|
||||
if ( v1->x == v2->x &&
|
||||
cf2_fixedAbs( intersection->x - v1->x ) < glyphpath->snapThreshold )
|
||||
if ( v1->x == v2->x &&
|
||||
cf2_fixedAbs( OVERFLOW_SUB_INT32(
|
||||
intersection->x,
|
||||
v1->x ) ) < glyphpath->snapThreshold )
|
||||
intersection->x = v1->x;
|
||||
if ( v1->y == v2->y &&
|
||||
cf2_fixedAbs( intersection->y - v1->y ) < glyphpath->snapThreshold )
|
||||
if ( v1->y == v2->y &&
|
||||
cf2_fixedAbs( OVERFLOW_SUB_INT32(
|
||||
intersection->y,
|
||||
v1->y ) ) < glyphpath->snapThreshold )
|
||||
intersection->y = v1->y;
|
||||
|
||||
/* limit the intersection distance from midpoint of u2 and v1 */
|
||||
if ( cf2_fixedAbs( intersection->x - ( u2->x + v1->x ) / 2 ) >
|
||||
glyphpath->miterLimit ||
|
||||
cf2_fixedAbs( intersection->y - ( u2->y + v1->y ) / 2 ) >
|
||||
glyphpath->miterLimit )
|
||||
if ( cf2_fixedAbs( intersection->x -
|
||||
OVERFLOW_ADD_INT32( u2->x, v1->x ) / 2 ) >
|
||||
glyphpath->miterLimit ||
|
||||
cf2_fixedAbs( intersection->y -
|
||||
OVERFLOW_ADD_INT32( u2->y, v1->y ) / 2 ) >
|
||||
glyphpath->miterLimit )
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -1446,16 +1468,16 @@
|
|||
CF2_Fixed* x,
|
||||
CF2_Fixed* y )
|
||||
{
|
||||
CF2_Fixed dx = x2 - x1;
|
||||
CF2_Fixed dy = y2 - y1;
|
||||
CF2_Fixed dx = OVERFLOW_SUB_INT32( x2, x1 );
|
||||
CF2_Fixed dy = OVERFLOW_SUB_INT32( y2, y1 );
|
||||
|
||||
|
||||
/* note: negative offsets don't work here; negate deltas to change */
|
||||
/* quadrants, below */
|
||||
if ( glyphpath->font->reverseWinding )
|
||||
{
|
||||
dx = -dx;
|
||||
dy = -dy;
|
||||
dx = NEG_INT32( dx );
|
||||
dy = NEG_INT32( dy );
|
||||
}
|
||||
|
||||
*x = *y = 0;
|
||||
|
@ -1474,13 +1496,13 @@
|
|||
{
|
||||
/* first quadrant, +x +y */
|
||||
|
||||
if ( dx > 2 * dy )
|
||||
if ( dx > OVERFLOW_MUL_INT32( 2, dy ) )
|
||||
{
|
||||
/* +x */
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
}
|
||||
else if ( dy > 2 * dx )
|
||||
else if ( dy > OVERFLOW_MUL_INT32( 2, dx ) )
|
||||
{
|
||||
/* +y */
|
||||
*x = glyphpath->xOffset;
|
||||
|
@ -1499,16 +1521,16 @@
|
|||
{
|
||||
/* fourth quadrant, +x -y */
|
||||
|
||||
if ( dx > -2 * dy )
|
||||
if ( dx > OVERFLOW_MUL_INT32( -2, dy ) )
|
||||
{
|
||||
/* +x */
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
}
|
||||
else if ( -dy > 2 * dx )
|
||||
else if ( NEG_INT32( dy ) > OVERFLOW_MUL_INT32( 2, dx ) )
|
||||
{
|
||||
/* -y */
|
||||
*x = -glyphpath->xOffset;
|
||||
*x = NEG_INT32( glyphpath->xOffset );
|
||||
*y = glyphpath->yOffset;
|
||||
}
|
||||
else
|
||||
|
@ -1527,13 +1549,13 @@
|
|||
{
|
||||
/* second quadrant, -x +y */
|
||||
|
||||
if ( -dx > 2 * dy )
|
||||
if ( NEG_INT32( dx ) > OVERFLOW_MUL_INT32( 2, dy ) )
|
||||
{
|
||||
/* -x */
|
||||
*x = 0;
|
||||
*y = 2 * glyphpath->yOffset;
|
||||
*y = OVERFLOW_MUL_INT32( 2, glyphpath->yOffset );
|
||||
}
|
||||
else if ( dy > -2 * dx )
|
||||
else if ( dy > OVERFLOW_MUL_INT32( -2, dx ) )
|
||||
{
|
||||
/* +y */
|
||||
*x = glyphpath->xOffset;
|
||||
|
@ -1552,16 +1574,16 @@
|
|||
{
|
||||
/* third quadrant, -x -y */
|
||||
|
||||
if ( -dx > -2 * dy )
|
||||
if ( NEG_INT32( dx ) > OVERFLOW_MUL_INT32( -2, dy ) )
|
||||
{
|
||||
/* -x */
|
||||
*x = 0;
|
||||
*y = 2 * glyphpath->yOffset;
|
||||
*y = OVERFLOW_MUL_INT32( 2, glyphpath->yOffset );
|
||||
}
|
||||
else if ( -dy > -2 * dx )
|
||||
else if ( NEG_INT32( dy ) > OVERFLOW_MUL_INT32( -2, dx ) )
|
||||
{
|
||||
/* -y */
|
||||
*x = -glyphpath->xOffset;
|
||||
*x = NEG_INT32( glyphpath->xOffset );
|
||||
*y = glyphpath->yOffset;
|
||||
}
|
||||
else
|
||||
|
@ -1675,10 +1697,10 @@
|
|||
&yOffset );
|
||||
|
||||
/* construct offset points */
|
||||
P0.x = glyphpath->currentCS.x + xOffset;
|
||||
P0.y = glyphpath->currentCS.y + yOffset;
|
||||
P1.x = x + xOffset;
|
||||
P1.y = y + yOffset;
|
||||
P0.x = OVERFLOW_ADD_INT32( glyphpath->currentCS.x, xOffset );
|
||||
P0.y = OVERFLOW_ADD_INT32( glyphpath->currentCS.y, yOffset );
|
||||
P1.x = OVERFLOW_ADD_INT32( x, xOffset );
|
||||
P1.y = OVERFLOW_ADD_INT32( y, yOffset );
|
||||
|
||||
if ( glyphpath->moveIsPending )
|
||||
{
|
||||
|
@ -1757,15 +1779,15 @@
|
|||
cf2_getWindingMomentum( x1, y1, x2, y2 );
|
||||
|
||||
/* construct offset points */
|
||||
P0.x = glyphpath->currentCS.x + xOffset1;
|
||||
P0.y = glyphpath->currentCS.y + yOffset1;
|
||||
P1.x = x1 + xOffset1;
|
||||
P1.y = y1 + yOffset1;
|
||||
P0.x = OVERFLOW_ADD_INT32( glyphpath->currentCS.x, xOffset1 );
|
||||
P0.y = OVERFLOW_ADD_INT32( glyphpath->currentCS.y, yOffset1 );
|
||||
P1.x = OVERFLOW_ADD_INT32( x1, xOffset1 );
|
||||
P1.y = OVERFLOW_ADD_INT32( y1, yOffset1 );
|
||||
/* note: preserve angle of final segment by using offset3 at both ends */
|
||||
P2.x = x2 + xOffset3;
|
||||
P2.y = y2 + yOffset3;
|
||||
P3.x = x3 + xOffset3;
|
||||
P3.y = y3 + yOffset3;
|
||||
P2.x = OVERFLOW_ADD_INT32( x2, xOffset3 );
|
||||
P2.y = OVERFLOW_ADD_INT32( y2, yOffset3 );
|
||||
P3.x = OVERFLOW_ADD_INT32( x3, xOffset3 );
|
||||
P3.y = OVERFLOW_ADD_INT32( y3, yOffset3 );
|
||||
|
||||
if ( glyphpath->moveIsPending )
|
||||
{
|
||||
|
|
|
@ -348,7 +348,9 @@
|
|||
{
|
||||
vals[i + 2] = vals[i];
|
||||
if ( readFromStack[i] )
|
||||
vals[i + 2] += cf2_stack_getReal( opStack, idx++ );
|
||||
vals[i + 2] = OVERFLOW_ADD_INT32( vals[i + 2],
|
||||
cf2_stack_getReal( opStack,
|
||||
idx++ ) );
|
||||
}
|
||||
|
||||
if ( isHFlex )
|
||||
|
@ -363,24 +365,26 @@
|
|||
|
||||
if ( lastIsX )
|
||||
{
|
||||
vals[12] = vals[10] + lastVal;
|
||||
vals[12] = OVERFLOW_ADD_INT32( vals[10], lastVal );
|
||||
vals[13] = *curY;
|
||||
}
|
||||
else
|
||||
{
|
||||
vals[12] = *curX;
|
||||
vals[13] = vals[11] + lastVal;
|
||||
vals[13] = OVERFLOW_ADD_INT32( vals[11], lastVal );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( readFromStack[10] )
|
||||
vals[12] = vals[10] + cf2_stack_getReal( opStack, idx++ );
|
||||
vals[12] = OVERFLOW_ADD_INT32( vals[10],
|
||||
cf2_stack_getReal( opStack, idx++ ) );
|
||||
else
|
||||
vals[12] = *curX;
|
||||
|
||||
if ( readFromStack[11] )
|
||||
vals[13] = vals[11] + cf2_stack_getReal( opStack, idx );
|
||||
vals[13] = OVERFLOW_ADD_INT32( vals[11],
|
||||
cf2_stack_getReal( opStack, idx ) );
|
||||
else
|
||||
vals[13] = *curY;
|
||||
}
|
||||
|
@ -426,7 +430,10 @@
|
|||
|
||||
|
||||
for ( j = 1; j < blend->lenBV; j++ )
|
||||
sum += FT_MulFix( *weight++, cf2_stack_getReal( opStack, delta++ ) );
|
||||
sum = OVERFLOW_ADD_INT32(
|
||||
sum,
|
||||
FT_MulFix( *weight++,
|
||||
cf2_stack_getReal( opStack, delta++ ) ) );
|
||||
|
||||
/* store blended result */
|
||||
cf2_stack_setReal( opStack, i + base, sum );
|
||||
|
@ -767,7 +774,7 @@
|
|||
if ( font->decoder->width_only )
|
||||
goto exit;
|
||||
|
||||
curY += cf2_stack_popFixed( opStack );
|
||||
curY = OVERFLOW_ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
|
||||
|
||||
cf2_glyphpath_moveTo( &glyphPath, curX, curY );
|
||||
|
||||
|
@ -783,8 +790,12 @@
|
|||
|
||||
for ( idx = 0; idx < count; idx += 2 )
|
||||
{
|
||||
curX += cf2_stack_getReal( opStack, idx + 0 );
|
||||
curY += cf2_stack_getReal( opStack, idx + 1 );
|
||||
curX = OVERFLOW_ADD_INT32( curX,
|
||||
cf2_stack_getReal( opStack,
|
||||
idx + 0 ) );
|
||||
curY = OVERFLOW_ADD_INT32( curY,
|
||||
cf2_stack_getReal( opStack,
|
||||
idx + 1 ) );
|
||||
|
||||
cf2_glyphpath_lineTo( &glyphPath, curX, curY );
|
||||
}
|
||||
|
@ -810,9 +821,9 @@
|
|||
|
||||
|
||||
if ( isX )
|
||||
curX += v;
|
||||
curX = OVERFLOW_ADD_INT32( curX, v );
|
||||
else
|
||||
curY += v;
|
||||
curY = OVERFLOW_ADD_INT32( curY, v );
|
||||
|
||||
isX = !isX;
|
||||
|
||||
|
@ -835,14 +846,22 @@
|
|||
|
||||
while ( idx + 6 <= count )
|
||||
{
|
||||
CF2_Fixed x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX;
|
||||
CF2_Fixed y1 = cf2_stack_getReal( opStack, idx + 1 ) + curY;
|
||||
CF2_Fixed x2 = cf2_stack_getReal( opStack, idx + 2 ) + x1;
|
||||
CF2_Fixed y2 = cf2_stack_getReal( opStack, idx + 3 ) + y1;
|
||||
CF2_Fixed x3 = cf2_stack_getReal( opStack, idx + 4 ) + x2;
|
||||
CF2_Fixed y3 = cf2_stack_getReal( opStack, idx + 5 ) + y2;
|
||||
CF2_Fixed x1, y1, x2, y2, x3, y3;
|
||||
|
||||
|
||||
x1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ),
|
||||
curX );
|
||||
y1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ),
|
||||
curY );
|
||||
x2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ),
|
||||
x1 );
|
||||
y2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ),
|
||||
y1 );
|
||||
x3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ),
|
||||
x2 );
|
||||
y3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ),
|
||||
y2 );
|
||||
|
||||
cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
|
||||
|
||||
curX = x3;
|
||||
|
@ -852,8 +871,12 @@
|
|||
|
||||
if ( op1 == cf2_cmdRCURVELINE )
|
||||
{
|
||||
curX += cf2_stack_getReal( opStack, idx + 0 );
|
||||
curY += cf2_stack_getReal( opStack, idx + 1 );
|
||||
curX = OVERFLOW_ADD_INT32( curX,
|
||||
cf2_stack_getReal( opStack,
|
||||
idx + 0 ) );
|
||||
curY = OVERFLOW_ADD_INT32( curY,
|
||||
cf2_stack_getReal( opStack,
|
||||
idx + 1 ) );
|
||||
|
||||
cf2_glyphpath_lineTo( &glyphPath, curX, curY );
|
||||
}
|
||||
|
@ -1129,7 +1152,10 @@
|
|||
|
||||
arg = cf2_stack_popFixed( opStack );
|
||||
|
||||
cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
|
||||
if ( arg < -CF2_FIXED_MAX )
|
||||
cf2_stack_pushFixed( opStack, CF2_FIXED_MAX );
|
||||
else
|
||||
cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
|
@ -1144,7 +1170,9 @@
|
|||
summand2 = cf2_stack_popFixed( opStack );
|
||||
summand1 = cf2_stack_popFixed( opStack );
|
||||
|
||||
cf2_stack_pushFixed( opStack, summand1 + summand2 );
|
||||
cf2_stack_pushFixed( opStack,
|
||||
OVERFLOW_ADD_INT32( summand1,
|
||||
summand2 ) );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
|
@ -1159,7 +1187,9 @@
|
|||
subtrahend = cf2_stack_popFixed( opStack );
|
||||
minuend = cf2_stack_popFixed( opStack );
|
||||
|
||||
cf2_stack_pushFixed( opStack, minuend - subtrahend );
|
||||
cf2_stack_pushFixed( opStack,
|
||||
OVERFLOW_SUB_INT32( minuend,
|
||||
subtrahend ) );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
|
@ -1174,7 +1204,8 @@
|
|||
divisor = cf2_stack_popFixed( opStack );
|
||||
dividend = cf2_stack_popFixed( opStack );
|
||||
|
||||
cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) );
|
||||
cf2_stack_pushFixed( opStack,
|
||||
FT_DivFix( dividend, divisor ) );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
|
@ -1187,7 +1218,10 @@
|
|||
|
||||
arg = cf2_stack_popFixed( opStack );
|
||||
|
||||
cf2_stack_pushFixed( opStack, -arg );
|
||||
if ( arg < -CF2_FIXED_MAX )
|
||||
cf2_stack_pushFixed( opStack, CF2_FIXED_MAX );
|
||||
else
|
||||
cf2_stack_pushFixed( opStack, -arg );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
|
@ -1257,7 +1291,8 @@
|
|||
arg2 = cf2_stack_popFixed( opStack );
|
||||
arg1 = cf2_stack_popFixed( opStack );
|
||||
|
||||
cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 );
|
||||
cf2_stack_pushFixed( opStack,
|
||||
cond1 <= cond2 ? arg1 : arg2 );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
|
@ -1291,7 +1326,8 @@
|
|||
factor2 = cf2_stack_popFixed( opStack );
|
||||
factor1 = cf2_stack_popFixed( opStack );
|
||||
|
||||
cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) );
|
||||
cf2_stack_pushFixed( opStack,
|
||||
FT_MulFix( factor1, factor2 ) );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
|
@ -1305,7 +1341,9 @@
|
|||
arg = cf2_stack_popFixed( opStack );
|
||||
if ( arg > 0 )
|
||||
{
|
||||
FT_Fixed root = arg;
|
||||
/* use a start value that doesn't make */
|
||||
/* the algorithm's addition overflow */
|
||||
FT_Fixed root = arg < 10 ? arg : arg >> 1;
|
||||
FT_Fixed new_root;
|
||||
|
||||
|
||||
|
@ -1369,7 +1407,8 @@
|
|||
|
||||
if ( size > 0 )
|
||||
{
|
||||
/* for `cf2_stack_getReal', index 0 is bottom of stack */
|
||||
/* for `cf2_stack_getReal', */
|
||||
/* index 0 is bottom of stack */
|
||||
CF2_UInt gr_idx;
|
||||
|
||||
|
||||
|
@ -1381,7 +1420,8 @@
|
|||
gr_idx = size - 1 - (CF2_UInt)idx;
|
||||
|
||||
cf2_stack_pushFixed( opStack,
|
||||
cf2_stack_getReal( opStack, gr_idx ) );
|
||||
cf2_stack_getReal( opStack,
|
||||
gr_idx ) );
|
||||
}
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
@ -1416,7 +1456,8 @@
|
|||
cf2_stack_count( opStack ) == 5 )
|
||||
{
|
||||
if ( !haveWidth )
|
||||
*width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
|
||||
*width = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, 0 ),
|
||||
nominalWidthX );
|
||||
}
|
||||
|
||||
/* width is defined or default after this */
|
||||
|
@ -1564,7 +1605,8 @@
|
|||
FT_TRACE4(( " rmoveto\n" ));
|
||||
|
||||
if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
|
||||
*width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
|
||||
*width = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, 0 ),
|
||||
nominalWidthX );
|
||||
|
||||
/* width is defined or default after this */
|
||||
haveWidth = TRUE;
|
||||
|
@ -1583,7 +1625,8 @@
|
|||
FT_TRACE4(( " hmoveto\n" ));
|
||||
|
||||
if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
|
||||
*width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
|
||||
*width = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, 0 ),
|
||||
nominalWidthX );
|
||||
|
||||
/* width is defined or default after this */
|
||||
haveWidth = TRUE;
|
||||
|
@ -1591,7 +1634,7 @@
|
|||
if ( font->decoder->width_only )
|
||||
goto exit;
|
||||
|
||||
curX += cf2_stack_popFixed( opStack );
|
||||
curX = OVERFLOW_ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
|
||||
|
||||
cf2_glyphpath_moveTo( &glyphPath, curX, curY );
|
||||
|
||||
|
@ -1607,8 +1650,12 @@
|
|||
|
||||
while ( idx + 6 < count )
|
||||
{
|
||||
curX += cf2_stack_getReal( opStack, idx + 0 );
|
||||
curY += cf2_stack_getReal( opStack, idx + 1 );
|
||||
curX = OVERFLOW_ADD_INT32( curX,
|
||||
cf2_stack_getReal( opStack,
|
||||
idx + 0 ) );
|
||||
curY = OVERFLOW_ADD_INT32( curY,
|
||||
cf2_stack_getReal( opStack,
|
||||
idx + 1 ) );
|
||||
|
||||
cf2_glyphpath_lineTo( &glyphPath, curX, curY );
|
||||
idx += 2;
|
||||
|
@ -1616,14 +1663,28 @@
|
|||
|
||||
while ( idx < count )
|
||||
{
|
||||
CF2_Fixed x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX;
|
||||
CF2_Fixed y1 = cf2_stack_getReal( opStack, idx + 1 ) + curY;
|
||||
CF2_Fixed x2 = cf2_stack_getReal( opStack, idx + 2 ) + x1;
|
||||
CF2_Fixed y2 = cf2_stack_getReal( opStack, idx + 3 ) + y1;
|
||||
CF2_Fixed x3 = cf2_stack_getReal( opStack, idx + 4 ) + x2;
|
||||
CF2_Fixed y3 = cf2_stack_getReal( opStack, idx + 5 ) + y2;
|
||||
CF2_Fixed x1, y1, x2, y2, x3, y3;
|
||||
|
||||
|
||||
x1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 0 ),
|
||||
curX );
|
||||
y1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 1 ),
|
||||
curY );
|
||||
x2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 2 ),
|
||||
x1 );
|
||||
y2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 3 ),
|
||||
y1 );
|
||||
x3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 4 ),
|
||||
x2 );
|
||||
y3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 5 ),
|
||||
y2 );
|
||||
|
||||
cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
|
||||
|
||||
curX = x3;
|
||||
|
@ -1656,18 +1717,23 @@
|
|||
|
||||
if ( ( count - idx ) & 1 )
|
||||
{
|
||||
x1 = cf2_stack_getReal( opStack, idx ) + curX;
|
||||
x1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx ),
|
||||
curX );
|
||||
|
||||
idx++;
|
||||
}
|
||||
else
|
||||
x1 = curX;
|
||||
|
||||
y1 = cf2_stack_getReal( opStack, idx + 0 ) + curY;
|
||||
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1;
|
||||
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1;
|
||||
y1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ),
|
||||
curY );
|
||||
x2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ),
|
||||
x1 );
|
||||
y2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ),
|
||||
y1 );
|
||||
x3 = x2;
|
||||
y3 = cf2_stack_getReal( opStack, idx + 3 ) + y2;
|
||||
y3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ),
|
||||
y2 );
|
||||
|
||||
cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
|
||||
|
||||
|
@ -1701,17 +1767,22 @@
|
|||
|
||||
if ( ( count - idx ) & 1 )
|
||||
{
|
||||
y1 = cf2_stack_getReal( opStack, idx ) + curY;
|
||||
y1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx ),
|
||||
curY );
|
||||
|
||||
idx++;
|
||||
}
|
||||
else
|
||||
y1 = curY;
|
||||
|
||||
x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX;
|
||||
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1;
|
||||
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1;
|
||||
x3 = cf2_stack_getReal( opStack, idx + 3 ) + x2;
|
||||
x1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ),
|
||||
curX );
|
||||
x2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ),
|
||||
x1 );
|
||||
y2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ),
|
||||
y1 );
|
||||
x3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ),
|
||||
x2 );
|
||||
y3 = y2;
|
||||
|
||||
cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
|
||||
|
@ -1750,15 +1821,21 @@
|
|||
|
||||
if ( alternate )
|
||||
{
|
||||
x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX;
|
||||
x1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ),
|
||||
curX );
|
||||
y1 = curY;
|
||||
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1;
|
||||
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1;
|
||||
y3 = cf2_stack_getReal( opStack, idx + 3 ) + y2;
|
||||
x2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ),
|
||||
x1 );
|
||||
y2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ),
|
||||
y1 );
|
||||
y3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ),
|
||||
y2 );
|
||||
|
||||
if ( count - idx == 5 )
|
||||
{
|
||||
x3 = cf2_stack_getReal( opStack, idx + 4 ) + x2;
|
||||
x3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 4 ),
|
||||
x2 );
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
@ -1770,14 +1847,20 @@
|
|||
else
|
||||
{
|
||||
x1 = curX;
|
||||
y1 = cf2_stack_getReal( opStack, idx + 0 ) + curY;
|
||||
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1;
|
||||
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1;
|
||||
x3 = cf2_stack_getReal( opStack, idx + 3 ) + x2;
|
||||
y1 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ),
|
||||
curY );
|
||||
x2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ),
|
||||
x1 );
|
||||
y2 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ),
|
||||
y1 );
|
||||
x3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ),
|
||||
x2 );
|
||||
|
||||
if ( count - idx == 5 )
|
||||
{
|
||||
y3 = cf2_stack_getReal( opStack, idx + 4 ) + y2;
|
||||
y3 = OVERFLOW_ADD_INT32( cf2_stack_getReal( opStack,
|
||||
idx + 4 ),
|
||||
y2 );
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue