[cff] Make blend operator work with floats in private dicts.

The CFF2 blend operator takes N default values and corresponding
sets of deltas and pushes N values specific to a designspace
location.  CFF has a floating point numeric type and the FreeType
blending code was not converting those into its internal 16.16
Fixed type format.

Fixes #1243.

* src/cff/cffparse.c (do_fixed): Handle floating point numbers.
Also fix scaling overflow check for integer-to-fixed conversion.

* src/cff/cffload.c (cff_blend_doBlend): Updated.
This commit is contained in:
Skef Iterum 2023-07-11 01:40:25 -07:00 committed by Werner Lemberg
parent dec2743e6a
commit 26a7f0478b
2 changed files with 23 additions and 4 deletions

View File

@ -1364,11 +1364,12 @@
FT_UInt32 sum;
/* convert inputs to 16.16 fixed-point */
sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
/* convert inputs to 16.16 fixed point */
sum = cff_parse_fixed( parser, &parser->stack[i + base] );
for ( j = 1; j < blend->lenBV; j++ )
sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++;
sum += FT_MulFix( cff_parse_fixed( parser, &parser->stack[delta++] ),
*weight++ );
/* point parser stack to new value on blend_stack */
parser->stack[i + base] = subFont->blend_top;

View File

@ -499,6 +499,24 @@
{
if ( **d == 30 )
return cff_parse_real( *d, parser->limit, scaling, NULL );
else if ( **d == 255 )
{
FT_Fixed val = ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
( (FT_UInt32)*( d[0] + 3 ) << 8 ) |
(FT_UInt32)*( d[0] + 4 ) ) );
if ( scaling )
{
if ( FT_ABS( val ) > power_ten_limits[scaling] )
{
FT_TRACE4(( "!!!OVERFLOW:!!!" ));
return val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
}
val *= power_tens[scaling];
}
return val;
}
else
{
FT_Long val = cff_parse_integer( *d, parser->limit );
@ -506,7 +524,7 @@
if ( scaling )
{
if ( FT_ABS( val ) > power_ten_limits[scaling] )
if ( ( FT_ABS( val ) << 16 ) > power_ten_limits[scaling] )
{
val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
goto Overflow;