From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Seigo Nonaka <nona@google.com>
Date: Tue, 2 May 2023 10:01:38 +0900
Subject: [PATCH] Cherrypick following three changes

[cherrypick 545bf3a27] [sfnt, truetype] Add `size_reset` to `MetricsVariations`.
[cherrypick daad10810] [truetype] tt_size_reset_height to take FT_Size
[cherrypick 51ad7b243] [services] FT_Size_Reset_Func to return FT_Error

Bug: 278221085
Test: TreeHugger
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9fe9411db4b7e715a39c0ccf48d1e0328f1d8e7c)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8d63b0bfcbaba361543fd9394b8d86907f52c97d)
Merged-In: I7e839b2a36e35c27974a82cc76e853996a7c7688
Change-Id: I7e839b2a36e35c27974a82cc76e853996a7c7688
---
 include/freetype/internal/services/svmetric.h | 10 ++-
 include/freetype/internal/tttypes.h           | 10 ++-
 src/cff/cffdrivr.c                            |  9 ++-
 src/cff/cffobjs.c                             |  6 +-
 src/sfnt/sfobjs.c                             | 14 ++--
 src/sfnt/ttmtx.c                              |  2 +-
 src/truetype/ttdriver.c                       |  7 +-
 src/truetype/ttgxvar.c                        | 23 ++++---
 src/truetype/ttobjs.c                         | 68 +++++++++++--------
 src/truetype/ttobjs.h                         |  6 +-
 10 files changed, 99 insertions(+), 56 deletions(-)

diff --git a/include/freetype/internal/services/svmetric.h b/include/freetype/internal/services/svmetric.h
index abaacddbb..c60b650fd 100644
--- a/include/freetype/internal/services/svmetric.h
+++ b/include/freetype/internal/services/svmetric.h
@@ -77,6 +77,9 @@ FT_BEGIN_HEADER
   typedef void
   (*FT_Metrics_Adjust_Func)( FT_Face  face );
 
+  typedef FT_Error
+  (*FT_Size_Reset_Func)( FT_Size  size );
+
 
   FT_DEFINE_SERVICE( MetricsVariations )
   {
@@ -90,6 +93,7 @@ FT_BEGIN_HEADER
     FT_VOrg_Adjust_Func      vorg_adjust;
 
     FT_Metrics_Adjust_Func   metrics_adjust;
+    FT_Size_Reset_Func       size_reset;
   };
 
 
@@ -103,7 +107,8 @@ FT_BEGIN_HEADER
                                                 tsb_adjust_,       \
                                                 bsb_adjust_,       \
                                                 vorg_adjust_,      \
-                                                metrics_adjust_  ) \
+                                                metrics_adjust_,   \
+                                                size_reset_      ) \
   static const FT_Service_MetricsVariationsRec  class_ =           \
   {                                                                \
     hadvance_adjust_,                                              \
@@ -113,7 +118,8 @@ FT_BEGIN_HEADER
     tsb_adjust_,                                                   \
     bsb_adjust_,                                                   \
     vorg_adjust_,                                                  \
-    metrics_adjust_                                                \
+    metrics_adjust_,                                                \
+    size_reset_                                                    \
   };
 
 #else /* FT_CONFIG_OPTION_PIC */
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 10dd336a8..422a680de 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1437,8 +1437,14 @@ FT_BEGIN_HEADER
     void*                 mm;
 
     /* a typeless pointer to the FT_Service_MetricsVariationsRec table */
-    /* used to handle the HVAR, VVAR, and MVAR OpenType tables         */
-    void*                 var;
+    /* used to handle the HVAR, VVAR, and MVAR OpenType tables by the  */
+    /* "truetype" driver                                               */
+    void*                 tt_var;
+
+    /* a typeless pointer to the FT_Service_MetricsVariationsRec table */
+    /* used to handle the HVAR, VVAR, and MVAR OpenType tables by this */
+    /* TT_Face's driver                                                */
+    void*                 face_var;
 #endif
 
     /* a typeless pointer to the PostScript Aux service */
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index df896848d..7f809bf88 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -933,7 +933,8 @@
                        FT_UInt   gindex,
                        FT_Int   *avalue )
   {
-    FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
+    FT_Service_MetricsVariations
+      var = (FT_Service_MetricsVariations)face->tt_var;
 
 
     return var->hadvance_adjust( FT_FACE( face ), gindex, avalue );
@@ -943,7 +944,8 @@
   static void
   cff_metrics_adjust( CFF_Face  face )
   {
-    FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
+    FT_Service_MetricsVariations
+      var = (FT_Service_MetricsVariations)face->tt_var;
 
 
     var->metrics_adjust( FT_FACE( face ) );
@@ -962,7 +964,8 @@
     (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
     (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
 
-    (FT_Metrics_Adjust_Func) cff_metrics_adjust      /* metrics_adjust  */
+    (FT_Metrics_Adjust_Func) cff_metrics_adjust,     /* metrics_adjust  */
+    (FT_Size_Reset_Func)     NULL                    /* size_reset      */
   )
 #endif
 
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index a2d7aec65..30e68a104 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -710,8 +710,10 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       {
-        FT_Service_MultiMasters       mm  = (FT_Service_MultiMasters)face->mm;
-        FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
+        FT_Service_MultiMasters
+          mm = (FT_Service_MultiMasters)face->mm;
+        FT_Service_MetricsVariations
+          var = (FT_Service_MetricsVariations)face->face_var;
 
         FT_UInt  instance_index = (FT_UInt)face_index >> 16;
 
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 0c917030f..b0547ea70 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -896,17 +896,23 @@
                                         0 );
     }
 
-    if ( !face->var )
+    if ( !face->tt_var )
     {
       /* we want the metrics variations interface */
       /* from the `truetype' module only          */
       FT_Module  tt_module = FT_Get_Module( library, "truetype" );
 
 
-      face->var = ft_module_get_service( tt_module,
-                                         FT_SERVICE_ID_METRICS_VARIATIONS,
-                                         0 );
+      face->tt_var = ft_module_get_service( tt_module,
+                                            FT_SERVICE_ID_METRICS_VARIATIONS,
+                                            0 );
     }
+
+    if ( !face->face_var )
+      face->face_var = ft_module_get_service(
+                         &face->root.driver->root,
+                         FT_SERVICE_ID_METRICS_VARIATIONS,
+                         0 );
 #endif
 
     FT_TRACE2(( "SFNT driver\n" ));
diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index 6ddda95b5..0215ac8b2 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -229,7 +229,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_Service_MetricsVariations  var =
-      (FT_Service_MetricsVariations)face->var;
+      (FT_Service_MetricsVariations)face->tt_var;
 #endif
 
 
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 820cafbb8..757f3d205 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -304,7 +304,7 @@
       /* use the scaled metrics, even when tt_size_reset fails */
       FT_Select_Metrics( size->face, strike_index );
 
-      tt_size_reset( ttsize, 0 ); /* ignore return value */
+      tt_size_reset( ttsize ); /* ignore return value */
     }
     else
     {
@@ -356,7 +356,7 @@
 
     if ( FT_IS_SCALABLE( size->face ) )
     {
-      error = tt_size_reset( ttsize, 0 );
+      error = tt_size_reset( ttsize );
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
       /* for the `MPS' bytecode instruction we need the point size */
@@ -516,7 +516,8 @@
     (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
     (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
 
-    (FT_Metrics_Adjust_Func) tt_apply_mvar           /* metrics_adjust  */
+    (FT_Metrics_Adjust_Func) tt_apply_mvar,          /* metrics_adjust  */
+    (FT_Size_Reset_Func)     tt_size_reset_height    /* size_reset      */
   )
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index b3e9ec7d9..fc22229de 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -1283,15 +1283,14 @@
 
 
   static FT_Error
-  tt_size_reset_iterator( FT_ListNode  node,
+  ft_size_reset_iterator( FT_ListNode  node,
                           void*        user )
   {
-    TT_Size  size = (TT_Size)node->data;
+    FT_Size                       size = (FT_Size)node->data;
+    FT_Service_MetricsVariations  var  = (FT_Service_MetricsVariations)user;
 
-    FT_UNUSED( user );
 
-
-    tt_size_reset( size, 1 );
+    var->size_reset( size );
 
     return FT_Err_Ok;
   }
@@ -1352,6 +1351,9 @@
 
     /* adjust all derived values */
     {
+      FT_Service_MetricsVariations  var =
+        (FT_Service_MetricsVariations)face->face_var;
+
       FT_Face  root = &face->root;
 
 
@@ -1378,11 +1380,12 @@
                                   face->postscript.underlineThickness / 2;
       root->underline_thickness = face->postscript.underlineThickness;
 
-      /* iterate over all FT_Size objects and call `tt_size_reset' */
-      /* to propagate the metrics changes                          */
-      FT_List_Iterate( &root->sizes_list,
-                       tt_size_reset_iterator,
-                       NULL );
+      /* iterate over all FT_Size objects and call `var->size_reset' */
+      /* to propagate the metrics changes                            */
+      if ( var && var->size_reset )
+        FT_List_Iterate( &root->sizes_list,
+                         ft_size_reset_iterator,
+                         (void*)var );
     }
   }
 
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index bc8086f25..f7f9b2527 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -1234,37 +1234,29 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    tt_size_reset                                                      */
+  /*   tt_size_reset_height                                                */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Reset a TrueType size when resolutions and character dimensions    */
-  /*    have been changed.                                                 */
+  /*   Recompute a TrueType size's ascender, descender, and height         */
+  /*   when resolutions and character dimensions have been changed.        */
+  /*   Used for variation fonts as an iterator function.                   */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    size        :: A handle to the target size object.                 */
-  /*                                                                       */
-  /*    only_height :: Only recompute ascender, descender, and height;     */
-  /*                   this flag is used for variation fonts where         */
-  /*                   `tt_size_reset' is used as an iterator function.    */
+  /*   ft_size ::                                                          */
+  /*     A handle to the target TT_Size object. This function will be called*/
+  /*     through a `FT_Size_Reset_Func` pointer which takes `FT_Size`. This*/
+  /*     function must take `FT_Size` as a result. The passed `FT_Size` is */
+  /*     expected to point to a `TT_Size`.                                 */
   /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
-  tt_size_reset( TT_Size  size,
-                 FT_Bool  only_height )
+  tt_size_reset_height( FT_Size  ft_size )
   {
-    TT_Face           face;
-    FT_Size_Metrics*  size_metrics;
-
-
-    face = (TT_Face)size->root.face;
-
-    /* nothing to do for CFF2 */
-    if ( face->is_cff2 )
-      return FT_Err_Ok;
+    TT_Size           size         = (TT_Size)ft_size;
+    TT_Face           face         = (TT_Face)size->root.face;
+    FT_Size_Metrics*  size_metrics = &size->hinted_metrics;
 
     size->ttmetrics.valid = FALSE;
 
-    size_metrics = &size->hinted_metrics;
-
     /* copy the result from base layer */
     *size_metrics = size->root.metrics;
 
@@ -1291,12 +1283,34 @@
 
     size->ttmetrics.valid = TRUE;
 
-    if ( only_height )
-    {
-      /* we must not recompute the scaling values here since       */
-      /* `tt_size_reset' was already called (with only_height = 0) */
-      return FT_Err_Ok;
-    }
+    return FT_Err_Ok;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   tt_size_reset
+   *
+   * @Description:
+   *   Reset a TrueType size when resolutions and character dimensions
+   *   have been changed.
+   *
+   * @Input:
+   *   size ::
+   *     A handle to the target size object.
+   */
+  FT_LOCAL_DEF( FT_Error )
+  tt_size_reset( TT_Size  size )
+  {
+    FT_Error          error;
+    TT_Face           face         = (TT_Face)size->root.face;
+    FT_Size_Metrics*  size_metrics = &size->hinted_metrics;
+
+
+    error = tt_size_reset_height( (FT_Size)size );
+    if ( error )
+      return error;
 
     if ( face->header.Flags & 8 )
     {
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 38fa30e4e..703328167 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -390,8 +390,10 @@ FT_BEGIN_HEADER
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
   FT_LOCAL( FT_Error )
-  tt_size_reset( TT_Size  size,
-                 FT_Bool  only_height );
+  tt_size_reset_height( FT_Size  size );
+
+  FT_LOCAL( FT_Error )
+  tt_size_reset( TT_Size  size );
 
 
   /*************************************************************************/
