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>
|
2016-05-16 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[base] Reject invalid sfnt Mac resource (#47891).
|
[base] Reject invalid sfnt Mac resource (#47891).
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#define FT_INT_MAX INT_MAX
|
#define FT_INT_MAX INT_MAX
|
||||||
#define FT_INT_MIN INT_MIN
|
#define FT_INT_MIN INT_MIN
|
||||||
#define FT_UINT_MAX UINT_MAX
|
#define FT_UINT_MAX UINT_MAX
|
||||||
|
#define FT_LONG_MIN LONG_MIN
|
||||||
#define FT_LONG_MAX LONG_MAX
|
#define FT_LONG_MAX LONG_MAX
|
||||||
#define FT_ULONG_MAX ULONG_MAX
|
#define FT_ULONG_MAX ULONG_MAX
|
||||||
|
|
||||||
|
|
|
@ -670,10 +670,11 @@
|
||||||
if ( !dict->has_font_matrix )
|
if ( !dict->has_font_matrix )
|
||||||
dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
|
dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
|
||||||
|
|
||||||
/* Normalize the font matrix so that `matrix->yy' is 1; the */
|
/* Normalize the font matrix so that `matrix->yy' is 1; if */
|
||||||
/* scaling is done with `units_per_em' then (at this point, */
|
/* it is zero, we use `matrix->yx' instead. The scaling is */
|
||||||
/* it already contains the scaling factor, but without */
|
/* done with `units_per_em' then (at this point, it already */
|
||||||
/* normalization of the matrix). */
|
/* contains the scaling factor, but without normalization */
|
||||||
|
/* of the matrix). */
|
||||||
/* */
|
/* */
|
||||||
/* Note that the offsets must be expressed in integer font */
|
/* Note that the offsets must be expressed in integer font */
|
||||||
/* units. */
|
/* units. */
|
||||||
|
@ -682,9 +683,12 @@
|
||||||
FT_Matrix* matrix = &dict->font_matrix;
|
FT_Matrix* matrix = &dict->font_matrix;
|
||||||
FT_Vector* offset = &dict->font_offset;
|
FT_Vector* offset = &dict->font_offset;
|
||||||
FT_ULong* upm = &dict->units_per_em;
|
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 )
|
if ( temp != 0x10000L )
|
||||||
{
|
{
|
||||||
*upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
|
*upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
|
||||||
|
@ -752,7 +756,10 @@
|
||||||
matrix = &sub->font_matrix;
|
matrix = &sub->font_matrix;
|
||||||
offset = &sub->font_offset;
|
offset = &sub->font_offset;
|
||||||
upm = &sub->units_per_em;
|
upm = &sub->units_per_em;
|
||||||
temp = FT_ABS( matrix->yy );
|
|
||||||
|
temp = matrix->yy ? FT_ABS( matrix->yy )
|
||||||
|
: FT_ABS( matrix->yx );
|
||||||
|
|
||||||
|
|
||||||
if ( temp != 0x10000L )
|
if ( temp != 0x10000L )
|
||||||
{
|
{
|
||||||
|
|
|
@ -521,7 +521,11 @@
|
||||||
|
|
||||||
if ( parser->top >= parser->stack + 6 )
|
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;
|
error = FT_Err_Ok;
|
||||||
|
@ -530,22 +534,36 @@
|
||||||
|
|
||||||
/* We expect a well-formed font matrix, this is, the matrix elements */
|
/* We expect a well-formed font matrix, this is, the matrix elements */
|
||||||
/* `xx' and `yy' are of approximately the same magnitude. To avoid */
|
/* `xx' and `yy' are of approximately the same magnitude. To avoid */
|
||||||
/* loss of precision, we use the magnitude of element `xx' to scale */
|
/* loss of precision, we use the magnitude of the largest matrix */
|
||||||
/* all other elements. The scaling factor is then contained in the */
|
/* element to scale all other elements. The scaling factor is then */
|
||||||
/* `units_per_em' value. */
|
/* 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. */
|
/* Return default matrix in case of unlikely values. */
|
||||||
|
|
||||||
FT_TRACE1(( "cff_parse_font_matrix:"
|
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->xx = 0x10000L;
|
||||||
matrix->yx = 0;
|
matrix->yx = 0;
|
||||||
|
@ -558,13 +576,42 @@
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix->yx = cff_parse_fixed_scaled( data++, scaling );
|
for ( i = 0; i < 6; i++ )
|
||||||
matrix->xy = cff_parse_fixed_scaled( data++, scaling );
|
{
|
||||||
matrix->yy = cff_parse_fixed_scaled( data++, scaling );
|
FT_Fixed value = values[i];
|
||||||
offset->x = cff_parse_fixed_scaled( data++, scaling );
|
FT_Long divisor, half_divisor;
|
||||||
offset->y = cff_parse_fixed_scaled( data, scaling );
|
|
||||||
|
|
||||||
*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",
|
FT_TRACE4(( " [%f %f %f %f %f %f]\n",
|
||||||
(double)matrix->xx / *upm / 65536,
|
(double)matrix->xx / *upm / 65536,
|
||||||
|
|
Loading…
Reference in New Issue