Commit f43b3094ef9eec177caafdbc4e73a14be000d127

Werner Lemberg 2017-08-05T18:22:17

[base, truetype] New function `FT_Get_Var_Axis_Flags'. The reserved `flags' field got a value in OpenType version 1.8.2; unfortunately, the public `FT_Var_Axis' structure misses the corresponding element. Since we can't add a new field, we add an access function. * src/base/ftmm.c (FT_Get_Var_Axis_Flags): New function. * include/freetype/ftmm.h (FT_VAR_AXIS_FLAG_HIDDEN): New macro. Updated. * src/truetype/ttgxvar.c (TT_Get_MM_Var): Increase allocated memory of `mmvar' to hold axis flags. Fill the axis flags array. * docs/CHANGES: Updated.

diff --git a/ChangeLog b/ChangeLog
index 6243e18..30f18b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2017-08-05  Werner Lemberg  <wl@gnu.org>
+
+	[base, truetype] New function `FT_Get_Var_Axis_Flags'.
+
+	The reserved `flags' field got a value in OpenType version 1.8.2;
+	unfortunately, the public `FT_Var_Axis' structure misses the
+	corresponding element.  Since we can't add a new field, we add an
+	access function.
+
+	* src/base/ftmm.c (FT_Get_Var_Axis_Flags): New function.
+
+	* include/freetype/ftmm.h (FT_VAR_AXIS_FLAG_HIDDEN): New macro.
+	Updated.
+
+	* src/truetype/ttgxvar.c (TT_Get_MM_Var): Increase allocated memory
+	of `mmvar' to hold axis flags.
+	Fill the axis flags array.
+
+	* docs/CHANGES: Updated.
+
 2017-08-03  Nikolaus Waxweiler  <madigens@gmail.com>
 
 	[truetype] Fix metrics of B/W hinting in v40 mode.
diff --git a/docs/CHANGES b/docs/CHANGES
index cea3f27..a62aab7 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -12,6 +12,10 @@ CHANGES BETWEEN 2.8 and 2.8.1
 
   II. MISCELLANEOUS
 
+    - Using the  new function `FT_Get_Var_Axis_Flags',  an application
+      can access the `flags' field  of a variation axis (introduced in
+      OpenType version 1.8.2)
+
     - More sanity checks.
 
 
diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h
index b1bc1ed..b4c5941 100644
--- a/include/freetype/ftmm.h
+++ b/include/freetype/ftmm.h
@@ -196,7 +196,7 @@ FT_BEGIN_HEADER
   /*    FT_MM_Var                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure to model the axes and space of a Adobe MM, TrueType    */
+  /*    A structure to model the axes and space of an Adobe MM, TrueType   */
   /*    GX, or OpenType variation font.                                    */
   /*                                                                       */
   /*    Some fields are specific to one format and not to the others.      */
@@ -480,6 +480,50 @@ FT_BEGIN_HEADER
                                 FT_UInt    num_coords,
                                 FT_Fixed*  coords );
 
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Enum>                                                                */
+  /*    FT_VAR_AXIS_FLAG_XXX                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A list of bit flags used in the return value of                    */
+  /*    @FT_Get_Var_Axis_Flags.                                            */
+  /*                                                                       */
+  /* <Values>                                                              */
+  /*    FT_VAR_AXIS_FLAG_HIDDEN ::                                         */
+  /*      The variation axis should not be exposed to user interfaces.     */
+  /*                                                                       */
+#define FT_VAR_AXIS_FLAG_HIDDEN  1
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Var_Axis_Flags                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the `flags' field of an OpenType Variation Axis Record.        */
+  /*                                                                       */
+  /*    Not meaningful for Adobe MM fonts (`*flags' is always zero).       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    master     :: The variation descriptor.                            */
+  /*                                                                       */
+  /*    axis_index :: The index of the requested variation axis.           */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    flags      :: The `flags' field.  See @FT_VAR_AXIS_FLAG_XXX for    */
+  /*                  possible values.                                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_Var_Axis_Flags( FT_MM_Var*  master,
+                         FT_UInt     axis_index,
+                         FT_UInt*    flags );
+
   /* */
 
 
diff --git a/src/base/ftmm.c b/src/base/ftmm.c
index 2cb56a3..c845008 100644
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -402,4 +402,28 @@
   }
 
 
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Var_Axis_Flags( FT_MM_Var*  master,
+                         FT_UInt     axis_index,
+                         FT_UInt*    flags )
+  {
+    FT_UShort*  axis_flags;
+
+
+    if ( !master || !flags )
+      return FT_THROW( Invalid_Argument );
+
+    if ( axis_index >= master->num_axis )
+      return FT_THROW( Invalid_Argument );
+
+    /* the axis flags array immediately follows the data of `master' */
+    axis_flags = (FT_UShort*)&( master[1] );
+    *flags     = axis_flags[axis_index];
+
+    return FT_Err_Ok;
+  }
+
+
 /* END */
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 5a87df1..49aa53a 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -395,14 +395,14 @@
 
 
   /* some macros we need */
-  #define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
+#define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
 
-  #define FT_fdot14ToFixed( x )                \
-          ( (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_fdot14ToFixed( x )                \
+        ( (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 ) )
 
 
   static FT_Error
@@ -1956,6 +1956,7 @@
     GX_FVar_Head         fvar_head;
     FT_Bool              usePsName;
     FT_UInt              num_instances;
+    FT_UShort*           axis_flags;
 
     static const FT_Frame_Field  fvar_fields[] =
     {
@@ -2041,14 +2042,16 @@
       /* in fvar's table of named instances                       */
       num_instances = face->root.style_flags >> 16;
 
-      /* cannot overflow 32-bit arithmetic because of the size limits */
-      /* used in the `fvar' table validity check in `sfnt_init_face'  */
+      /* prepare storage area for MM data; this cannot overflow   */
+      /* 32-bit arithmetic because of the size limits used in the */
+      /* `fvar' table validity check in `sfnt_init_face'          */
       face->blend->mmvar_len =
         sizeof ( FT_MM_Var ) +
+        fvar_head.axisCount * sizeof ( FT_UShort ) +
         fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
         num_instances * sizeof ( FT_Var_Named_Style ) +
         num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) +
-        5 * fvar_head.axisCount;
+        fvar_head.axisCount * 5;
 
       if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
         goto Exit;
@@ -2065,8 +2068,12 @@
                                /* (or tuples, as called by Apple)         */
       mmvar->num_namedstyles =
         num_instances;
+
+      /* alas, no public field in `FT_Var_Axis' for axis flags */
+      axis_flags =
+        (FT_UShort*)&( mmvar[1] );
       mmvar->axis =
-        (FT_Var_Axis*)&( mmvar[1] );
+        (FT_Var_Axis*)&( axis_flags[fvar_head.axisCount] );
       mmvar->namedstyle =
         (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] );
 
@@ -2110,6 +2117,8 @@
         a->name[3] = (FT_String)( ( a->tag       ) & 0xFF );
         a->name[4] = '\0';
 
+        *axis_flags = axis_rec.flags;
+
         if ( a->minimum > a->def ||
              a->def > a->maximum )
         {
@@ -2121,13 +2130,17 @@
           a->maximum = a->def;
         }
 
-        FT_TRACE5(( "  \"%s\": minimum=%.5f, default=%.5f, maximum=%.5f\n",
+        FT_TRACE5(( "  \"%s\":"
+                    " minimum=%.5f, default=%.5f, maximum=%.5f,"
+                    " flags=0x%04X\n",
                     a->name,
                     a->minimum / 65536.0,
                     a->def / 65536.0,
-                    a->maximum / 65536.0 ));
+                    a->maximum / 65536.0,
+                    *axis_flags ));
 
         a++;
+        axis_flags++;
       }
 
       FT_TRACE5(( "\n" ));
@@ -2244,13 +2257,15 @@
         goto Exit;
       FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
 
+      axis_flags =
+        (FT_UShort*)&( mmvar[1] );
       mmvar->axis =
-        (FT_Var_Axis*)&( mmvar[1] );
+        (FT_Var_Axis*)&( axis_flags[mmvar->num_axis] );
       mmvar->namedstyle =
         (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] );
+
       next_coords =
         (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] );
-
       for ( n = 0; n < mmvar->num_namedstyles; n++ )
       {
         mmvar->namedstyle[n].coords  = next_coords;