forked from minhngoc25a/freetype2
[cff] Fix matrix scaling (#47848).
* include/freetype/config/ftstdlib.h (FT_LONG_MIN): New macro. * src/cff/cffparse.c (cff_parse_font_matrix): Use largest scaling value of all matrix coefficients to scale matrix. * src/cff/cffobjs.c (cff_face_init): Use `matrix->yx' member for matrix normalization if `matrix->yy' is zero.
This commit is contained in:
parent
533887a947
commit
119e8e41ef
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2016-05-17 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[cff] Fix matrix scaling (#47848).
|
||||
|
||||
* include/freetype/config/ftstdlib.h (FT_LONG_MIN): New macro.
|
||||
|
||||
* src/cff/cffparse.c (cff_parse_font_matrix): Use largest scaling
|
||||
value of all matrix coefficients to scale matrix.
|
||||
|
||||
* src/cff/cffobjs.c (cff_face_init): Use `matrix->yx' member for
|
||||
matrix normalization if `matrix->yy' is zero.
|
||||
|
||||
2016-05-16 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[base] Reject invalid sfnt Mac resource (#47891).
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#define FT_INT_MAX INT_MAX
|
||||
#define FT_INT_MIN INT_MIN
|
||||
#define FT_UINT_MAX UINT_MAX
|
||||
#define FT_LONG_MIN LONG_MIN
|
||||
#define FT_LONG_MAX LONG_MAX
|
||||
#define FT_ULONG_MAX ULONG_MAX
|
||||
|
||||
|
|
|
@ -670,10 +670,11 @@
|
|||
if ( !dict->has_font_matrix )
|
||||
dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
|
||||
|
||||
/* Normalize the font matrix so that `matrix->yy' is 1; the */
|
||||
/* scaling is done with `units_per_em' then (at this point, */
|
||||
/* it already contains the scaling factor, but without */
|
||||
/* normalization of the matrix). */
|
||||
/* Normalize the font matrix so that `matrix->yy' is 1; if */
|
||||
/* it is zero, we use `matrix->yx' instead. The scaling is */
|
||||
/* done with `units_per_em' then (at this point, it already */
|
||||
/* contains the scaling factor, but without normalization */
|
||||
/* of the matrix). */
|
||||
/* */
|
||||
/* Note that the offsets must be expressed in integer font */
|
||||
/* units. */
|
||||
|
@ -682,9 +683,12 @@
|
|||
FT_Matrix* matrix = &dict->font_matrix;
|
||||
FT_Vector* offset = &dict->font_offset;
|
||||
FT_ULong* upm = &dict->units_per_em;
|
||||
FT_Fixed temp = FT_ABS( matrix->yy );
|
||||
FT_Fixed temp;
|
||||
|
||||
|
||||
temp = matrix->yy ? FT_ABS( matrix->yy )
|
||||
: FT_ABS( matrix->yx );
|
||||
|
||||
if ( temp != 0x10000L )
|
||||
{
|
||||
*upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
|
||||
|
@ -752,7 +756,10 @@
|
|||
matrix = &sub->font_matrix;
|
||||
offset = &sub->font_offset;
|
||||
upm = &sub->units_per_em;
|
||||
temp = FT_ABS( matrix->yy );
|
||||
|
||||
temp = matrix->yy ? FT_ABS( matrix->yy )
|
||||
: FT_ABS( matrix->yx );
|
||||
|
||||
|
||||
if ( temp != 0x10000L )
|
||||
{
|
||||
|
|
|
@ -521,7 +521,11 @@
|
|||
|
||||
if ( parser->top >= parser->stack + 6 )
|
||||
{
|
||||
FT_Long scaling;
|
||||
FT_Fixed values[6];
|
||||
FT_Long scalings[6];
|
||||
|
||||
FT_Long min_scaling, max_scaling;
|
||||
int i;
|
||||
|
||||
|
||||
error = FT_Err_Ok;
|
||||
|
@ -530,22 +534,36 @@
|
|||
|
||||
/* We expect a well-formed font matrix, this is, the matrix elements */
|
||||
/* `xx' and `yy' are of approximately the same magnitude. To avoid */
|
||||
/* loss of precision, we use the magnitude of element `xx' to scale */
|
||||
/* all other elements. The scaling factor is then contained in the */
|
||||
/* `units_per_em' value. */
|
||||
/* loss of precision, we use the magnitude of the largest matrix */
|
||||
/* element to scale all other elements. The scaling factor is then */
|
||||
/* contained in the `units_per_em' value. */
|
||||
|
||||
matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
|
||||
max_scaling = FT_LONG_MIN;
|
||||
min_scaling = FT_LONG_MAX;
|
||||
|
||||
scaling = -scaling;
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
values[i] = cff_parse_fixed_dynamic( data++, &scalings[i] );
|
||||
if ( values[i] )
|
||||
{
|
||||
if ( scalings[i] > max_scaling )
|
||||
max_scaling = scalings[i];
|
||||
if ( scalings[i] < min_scaling )
|
||||
min_scaling = scalings[i];
|
||||
}
|
||||
}
|
||||
|
||||
if ( scaling < 0 || scaling > 9 )
|
||||
if ( max_scaling < -9 ||
|
||||
max_scaling > 0 ||
|
||||
( max_scaling - min_scaling ) < 0 ||
|
||||
( max_scaling - min_scaling ) > 9 )
|
||||
{
|
||||
/* Return default matrix in case of unlikely values. */
|
||||
|
||||
FT_TRACE1(( "cff_parse_font_matrix:"
|
||||
" strange scaling value for xx element (%d),\n"
|
||||
" strange scaling values (minimum %d, maximum %d),\n"
|
||||
" "
|
||||
" using default matrix\n", scaling ));
|
||||
" using default matrix\n", min_scaling, max_scaling ));
|
||||
|
||||
matrix->xx = 0x10000L;
|
||||
matrix->yx = 0;
|
||||
|
@ -558,13 +576,42 @@
|
|||
goto Exit;
|
||||
}
|
||||
|
||||
matrix->yx = cff_parse_fixed_scaled( data++, scaling );
|
||||
matrix->xy = cff_parse_fixed_scaled( data++, scaling );
|
||||
matrix->yy = cff_parse_fixed_scaled( data++, scaling );
|
||||
offset->x = cff_parse_fixed_scaled( data++, scaling );
|
||||
offset->y = cff_parse_fixed_scaled( data, scaling );
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
FT_Fixed value = values[i];
|
||||
FT_Long divisor, half_divisor;
|
||||
|
||||
*upm = (FT_ULong)power_tens[scaling];
|
||||
|
||||
if ( !value )
|
||||
continue;
|
||||
|
||||
divisor = power_tens[max_scaling - scalings[i]];
|
||||
half_divisor = divisor >> 1;
|
||||
|
||||
if ( value < 0 )
|
||||
{
|
||||
if ( FT_LONG_MIN + half_divisor < value )
|
||||
values[i] = ( value - half_divisor ) / divisor;
|
||||
else
|
||||
values[i] = FT_LONG_MIN / divisor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( FT_LONG_MAX - half_divisor > value )
|
||||
values[i] = ( value + half_divisor ) / divisor;
|
||||
else
|
||||
values[i] = FT_LONG_MAX / divisor;
|
||||
}
|
||||
}
|
||||
|
||||
matrix->xx = values[0];
|
||||
matrix->yx = values[1];
|
||||
matrix->xy = values[2];
|
||||
matrix->yy = values[3];
|
||||
offset->x = values[4];
|
||||
offset->y = values[5];
|
||||
|
||||
*upm = (FT_ULong)power_tens[-max_scaling];
|
||||
|
||||
FT_TRACE4(( " [%f %f %f %f %f %f]\n",
|
||||
(double)matrix->xx / *upm / 65536,
|
||||
|
|
Loading…
Reference in New Issue