Commit 8c7fb78b1600b682d142a6996be25f07b2d7bebf

Werner Lemberg 2014-04-17T15:53:25

[autofit] More coverage fixes for complex scripts. * src/autofit/hbshim.c (af_get_coverage): Merge input glyph coverage of GSUB lookups into output coverage. Otherwise, ligatures are not handled properly. Don't check blue zone characters for default coverage.

diff --git a/ChangeLog b/ChangeLog
index 48e6199..9bb6435 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2014-04-17  Werner Lemberg  <wl@gnu.org>
 
+	[autofit] More coverage fixes for complex scripts.
+
+	* src/autofit/hbshim.c (af_get_coverage): Merge input glyph coverage
+	of GSUB lookups into output coverage.  Otherwise, ligatures are not
+	handled properly.
+	Don't check blue zone characters for default coverage.
+
+2014-04-17  Werner Lemberg  <wl@gnu.org>
+
 	Make `FT_Get_SubGlyph_Info' actually work.
 
 	* src/base/ftobjs.c (FT_Get_SubGlyph_Info): Return FT_Err_Ok
diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c
index ced5ce5..431360e 100644
--- a/src/autofit/hbshim.c
+++ b/src/autofit/hbshim.c
@@ -102,10 +102,12 @@
   {
     hb_face_t*  face;
 
-    hb_set_t*  gsub_lookups;  /* GSUB lookups for a given script */
-    hb_set_t*  gsub_glyphs;   /* glyphs covered by GSUB lookups  */
-    hb_set_t*  gpos_lookups;  /* GPOS lookups for a given script */
-    hb_set_t*  gpos_glyphs;   /* glyphs covered by GPOS lookups  */
+    hb_set_t*  gsub_lookups;    /* GSUB lookups for a given script */
+    hb_set_t*  gsub_glyphs_in;  /* glyphs covered by GSUB lookups  */
+    hb_set_t*  gsub_glyphs_out;
+
+    hb_set_t*  gpos_lookups;    /* GPOS lookups for a given script */
+    hb_set_t*  gpos_glyphs;     /* glyphs covered by GPOS lookups  */
 
     hb_script_t      script;
     const hb_tag_t*  coverage_tags;
@@ -125,10 +127,11 @@
 
     face = hb_font_get_face( globals->hb_font );
 
-    gsub_lookups = hb_set_create();
-    gsub_glyphs  = hb_set_create();
-    gpos_lookups = hb_set_create();
-    gpos_glyphs  = hb_set_create();
+    gsub_lookups    = hb_set_create();
+    gsub_glyphs_in  = hb_set_create();
+    gsub_glyphs_out = hb_set_create();
+    gpos_lookups    = hb_set_create();
+    gpos_glyphs     = hb_set_create();
 
     coverage_tags = coverages[style_class->coverage];
     script        = scripts[style_class->script];
@@ -199,9 +202,9 @@
                                           HB_OT_TAG_GSUB,
                                           idx,
                                           NULL,
+                                          gsub_glyphs_in,
                                           NULL,
-                                          NULL,
-                                          gsub_glyphs );
+                                          gsub_glyphs_out );
     }
 
 #ifdef FT_DEBUG_LEVEL_TRACE
@@ -247,6 +250,7 @@
      * (this is, not a single character is covered), we skip this coverage.
      *
      */
+    if ( style_class->coverage != AF_COVERAGE_DEFAULT )
     {
       AF_Blue_Stringset         bss = style_class->blue_stringset;
       const AF_Blue_StringRec*  bs  = &af_blue_stringsets[bss];
@@ -288,6 +292,9 @@
       }
     }
 
+    /* merge in and out glyphs */
+    hb_set_union( gsub_glyphs_out, gsub_glyphs_in );
+
     /*
      * Various OpenType features might use the same glyphs at different
      * vertical positions; for example, superscript and subscript glyphs
@@ -336,14 +343,14 @@
      *
      */
     if ( style_class->coverage != AF_COVERAGE_DEFAULT )
-      hb_set_subtract( gsub_glyphs, gpos_glyphs );
+      hb_set_subtract( gsub_glyphs_out, gpos_glyphs );
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     FT_TRACE4(( "  glyphs without GPOS data (`*' means already assigned)" ));
     count = 0;
 #endif
 
-    for ( idx = -1; hb_set_next( gsub_glyphs, &idx ); )
+    for ( idx = -1; hb_set_next( gsub_glyphs_out, &idx ); )
     {
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( !( count % 10 ) )
@@ -375,10 +382,11 @@
 #endif
 
   Exit:
-    hb_set_destroy( gsub_lookups );
-    hb_set_destroy( gsub_glyphs  );
-    hb_set_destroy( gpos_lookups );
-    hb_set_destroy( gpos_glyphs  );
+    hb_set_destroy( gsub_lookups    );
+    hb_set_destroy( gsub_glyphs_in  );
+    hb_set_destroy( gsub_glyphs_out );
+    hb_set_destroy( gpos_lookups    );
+    hb_set_destroy( gpos_glyphs     );
 
     return FT_Err_Ok;
   }