[truetype] Doh. Fix last commit to make it work.

Very embarassing :-)

Reported as

  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14701
  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14705
  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14710

* src/truetype/ttgload.c (IS_DEFAULT_INSTANCE): Move up and add
argument; update all callers.
(TT_Process_Simple_Glyph): Use it.  The `unrounded' array is active
for variation fonts only, thus also enclose related code with
`#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT ...  #endif' where
necessary.
Revert commit a113e5d from 2019-05-09, and don't use `extra_points2'
but allocate a temporary array.
Speed up the scaling of the `unrounded' array.

* src/truetype/ttgxvar.c (FT_fixedToInt, FT_FixedToFdot6): Fix type
conversions and rounding.  The unsigned type must have more or equal
bits to the signed type.
This commit is contained in:
Werner Lemberg 2019-05-12 21:05:36 +02:00
parent 1178227b39
commit 94ebc24865
3 changed files with 94 additions and 29 deletions

View File

@ -1,8 +1,34 @@
2019-05-12 Werner Lemberg <wl@gnu.org>
[truetype] Doh. Fix last commit to make it work.
Very embarassing :-)
Reported as
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14701
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14705
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14710
* src/truetype/ttgload.c (IS_DEFAULT_INSTANCE): Move up and add
argument; update all callers.
(TT_Process_Simple_Glyph): Use it. The `unrounded' array is active
for variation fonts only, thus also enclose related code with
`#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT ... #endif' where
necessary.
Revert commit a113e5d from 2019-05-09, and don't use `extra_points2'
but allocate a temporary array.
Speed up the scaling of the `unrounded' array.
* src/truetype/ttgxvar.c (FT_fixedToInt, FT_FixedToFdot6): Fix type
conversions and rounding. The unsigned type must have more or equal
bits to the signed type.
2019-05-09 Werner Lemberg <wl@gnu.org>
[truetype] Increase precision of font variation (#54371).
This patch make FreeType use font units in 26.6 format internally
This patch makes FreeType use font units in 26.6 format internally
instead of integers.
* src/truetype/ttgxvar.c (FT_fixedToFdot6): New macro.

View File

@ -82,6 +82,15 @@
#define UNSCALED_COMPONENT_OFFSET 0x1000
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#define IS_DEFAULT_INSTANCE( _face ) \
( !( FT_IS_NAMED_INSTANCE( _face ) || \
FT_IS_VARIATION( _face ) ) )
#else
#define IS_DEFAULT_INSTANCE( _face ) 1
#endif
/**************************************************************************
*
* Return the horizontal metrics in font units for a given glyph.
@ -925,9 +934,13 @@
FT_GlyphLoader gloader = loader->gloader;
FT_Error error = FT_Err_Ok;
FT_Outline* outline;
FT_Vector* unrounded;
FT_Int n_points;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Memory memory = loader->face->root.memory;
FT_Vector* unrounded = NULL;
#endif
outline = &gloader->current.outline;
n_points = outline->n_points;
@ -948,12 +961,12 @@
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
FT_IS_VARIATION( FT_FACE( loader->face ) ) )
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
{
/* Deltas apply to the unscaled data. */
/* We temporarily use `extra_points2' to hold unrounded values. */
unrounded = gloader->current.extra_points2;
if ( FT_NEW_ARRAY( unrounded, n_points ) )
goto Exit;
/* Deltas apply to the unscaled data. */
error = TT_Vary_Apply_Glyph_Deltas( loader->face,
loader->glyph_index,
outline,
@ -973,11 +986,19 @@
unrounded[n_points - 2].x ) / 64;
if ( error )
return error;
goto Exit;
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
if ( IS_HINTED( loader->load_flags ) )
{
tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
loader->zone.n_points + 4 );
}
{
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
TT_Face face = loader->face;
@ -1021,15 +1042,21 @@
/* the amount was determined via experimentation */
if ( x_scale_factor != 1000 && ppem > 11 )
{
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Vector* orig_points = outline->points;
outline->points = unrounded;
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
outline->points = unrounded;
#endif
FT_Outline_EmboldenXY( outline,
FT_MulFix( 1280 * ppem,
1000 - x_scale_factor ),
0 );
outline->points = orig_points;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
outline->points = orig_points;
#endif
}
do_scale = TRUE;
}
@ -1051,10 +1078,29 @@
if ( do_scale )
{
for ( ; vec < limit; vec++, unrounded++ )
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
{
vec->x = FT_MulDiv( unrounded->x, x_scale, 0x10000L * 64 );
vec->y = FT_MulDiv( unrounded->y, y_scale, 0x10000L * 64 );
FT_Vector* u = unrounded;
FT_Fixed xs = x_scale >> 6;
FT_Fixed ys = y_scale >> 6;
for ( ; vec < limit; vec++, u++ )
{
vec->x = FT_MulFix( u->x, xs );
vec->y = FT_MulFix( u->y, ys );
}
}
else
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
{
for ( ; vec < limit; vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
}
}
@ -1081,16 +1127,16 @@
if ( IS_HINTED( loader->load_flags ) )
{
tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
loader->zone.n_points + 4 );
loader->zone.n_points += 4;
error = TT_Hint_Glyph( loader, 0 );
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
Exit:
FT_FREE( unrounded );
#endif
return error;
}
@ -2742,13 +2788,6 @@
FT_Error error;
TT_LoaderRec loader;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \
FT_IS_VARIATION( glyph->face ) ) )
#else
#define IS_DEFAULT_INSTANCE 1
#endif
FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
@ -2757,7 +2796,7 @@
/* try to load embedded bitmap (if any) */
if ( size->strike_index != 0xFFFFFFFFUL &&
( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
IS_DEFAULT_INSTANCE )
IS_DEFAULT_INSTANCE( glyph->face ) )
{
FT_Fixed x_scale = size->root.metrics.x_scale;
FT_Fixed y_scale = size->root.metrics.y_scale;

View File

@ -72,10 +72,10 @@
( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
#define FT_intToFixed( i ) \
( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
#define FT_fixedToInt( x ) \
( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
#define FT_fixedToInt( x ) \
( (FT_Short)( ( (FT_ULong)(x) + 0x8000U ) >> 16 ) )
#define FT_fixedToFdot6( x ) \
( (FT_Pos)( ( (FT_UInt32)(x) + 0x20 ) >> 10 ) )
( (FT_Pos)( ( (FT_ULong)(x) + 0x200 ) >> 10 ) )
/**************************************************************************