Commit 47ca5cb69d26b606b51292a90d025688d4dc5e4e

Werner Lemberg 2019-06-16T15:32:11

[autofit] Disable hinting if no blue zones are available (#56450). * src/autofit/afglobal.c (af_face_global_get_metrics): Start again (with dummy hinter module) if no blue zones are present. * src/autofit/aflatin.c (af_latin_metrics_init_blues): Change signature to return error code. If no blue zones are found, update `glyph_styles' array to hold AF_STYLE_NONE_DFLT instead of the current style. (af_latin_metrics_init): Return internal error code if no blue zones are found.

diff --git a/ChangeLog b/ChangeLog
index 9c4e7be..cd35fa6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2019-06-16  Werner Lemberg  <wl@gnu.org>
 
+	[autofit] Disable hinting if no blue zones are available (#56450).
+
+	* src/autofit/afglobal.c (af_face_global_get_metrics): Start again
+	(with dummy hinter module) if no blue zones are present.
+
+	* src/autofit/aflatin.c (af_latin_metrics_init_blues): Change
+	signature to return error code.
+	If no blue zones are found, update `glyph_styles' array to hold
+	AF_STYLE_NONE_DFLT instead of the current style.
+	(af_latin_metrics_init): Return internal error code if no blue zones
+	are found.
+
+2019-06-16  Werner Lemberg  <wl@gnu.org>
+
 	Towards better VMS support.
 
 	More to come.
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index 7183ce4..6a9a1e5 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -443,6 +443,7 @@
       style = (AF_Style)( globals->glyph_styles[gindex] &
                           AF_STYLE_UNASSIGNED           );
 
+  Again:
     style_class          = af_style_classes[style];
     writing_system_class = af_writing_system_classes
                              [style_class->writing_system];
@@ -470,6 +471,16 @@
             writing_system_class->style_metrics_done( metrics );
 
           FT_FREE( metrics );
+
+          /* internal error code -1 indicates   */
+          /* that no blue zones have been found */
+          if ( error == -1 )
+          {
+            style = (AF_Style)( globals->glyph_styles[gindex] &
+                                AF_STYLE_UNASSIGNED           );
+            goto Again;
+          }
+
           goto Exit;
         }
       }
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index b5cd3c1..27d4024 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -316,7 +316,7 @@
   /* Find all blue zones.  Flat segments give the reference points, */
   /* round segments the overshoot positions.                        */
 
-  static void
+  static int
   af_latin_metrics_init_blues( AF_LatinMetrics  metrics,
                                FT_Face          face )
   {
@@ -985,10 +985,11 @@
 
     af_shaper_buf_destroy( face, shaper_buf );
 
-    /* we finally check whether blue zones are ordered; */
-    /* `ref' and `shoot' values of two blue zones must not overlap */
     if ( axis->blue_count )
     {
+      /* we finally check whether blue zones are ordered;            */
+      /* `ref' and `shoot' values of two blue zones must not overlap */
+
       FT_UInt       i;
       AF_LatinBlue  blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2];
 
@@ -1037,11 +1038,34 @@
                       *a ));
         }
       }
+
+      FT_TRACE5(( "\n" ));
+
+      return 0;
     }
+    else
+    {
+      /* disable hinting for the current style if there are no blue zones */
 
-    FT_TRACE5(( "\n" ));
+      AF_FaceGlobals  globals = metrics->root.globals;
+      FT_UShort*      gstyles = globals->glyph_styles;
+
+      FT_Long  i;
+
+
+      FT_TRACE5(( "no blue zones found:"
+                  " hinting disabled for this style\n" ));
+
+      for ( i = 0; i < globals->glyph_count; i++ )
+      {
+        if ( ( gstyles[i] & AF_STYLE_MASK ) == sc->style )
+          gstyles[i] = AF_STYLE_NONE_DFLT;
+      }
+
+      FT_TRACE5(( "\n" ));
 
-    return;
+      return 1;
+    }
   }
 
 
@@ -1120,6 +1144,8 @@
   af_latin_metrics_init( AF_LatinMetrics  metrics,
                          FT_Face          face )
   {
+    FT_Error  error = FT_Err_Ok;
+
     FT_CharMap  oldmap = face->charmap;
 
 
@@ -1128,12 +1154,18 @@
     if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
     {
       af_latin_metrics_init_widths( metrics, face );
-      af_latin_metrics_init_blues( metrics, face );
+      if ( af_latin_metrics_init_blues( metrics, face ) )
+      {
+        /* use internal error code to indicate missing blue zones */
+        error = -1;
+        goto Exit;
+      }
       af_latin_metrics_check_digits( metrics, face );
     }
 
+  Exit:
     FT_Set_Charmap( face, oldmap );
-    return FT_Err_Ok;
+    return error;
   }