[psaux] Performance improvements (#43248).

Implement proper disabling of hinting procedures when not hinting. This
results in a ~30% speedup.

* src/psaux/pshints.h (CF2_HintData): Gather hintmaps into hinting context.
* src/psaux/pshints.c: Do not allocate structs unless needed.
Skip hintmap funcs calls.
Update references.

* src/psaux/psintrp.c (cf2_interpT2CharString): Initialization for hinting
context.
<cntrmask, hintmask>: Ignore if not hinting.
Update references.
diff --git a/src/psaux/pshints.c b/src/psaux/pshints.c
index cf40bc0..97773d4 100644
--- a/src/psaux/pshints.c
+++ b/src/psaux/pshints.c
@@ -814,6 +814,9 @@
     FT_Byte  maskByte;
 
 
+    if ( !hintmap )
+      return;
+
     /* check whether initial map is constructed */
     if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) )
     {
@@ -1072,6 +1075,7 @@
                       /* CF2_Fixed  hShift, */
                       CF2_ArrStack          hStemHintArray,
                       CF2_ArrStack          vStemHintArray,
+                      CF2_HintData          hintData,
                       CF2_HintMask          hintMask,
                       CF2_Fixed             hintOriginY,
                       const CF2_Blues       blues,
@@ -1082,26 +1086,34 @@
     glyphpath->font      = font;
     glyphpath->callbacks = callbacks;
 
-    cf2_arrstack_init( &glyphpath->hintMoves,
-                       font->memory,
-                       &font->error,
-                       sizeof ( CF2_HintMoveRec ) );
+    if ( font->hinted )
+    {
+      cf2_arrstack_init( &hintData->hintMoves,
+                         font->memory,
+                         &font->error,
+                         sizeof ( CF2_HintMoveRec ) );
 
-    cf2_hintmap_init( &glyphpath->initialHintMap,
-                      font,
-                      &glyphpath->initialHintMap,
-                      &glyphpath->hintMoves,
-                      scaleY );
-    cf2_hintmap_init( &glyphpath->firstHintMap,
-                      font,
-                      &glyphpath->initialHintMap,
-                      &glyphpath->hintMoves,
-                      scaleY );
-    cf2_hintmap_init( &glyphpath->hintMap,
-                      font,
-                      &glyphpath->initialHintMap,
-                      &glyphpath->hintMoves,
-                      scaleY );
+      cf2_hintmap_init( &hintData->initialHintMap,
+                        font,
+                        &hintData->initialHintMap,
+                        &hintData->hintMoves,
+                        scaleY );
+      cf2_hintmap_init( &hintData->firstHintMap,
+                        font,
+                        &hintData->initialHintMap,
+                        &hintData->hintMoves,
+                        scaleY );
+      cf2_hintmap_init( &hintData->hintMap,
+                        font,
+                        &hintData->initialHintMap,
+                        &hintData->hintMoves,
+                        scaleY );
+
+      glyphpath->hintMap        = &hintData->hintMap;
+      glyphpath->firstHintMap   = &hintData->firstHintMap;
+      glyphpath->initialHintMap = &hintData->initialHintMap;
+      glyphpath->hintMoves      = &hintData->hintMoves;
+    }
 
     glyphpath->scaleX = font->innerTransform.a;
     glyphpath->scaleC = font->innerTransform.c;
@@ -1138,7 +1150,8 @@
   FT_LOCAL_DEF( void )
   cf2_glyphpath_finalize( CF2_GlyphPath  glyphpath )
   {
-    cf2_arrstack_finalize( &glyphpath->hintMoves );
+    if ( glyphpath->font->hinted )
+      cf2_arrstack_finalize( glyphpath->hintMoves );
   }
 
 
@@ -1160,7 +1173,9 @@
 
     pt.x = ADD_INT32( FT_MulFix( glyphpath->scaleX, x ),
                       FT_MulFix( glyphpath->scaleC, y ) );
-    pt.y = cf2_hintmap_map( hintmap, y );
+    pt.y = hintmap ? cf2_hintmap_map( hintmap, y )
+                   : FT_MulFix( glyphpath->scaleY, y );
+
 
     ppt->x = ADD_INT32(
                FT_MulFix( glyphpath->font->outerTransform.a, pt.x ),
@@ -1366,7 +1381,7 @@
       {
         /* use first hint map if closing */
         cf2_glyphpath_hintPoint( glyphpath,
-                                 &glyphpath->firstHintMap,
+                                 glyphpath->firstHintMap,
                                  &params.pt1,
                                  glyphpath->prevElemP1.x,
                                  glyphpath->prevElemP1.y );
@@ -1428,7 +1443,7 @@
         /* if we are closing the subpath, then nextP0 is in the first     */
         /* hint zone                                                      */
         cf2_glyphpath_hintPoint( glyphpath,
-                                 &glyphpath->firstHintMap,
+                                 glyphpath->firstHintMap,
                                  &params.pt1,
                                  nextP0->x,
                                  nextP0->y );
@@ -1478,7 +1493,8 @@
 
     /* Test if move has really happened yet; it would have called */
     /* `cf2_hintmap_build' to set `isValid'.                   */
-    if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) )
+    if ( glyphpath->font->hinted                   &&
+         !cf2_hintmap_isValid( glyphpath->hintMap ) )
     {
       /* we are here iff first subpath is missing a moveto operator: */
       /* synthesize first moveTo to finish initialization of hintMap */
@@ -1488,7 +1504,7 @@
     }
 
     cf2_glyphpath_hintPoint( glyphpath,
-                             &glyphpath->hintMap,
+                             glyphpath->hintMap,
                              &params.pt1,
                              start.x,
                              start.y );
@@ -1677,18 +1693,21 @@
 
     glyphpath->moveIsPending = TRUE;
 
-    /* ensure we have a valid map with current mask */
-    if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ||
-         cf2_hintmask_isNew( glyphpath->hintMask )   )
-      cf2_hintmap_build( &glyphpath->hintMap,
-                         glyphpath->hStemHintArray,
-                         glyphpath->vStemHintArray,
-                         glyphpath->hintMask,
-                         glyphpath->hintOriginY,
-                         FALSE );
+    /* ensure we have a valid map with current mask, if hinting is on */
+    if ( glyphpath->font->hinted )
+    {
+      if ( !cf2_hintmap_isValid( glyphpath->hintMap ) ||
+           cf2_hintmask_isNew( glyphpath->hintMask )  )
+        cf2_hintmap_build( glyphpath->hintMap,
+                           glyphpath->hStemHintArray,
+                           glyphpath->vStemHintArray,
+                           glyphpath->hintMask,
+                           glyphpath->hintOriginY,
+                           FALSE );
 
-    /* save a copy of current HintMap to use when drawing initial point */
-    glyphpath->firstHintMap = glyphpath->hintMap;     /* structure copy */
+      /* save a copy of current HintMap to use when drawing initial point */
+      *glyphpath->firstHintMap = *glyphpath->hintMap;     /* structure copy */
+    }
   }
 
 
@@ -1768,11 +1787,12 @@
 
     if ( glyphpath->elemIsQueued )
     {
-      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
-                 glyphpath->hintMap.count == 0              );
+      FT_ASSERT( !glyphpath->font->hinted                  ||
+                 cf2_hintmap_isValid( glyphpath->hintMap ) ||
+                 glyphpath->hintMap->count == 0             );
 
       cf2_glyphpath_pushPrevElem( glyphpath,
-                                  &glyphpath->hintMap,
+                                  glyphpath->hintMap,
                                   &P0,
                                   P1,
                                   FALSE );
@@ -1786,7 +1806,7 @@
 
     /* update current map */
     if ( newHintMap )
-      cf2_hintmap_build( &glyphpath->hintMap,
+      cf2_hintmap_build( glyphpath->hintMap,
                          glyphpath->hStemHintArray,
                          glyphpath->vStemHintArray,
                          glyphpath->hintMask,
@@ -1856,11 +1876,12 @@
 
     if ( glyphpath->elemIsQueued )
     {
-      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
-                 glyphpath->hintMap.count == 0              );
+      FT_ASSERT( !glyphpath->font->hinted                  ||
+                 cf2_hintmap_isValid( glyphpath->hintMap ) ||
+                 glyphpath->hintMap->count == 0             );
 
       cf2_glyphpath_pushPrevElem( glyphpath,
-                                  &glyphpath->hintMap,
+                                  glyphpath->hintMap,
                                   &P0,
                                   P1,
                                   FALSE );
@@ -1876,7 +1897,7 @@
 
     /* update current map */
     if ( cf2_hintmask_isNew( glyphpath->hintMask ) )
-      cf2_hintmap_build( &glyphpath->hintMap,
+      cf2_hintmap_build( glyphpath->hintMap,
                          glyphpath->hStemHintArray,
                          glyphpath->vStemHintArray,
                          glyphpath->hintMask,
@@ -1907,7 +1928,7 @@
       /* empty the final element from the queue and close the path */
       if ( glyphpath->elemIsQueued )
         cf2_glyphpath_pushPrevElem( glyphpath,
-                                    &glyphpath->hintMap,
+                                    glyphpath->hintMap,
                                     &glyphpath->offsetStart0,
                                     glyphpath->offsetStart1,
                                     TRUE );
diff --git a/src/psaux/pshints.h b/src/psaux/pshints.h
index 02fdc53..e56afba 100644
--- a/src/psaux/pshints.h
+++ b/src/psaux/pshints.h
@@ -173,6 +173,16 @@
                      FT_Bool       initialMap );
 
 
+  typedef struct  CF2_HintDataRec_
+  {
+    CF2_HintMapRec  hintMap;        /* current hint map            */
+    CF2_HintMapRec  firstHintMap;   /* saved copy                  */
+    CF2_HintMapRec  initialHintMap; /* based on all captured hints */
+
+    CF2_ArrStackRec  hintMoves;  /* list of hint moves for 2nd pass */
+
+  } CF2_HintDataRec, *CF2_HintData;
+
   /*
    * GlyphPath is a wrapper for drawing operations that scales the
    * coordinates according to the render matrix and HintMap.  It also tracks
@@ -181,17 +191,15 @@
    */
   typedef struct  CF2_GlyphPathRec_
   {
-    /* TODO: gather some of these into a hinting context */
-
     CF2_Font              font;           /* font instance    */
     CF2_OutlineCallbacks  callbacks;      /* outline consumer */
 
 
-    CF2_HintMapRec  hintMap;        /* current hint map            */
-    CF2_HintMapRec  firstHintMap;   /* saved copy                  */
-    CF2_HintMapRec  initialHintMap; /* based on all captured hints */
+    CF2_HintMap  hintMap;        /* ptr to current hint map     */
+    CF2_HintMap  firstHintMap;   /* ptr to saved copy           */
+    CF2_HintMap  initialHintMap; /* based on all captured hints */
 
-    CF2_ArrStackRec  hintMoves;  /* list of hint moves for 2nd pass */
+    CF2_ArrStack  hintMoves;  /* list of hint moves for 2nd pass */
 
     CF2_Fixed  scaleX;         /* matrix a */
     CF2_Fixed  scaleC;         /* matrix c */
@@ -253,6 +261,7 @@
                       /* CF2_Fixed hShift, */
                       CF2_ArrStack          hStemHintArray,
                       CF2_ArrStack          vStemHintArray,
+                      CF2_HintData          hintData,
                       CF2_HintMask          hintMask,
                       CF2_Fixed             hintOrigin,
                       const CF2_Blues       blues,
diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c
index 61fc8f8..538d589 100644
--- a/src/psaux/psintrp.c
+++ b/src/psaux/psintrp.c
@@ -524,9 +524,9 @@
     CF2_ArrStackRec  vStemHintArray;
 
     CF2_HintMaskRec   hintMask;
+    CF2_HintDataRec   hintData;
     CF2_GlyphPathRec  glyphPath;
 
-
     FT_ZERO( &storage );
     FT_ZERO( &results );
     FT_ZERO( &flexStore );
@@ -560,6 +560,7 @@
                         /* hShift, */
                         &hStemHintArray,
                         &vStemHintArray,
+                        &hintData,
                         &hintMask,
                         hintOriginY,
                         &font->blues,
@@ -2504,6 +2505,10 @@
         /* `cf2_hintmask_read' (which also traces the mask bytes) */
         FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
 
+        /* disregard if not hinting */
+        if ( !font->hinted )
+          break;
+
         /* never add hints after the mask is computed */
         if ( cf2_stack_count( opStack ) > 1    &&
              cf2_hintmask_isValid( &hintMask ) )
@@ -2553,8 +2558,8 @@
 
           cf2_hintmap_init( &counterHintMap,
                             font,
-                            &glyphPath.initialHintMap,
-                            &glyphPath.hintMoves,
+                            glyphPath.initialHintMap,
+                            glyphPath.hintMoves,
                             scaleY );
           cf2_hintmask_init( &counterMask, error );