[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
diff --git a/ChangeLog b/ChangeLog
index 52492cd..77766c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index d4a87ef..0111c40 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 317340a..eab4239 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 ) )
/**************************************************************************