ref: 64a91137f13fbc11b6bac393be978d191eee7633
parent: 57a6733dcf7828fe3db9254edab33fda7c9f6a10
author: Werner Lemberg <[email protected]>
date: Wed Dec 21 14:30:33 EST 2016
[truetype, sfnt] Introduce font variation flags to `TT_Face'. * include/freetype/internal/tttypes.h (TT_FACE_FLAG_VAR_XXX): New macros describing available functionality of various OpenType tables related to font variation. (TT_Face): New fields `variation_support' and `mvar_support', replacing and extending `use_fvar'. * src/sfnt/sfobjs.c (sfnt_init_face, sfnt_load_face): Use `variation_support'. * src/truetype/ttgxvar.c (ft_var_load_hvar): Set `variation_support' field. (TT_Vary_Apply_Glyph_Deltas): Updated.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2016-12-21 Werner Lemberg <[email protected]>
+ [truetype, sfnt] Introduce font variation flags to `TT_Face'.
+
+ * include/freetype/internal/tttypes.h (TT_FACE_FLAG_VAR_XXX):
+ New macros describing available functionality of various OpenType
+ tables related to font variation.
+ (TT_Face): New fields `variation_support' and `mvar_support',
+ replacing and extending `use_fvar'.
+
+ * src/sfnt/sfobjs.c (sfnt_init_face, sfnt_load_face): Use
+ `variation_support'.
+
+ * src/truetype/ttgxvar.c (ft_var_load_hvar): Set `variation_support'
+ field.
+ (TT_Vary_Apply_Glyph_Deltas): Updated.
+
+2016-12-21 Werner Lemberg <[email protected]>
+
[base] Improve sanity check for Mac resources (#49888).
* src/base/ftobjs.c (Mac_Read_sfnt_Resource): Abort if `rlen' is not
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1060,6 +1060,75 @@
} TT_SbitTableType;
+ /* OpenType 1.8 brings new tables for variation font support; */
+ /* to make the old MM and GX fonts still work we need to check */
+ /* the presence (and validity) of the functionality provided */
+ /* by those tables. The following flag macros are for the */
+ /* field `variation_support'. */
+ /* */
+ /* Note that `fvar' gets checked immediately at font loading, */
+ /* while the other features are only loaded if MM support is */
+ /* actually requested. */
+
+ /* FVAR */
+#define TT_FACE_FLAG_VAR_FVAR ( 1 << 0 )
+
+ /* HVAR */
+#define TT_FACE_FLAG_VAR_HADVANCE ( 1 << 1 )
+#define TT_FACE_FLAG_VAR_LSB ( 1 << 2 )
+#define TT_FACE_FLAG_VAR_RSB ( 1 << 3 )
+
+ /* VVAR */
+#define TT_FACE_FLAG_VAR_VADVANCE ( 1 << 4 )
+#define TT_FACE_FLAG_VAR_TSB ( 1 << 5 )
+#define TT_FACE_FLAG_VAR_BSB ( 1 << 6 )
+#define TT_FACE_FLAG_VAR_VORG ( 1 << 7 )
+
+ /* MVAR gasp data */
+#define TT_FACE_FLAG_VAR_GASP_0 ( 1 << 20 )
+#define TT_FACE_FLAG_VAR_GASP_1 ( 1 << 21 )
+#define TT_FACE_FLAG_VAR_GASP_2 ( 1 << 22 )
+#define TT_FACE_FLAG_VAR_GASP_3 ( 1 << 23 )
+#define TT_FACE_FLAG_VAR_GASP_4 ( 1 << 24 )
+#define TT_FACE_FLAG_VAR_GASP_5 ( 1 << 25 )
+#define TT_FACE_FLAG_VAR_GASP_6 ( 1 << 26 )
+#define TT_FACE_FLAG_VAR_GASP_7 ( 1 << 27 )
+#define TT_FACE_FLAG_VAR_GASP_8 ( 1 << 28 )
+#define TT_FACE_FLAG_VAR_GASP_9 ( 1 << 29 )
+
+ /* The following flag macros are for the field `mvar_support'. */
+
+ /* remaining MVAR data */
+#define TT_FACE_FLAG_VAR_CPHT ( 1 << 0 )
+#define TT_FACE_FLAG_VAR_HASC ( 1 << 1 )
+#define TT_FACE_FLAG_VAR_HCLA ( 1 << 2 )
+#define TT_FACE_FLAG_VAR_HCLD ( 1 << 3 )
+#define TT_FACE_FLAG_VAR_HCOF ( 1 << 4 )
+#define TT_FACE_FLAG_VAR_HCRN ( 1 << 5 )
+#define TT_FACE_FLAG_VAR_HCRS ( 1 << 6 )
+#define TT_FACE_FLAG_VAR_HDSC ( 1 << 7 )
+#define TT_FACE_FLAG_VAR_HLGP ( 1 << 8 )
+#define TT_FACE_FLAG_VAR_SBXO ( 1 << 9 )
+#define TT_FACE_FLAG_VAR_SBXS ( 1 << 10 )
+#define TT_FACE_FLAG_VAR_SBYO ( 1 << 11 )
+#define TT_FACE_FLAG_VAR_SBYS ( 1 << 12 )
+#define TT_FACE_FLAG_VAR_SPXO ( 1 << 13 )
+#define TT_FACE_FLAG_VAR_SPXS ( 1 << 14 )
+#define TT_FACE_FLAG_VAR_SPYO ( 1 << 15 )
+#define TT_FACE_FLAG_VAR_SPYS ( 1 << 16 )
+#define TT_FACE_FLAG_VAR_STRO ( 1 << 17 )
+#define TT_FACE_FLAG_VAR_STRS ( 1 << 18 )
+#define TT_FACE_FLAG_VAR_UNDO ( 1 << 19 )
+#define TT_FACE_FLAG_VAR_UNDS ( 1 << 20 )
+#define TT_FACE_FLAG_VAR_VASC ( 1 << 21 )
+#define TT_FACE_FLAG_VAR_VCOF ( 1 << 22 )
+#define TT_FACE_FLAG_VAR_VCRN ( 1 << 23 )
+#define TT_FACE_FLAG_VAR_VCRS ( 1 << 24 )
+#define TT_FACE_FLAG_VAR_VDSC ( 1 << 25 )
+#define TT_FACE_FLAG_VAR_VLGP ( 1 << 26 )
+#define TT_FACE_FLAG_VAR_XHGT ( 1 << 27 )
+
+
/*************************************************************************/
/* */
/* TrueType Face Type */
@@ -1237,9 +1306,15 @@
/* unmodified (i.e., without applying glyph */
/* variation deltas). */
/* */
- /* use_fvar :: Set if the `fvar' table header is valid, */
- /* and we have at least one design axis. */
+ /* variation_support :: Flags that indicate which OpenType */
+ /* functionality related to font variation */
+ /* support is present, valid, and usable. */
+ /* For example, TT_FACE_FLAG_VAR_FVAR is only */
+ /* set if we have at least one design axis. */
/* */
+ /* mvar_support :: Flags that indicate which metrics */
+ /* variations are supported. */
+ /* */
/* horz_metrics_size :: The size of the `hmtx' table. */
/* */
/* vert_metrics_size :: The size of the `vmtx' table. */
@@ -1432,7 +1507,8 @@
GX_Blend blend;
FT_Bool is_default_instance; /* since 2.7.1 */
- FT_Bool use_fvar; /* since 2.7.1 */
+ FT_UInt32 variation_support; /* since 2.7.1 */
+ FT_UInt32 mvar_support; /* since 2.7.1 */
#endif
/* since version 2.2 */
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -981,12 +981,9 @@
offset +
axis_size * num_axes +
instance_size * num_instances > fvar_len )
- {
- num_instances = 0;
- face->use_fvar = 0;
- }
+ num_instances = 0;
else
- face->use_fvar = 1;
+ face->variation_support |= TT_FACE_FLAG_VAR_FVAR;
/* we don't support Multiple Master CFFs yet */
if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) )
@@ -1368,7 +1365,7 @@
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
/* Don't bother to load the tables unless somebody asks for them. */
/* No need to do work which will (probably) not be used. */
- if ( face->use_fvar )
+ if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
{
if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
tt_face_lookup_table( face, TTAG_gvar ) != 0 )
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -742,8 +742,13 @@
FT_FREE( dataOffsetArray );
if ( !error )
+ {
blend->hvar_checked = TRUE;
+ /* TODO: implement other HVAR stuff */
+ face->variation_support |= TT_FACE_FLAG_VAR_HADVANCE;
+ }
+
return error;
}
@@ -796,6 +801,9 @@
goto Exit;
}
+ /* advance width adjustments are always present in an `HVAR' table, */
+ /* so need to test for this capability */
+
if ( gindex >= face->blend->hvar_table->widthMap.mapCount )
{
FT_TRACE2(( "gindex %d out of range\n", gindex ));
@@ -2608,14 +2616,22 @@
FT_Pos delta_y = FT_MulFix( deltas_y[j], apply );
- /* Experimental fix for double adjustment of advance width: */
- /* adjust phantom point 2 only if there's no HVAR. */
- /* */
- /* TODO: handle LSB (pp1) and VVAR (pp3, pp4) too */
- if ( j != ( n_points - 3 ) || blend->hvar_checked == FALSE )
+ /* To avoid double adjustment of advance width or height, */
+ /* adjust phantom points only if there is no HVAR or VVAR */
+ /* table, respectively. */
+ if ( j != ( n_points - 3 ) ||
+ !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
outline->points[j].x += delta_x;
+ if ( j != ( n_points - 2 ) ||
+ !( face->variation_support & TT_FACE_FLAG_VAR_LSB ) )
+ outline->points[j].x += delta_x;
- outline->points[j].y += delta_y;
+ if ( j != ( n_points - 1 ) ||
+ !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+ outline->points[j].y += delta_y;
+ if ( j != ( n_points - 0 ) ||
+ !( face->variation_support & TT_FACE_FLAG_VAR_TSB ) )
+ outline->points[j].y += delta_y;
#ifdef FT_DEBUG_LEVEL_TRACE
if ( delta_x || delta_y )