diff options
Diffstat (limited to 'src/cff/cf2intrp.c')
-rw-r--r-- | src/cff/cf2intrp.c | 205 |
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++; } |