Commit e5e3556fa28c0ec00ca9260de1552ec4b9c12d55

Werner Lemberg 2016-12-27T06:49:37

[truetype, type1] Implement `FT_Get_Var_Design_Coordinates'. * src/truetype/ttgxvar.c (TT_Get_Var_Design): Implement. (TT_Set_Var_Design): Fix tracing. * src/type1/t1load.c (T1_Get_Var_Design): Implement.

diff --git a/ChangeLog b/ChangeLog
index d8f446b..c6a336f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-12-27  Werner Lemberg  <wl@gnu.org>
+
+	[truetype, type1] Implement `FT_Get_Var_Design_Coordinates'.
+
+	* src/truetype/ttgxvar.c (TT_Get_Var_Design): Implement.
+	(TT_Set_Var_Design): Fix tracing.
+
+	* src/type1/t1load.c (T1_Get_Var_Design): Implement.
+
 2016-12-24  Werner Lemberg  <wl@gnu.org>
 
 	* src/truetype/ttpload.c (tt_face_load_hdmx): Ignore `version'.
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index e0ae12f..81c4634 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -1800,7 +1800,7 @@
       num_coords = mmvar->num_axis;
     }
 
-    /* Axis normalization is a two stage process.  First we normalize */
+    /* Axis normalization is a two-stage process.  First we normalize */
     /* based on the [min,def,max] values for the axis to be [-1,0,1]. */
     /* Then, if there's an `avar' table, we renormalize this range.   */
 
@@ -1859,9 +1859,10 @@
       {
         for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
         {
-          FT_TRACE5(( "  %.4f\n", normalized[i] / 65536.0 ));
           if ( normalized[i] < av->correspondence[j].fromCoord )
           {
+            FT_TRACE5(( "  %.4f\n", normalized[i] / 65536.0 ));
+
             normalized[i] =
               FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
                          av->correspondence[j].toCoord -
@@ -1883,17 +1884,112 @@
   }
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_Var_Design                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the design coordinates of the currently selected interpolated  */
+  /*    font.                                                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face       :: A handle to the source face.                         */
+  /*                                                                       */
+  /*    num_coords :: The number of design coordinates to retrieve.  If it */
+  /*                  is larger than the number of axes, set the excess    */
+  /*                  values to~0.                                         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    coords     :: The design coordinates array.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
   TT_Get_Var_Design( TT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
-    FT_UNUSED( face );
-    FT_UNUSED( num_coords );
-    FT_UNUSED( coords );
+    FT_Error  error = FT_Err_Ok;
+
+    GX_Blend      blend;
+    FT_MM_Var*    mmvar;
+    FT_Var_Axis*  a;
+
+    FT_UInt  i, j, nc;
+
+
+    if ( !face->blend )
+    {
+      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
+        return error;
+    }
+
+    blend = face->blend;
+
+    nc = num_coords;
+    if ( num_coords > blend->num_axis )
+    {
+      FT_TRACE2(( "TT_Get_MM_Blend: only using first %d of %d coordinates\n",
+                  blend->num_axis, num_coords ));
+      nc = blend->num_axis;
+    }
 
-    /* TODO: Implement this function. */
-    return FT_THROW( Unimplemented_Feature );
+    for ( i = 0; i < nc; ++i )
+      coords[i] = blend->normalizedcoords[i];
+
+    for ( ; i < num_coords; i++ )
+      coords[i] = 0;
+
+    if ( !blend->avar_checked )
+      ft_var_load_avar( face );
+
+    if ( blend->avar_segment )
+    {
+      GX_AVarSegment  av = blend->avar_segment;
+
+
+      FT_TRACE5(( "normalized design coordinates"
+                  " after removing `avar' distortion:\n" ));
+
+      for ( i = 0; i < nc; i++, av++ )
+      {
+        for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
+        {
+          if ( coords[i] < av->correspondence[j].toCoord )
+          {
+            coords[i] =
+              FT_MulDiv( coords[i] - av->correspondence[j - 1].toCoord,
+                         av->correspondence[j].fromCoord -
+                           av->correspondence[j - 1].fromCoord,
+                         av->correspondence[j].toCoord -
+                           av->correspondence[j - 1].toCoord ) +
+              av->correspondence[j - 1].fromCoord;
+
+            FT_TRACE5(( "  %.4f\n", coords[i] / 65536.0 ));
+            break;
+          }
+        }
+      }
+    }
+
+    mmvar = blend->mmvar;
+    a     = mmvar->axis;
+
+    for ( i = 0; i < nc; i++, a++ )
+    {
+      if ( coords[i] < 0 )
+        coords[i] = a->def + FT_MulFix( coords[i],
+                                        a->def - a->minimum );
+      else if ( coords[i] > 0 )
+        coords[i] = a->def + FT_MulFix( coords[i],
+                                        a->maximum - a->def );
+      else
+        coords[i] = a->def;
+    }
+
+    return FT_Err_Ok;
   }
 
 
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 9838ba0..f6b43dc 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -551,12 +551,34 @@
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
-    FT_UNUSED( face );
-    FT_UNUSED( num_coords );
-    FT_UNUSED( coords );
+    PS_Blend  blend = face->blend;
+
+    FT_Fixed  axiscoords[4];
+    FT_UInt   i, nc;
+
+
+    if ( !blend )
+      return FT_THROW( Invalid_Argument );
+
+    mm_weights_unmap( blend->weight_vector,
+                      axiscoords,
+                      blend->num_axis );
+
+    nc = num_coords;
+    if ( num_coords > blend->num_axis )
+    {
+      FT_TRACE2(( "T1_Get_Var_Design:"
+                  " only using first %d of %d coordinates\n",
+                  blend->num_axis, num_coords ));
+      nc = blend->num_axis;
+    }
+
+    for ( i = 0; i < nc; i++ )
+      coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] );
+    for ( ; i < num_coords; i++ )
+      coords[i] = 0;
 
-    /* TODO: Implement this function. */
-    return FT_THROW( Unimplemented_Feature );
+    return FT_Err_Ok;
   }