summaryrefslogtreecommitdiff
path: root/src/cff/cf2intrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cff/cf2intrp.c')
-rw-r--r--src/cff/cf2intrp.c205
1 files changed, 144 insertions, 61 deletions
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 40bd9059a..8f0785d59 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -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,13 +846,21 @@
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 );
@@ -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,13 +1663,27 @@
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 );
@@ -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++;
}