From 94ebc248653ede802b2bfbf6219e17f487fab3ff Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sun, 12 May 2019 21:05:36 +0200 Subject: [PATCH] [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. --- ChangeLog | 28 ++++++++++++- src/truetype/ttgload.c | 89 ++++++++++++++++++++++++++++++------------ src/truetype/ttgxvar.c | 6 +-- 3 files changed, 94 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52492cd1d..77766c41a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,34 @@ +2019-05-12 Werner Lemberg + + [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 [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. diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index d4a87ef09..0111c4053 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -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; diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 317340acb..eab423951 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -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 ) ) /**************************************************************************