Commit ec776596cef453a9e0119d428225c1579b804374

Werner Lemberg 2016-01-19T19:33:57

[autofit] Fix handling of default script. Patch taken from ttfautohint, commit 071ae2c00e0d67f9d19418f4fade1c23d27dc185. There were two bugs. - We now use non-standard script tags like `khms' for special purposes. However, HarfBuzz maps such tags to `DFLT', and without this commit the associated lookups were incorrectly assigned to the non-standard tags. - Let's assume we have a Bengali font, and the font's `DFLT' script tag handles the necessary lookups for Bengali, too. Without this commit, the `DFLT' lookups were assigned to ttfautohint's default script (usually `latn') before the standard lookups for Bengali were handled. We now have the following order while searching for covered glyph indices. special features of scripts (e.g. `sups' for Cyrillic) Unicode mappings of scripts remaining features of scripts (especially important for Indic scripts) default features of default script * src/autofit/afshaper.c, src/autofit/afshaper.h (af_shaper_get_coverage): Add boolean parameter to indicate default script. Update all callers. * src/autofit/afglobal.c (af_face_globals_compute_style_coverage): Fix search order for coverages.

diff --git a/ChangeLog b/ChangeLog
index 32d7c1a..721c5d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,42 @@
 2016-01-19  Werner Lemberg  <wl@gnu.org>
 
+	[autofit] Fix handling of default script.
+
+	Patch taken from ttfautohint, commit
+	071ae2c00e0d67f9d19418f4fade1c23d27dc185.
+
+	There were two bugs.
+
+	  - We now use non-standard script tags like `khms' for special
+	    purposes.  However, HarfBuzz maps such tags to `DFLT', and
+	    without this commit the associated lookups were incorrectly
+	    assigned to the non-standard tags.
+
+	  - Let's assume we have a Bengali font, and the font's `DFLT'
+	    script tag handles the necessary lookups for Bengali, too.
+	    Without this commit, the `DFLT' lookups were assigned to
+	    ttfautohint's default script (usually `latn') before the
+	    standard lookups for Bengali were handled.
+
+	    We now have the following order while searching for covered
+	    glyph indices.
+
+	      special features of scripts (e.g. `sups' for Cyrillic)
+	      Unicode mappings of scripts
+	      remaining features of scripts (especially important for Indic
+	        scripts)
+	      default features of default script
+
+	* src/autofit/afshaper.c, src/autofit/afshaper.h
+	(af_shaper_get_coverage): Add boolean parameter to indicate default
+	script.
+	Update all callers.
+
+	* src/autofit/afglobal.c (af_face_globals_compute_style_coverage):
+	Fix search order for coverages.
+
+2016-01-19  Werner Lemberg  <wl@gnu.org>
+
 	Various minor clang fixes.
 
 	* src/autofit/afcjk.c (af_cjk_metrics_init_widths),
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index c417702..ac6dcaf 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -241,23 +241,23 @@
       else
       {
         /* get glyphs not directly addressable by cmap */
-        af_shaper_get_coverage( globals, style_class, gstyles );
+        af_shaper_get_coverage( globals, style_class, gstyles, 0 );
       }
     }
 
-    /* handle the default OpenType features of the default script ... */
-    af_shaper_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles );
-
-    /* ... and the remaining default OpenType features */
+    /* handle the remaining default OpenType features ... */
     for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ )
     {
       AF_StyleClass  style_class = AF_STYLE_CLASSES_GET[ss];
 
 
-      if ( ss != dflt && style_class->coverage == AF_COVERAGE_DEFAULT )
-        af_shaper_get_coverage( globals, style_class, gstyles );
+      if ( style_class->coverage == AF_COVERAGE_DEFAULT )
+        af_shaper_get_coverage( globals, style_class, gstyles, 0 );
     }
 
+    /* ... and finally the default OpenType features of the default script */
+    af_shaper_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles, 1 );
+
     /* mark ASCII digits */
     for ( i = 0x30; i <= 0x39; i++ )
     {
diff --git a/src/autofit/afshaper.c b/src/autofit/afshaper.c
index f72c0b1..95c5d95 100644
--- a/src/autofit/afshaper.c
+++ b/src/autofit/afshaper.c
@@ -98,7 +98,8 @@
   FT_Error
   af_shaper_get_coverage( AF_FaceGlobals  globals,
                           AF_StyleClass   style_class,
-                          FT_UShort*      gstyles )
+                          FT_UShort*      gstyles,
+                          FT_Bool         default_script )
   {
     hb_face_t*  face;
 
@@ -143,8 +144,7 @@
     /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */
     /* as the second tag.  We change that to HB_TAG_NONE except for the  */
     /* default script.                                                   */
-    if ( style_class->script == globals->module->default_script &&
-         style_class->coverage == AF_COVERAGE_DEFAULT           )
+    if ( default_script )
     {
       if ( script_tags[0] == HB_TAG_NONE )
         script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT;
@@ -158,6 +158,11 @@
     }
     else
     {
+      /* we use non-standard tags like `khms' for special purposes;       */
+      /* HarfBuzz maps them to `DFLT', which we don't want to handle here */
+      if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT )
+        goto Exit;
+
       if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT )
         script_tags[1] = HB_TAG_NONE;
     }
diff --git a/src/autofit/afshaper.h b/src/autofit/afshaper.h
index 0d2962d..0d41f78 100644
--- a/src/autofit/afshaper.h
+++ b/src/autofit/afshaper.h
@@ -38,7 +38,8 @@ FT_BEGIN_HEADER
   FT_Error
   af_shaper_get_coverage( AF_FaceGlobals  globals,
                           AF_StyleClass   style_class,
-                          FT_UShort*      gstyles );
+                          FT_UShort*      gstyles,
+                          FT_Bool         default_script );
 
 
   void*