[HarfBuzz] harfbuzz: Branch 'master'

Behdad Esfahbod behdad at kemper.freedesktop.org
Mon Oct 2 18:14:17 UTC 2017


 src/hb-ot-layout-gsubgpos-private.hh                                    |   59 ++++++++--
 test/shaping/fonts/sha1sum/a6c76d1bafde4a0b1026ebcc932d2e5c6fd02442.ttf |binary
 test/shaping/tests/ligature-id.tests                                    |    1 
 3 files changed, 51 insertions(+), 9 deletions(-)

New commits:
commit 8b2c94c43fd335b944d5e5487265706b8e0f9041
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 2 20:02:45 2017 +0200

    Tweak ligature component matching for ligature formation
    
    If two marks want to ligate and they belong to different components of the
    same ligature glyph, and said ligature glyph is to be ignored according to
    mark-filtering rules, then allow.
    
    Example Burmese senquence:
    
      U+1004,U+103A,U+1039,U+101B,U+103D,U+102D
    
    Test font provided by Norbert Lindenberg.
    
    Fixes https://github.com/behdad/harfbuzz/issues/545

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 472628a3..f2ad9f1c 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -374,6 +374,13 @@ struct hb_apply_context_t :
 
     inline void reject (void) { num_items++; match_glyph_data--; }
 
+    inline matcher_t::may_skip_t
+    may_skip (const hb_apply_context_t *c,
+	      const hb_glyph_info_t    &info) const
+    {
+      return matcher.may_skip (c, info);
+    }
+
     inline bool next (void)
     {
       assert (num_items > 0);
@@ -736,11 +743,17 @@ static inline bool match_input (hb_apply_context_t *c,
    * - Ligatures cannot be formed across glyphs attached to different components
    *   of previous ligatures.  Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
    *   LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
-   *   However, it would be wrong to ligate that SHADDA,FATHA sequence.o
-   *   There is an exception to this: If a ligature tries ligating with marks that
-   *   belong to it itself, go ahead, assuming that the font designer knows what
-   *   they are doing (otherwise it can break Indic stuff when a matra wants to
-   *   ligate with a conjunct...)
+   *   However, it would be wrong to ligate that SHADDA,FATHA sequence.
+   *   There are a couple of exceptions to this:
+   *
+   *   o If a ligature tries ligating with marks that belong to it itself, go ahead,
+   *     assuming that the font designer knows what they are doing (otherwise it can
+   *     break Indic stuff when a matra wants to ligate with a conjunct,
+   *
+   *   o If two marks want to ligate and they belong to different components of the
+   *     same ligature glyph, and said ligature glyph is to be ignored according to
+   *     mark-filtering rules, then allow.
+   *     https://github.com/behdad/harfbuzz/issues/545
    */
 
   bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
@@ -761,13 +774,41 @@ static inline bool match_input (hb_apply_context_t *c,
     unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
     unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
 
-    if (first_lig_id && first_lig_comp) {
+    if (first_lig_id && first_lig_comp)
+    {
       /* If first component was attached to a previous ligature component,
        * all subsequent components should be attached to the same ligature
-       * component, otherwise we shouldn't ligate them. */
+       * component, otherwise we shouldn't ligate them... */
       if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
-	return_trace (false);
-    } else {
+      {
+        if (first_lig_id != this_lig_id && this_lig_id != 0)
+	  return_trace (false);
+
+        /* ...unless, we are attached to a base ligature and that base
+	 * ligature is ignorable. */
+	bool found = false;
+	const hb_glyph_info_t *out = buffer->out_info;
+	unsigned int j = buffer->out_len;
+	while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
+	{
+	  if (_hb_glyph_info_get_lig_comp (&out[j - 1]) == 0)
+	  {
+	    j--;
+	    found = true;
+	    break;
+	  }
+	  j--;
+	}
+
+	if (!found)
+	  return_trace (false);
+
+	if (skippy_iter.may_skip (c, out[j]) != hb_apply_context_t::matcher_t::SKIP_YES)
+	  return_trace (false);
+      }
+    }
+    else
+     {
       /* If first component was NOT attached to a previous ligature component,
        * all subsequent components should also NOT be attached to any ligature
        * component, unless they are attached to the first component itself! */
diff --git a/test/shaping/fonts/sha1sum/a6c76d1bafde4a0b1026ebcc932d2e5c6fd02442.ttf b/test/shaping/fonts/sha1sum/a6c76d1bafde4a0b1026ebcc932d2e5c6fd02442.ttf
new file mode 100644
index 00000000..7930a96b
Binary files /dev/null and b/test/shaping/fonts/sha1sum/a6c76d1bafde4a0b1026ebcc932d2e5c6fd02442.ttf differ
diff --git a/test/shaping/tests/ligature-id.tests b/test/shaping/tests/ligature-id.tests
index a1ce2bbf..cd7f1659 100644
--- a/test/shaping/tests/ligature-id.tests
+++ b/test/shaping/tests/ligature-id.tests
@@ -33,3 +33,4 @@ fonts/sha1sum/1c2fb74c1b2aa173262734c1f616148f1648cfd6.ttf::U+0995,U+09CD,U+0995
 fonts/sha1sum/1c2fb74c1b2aa173262734c1f616148f1648cfd6.ttf::U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0020,U+0995,U+09CD,U+09B0,U+0995,U+09CD,U+09B2:[u0995_u09CD.half_u0995.pres=0+566|u0995_u09CD.half_u0995.pres=3+566|u0995_u09CD.half_u0995.pres=6+566|u0995_u09CD.half_u0995.pres=9+566|u0995_u09CD.half_u0995.pres=12+566|u0995_u09CD.half_u0995.
 pres=15+566|u0995_u09CD.half_u0995.pres=18+566|u0995_u09CD.half_u0995.pres=21+566|u0995_u09CD.half_u0995.pres=24+566|u0995_u09CD.half_u0995.pres=27+566|u0995_u09CD.half_u0995.pres=30+566|u0995_u09CD.half_u0995.pres=33+566|u0995_u09CD.half_u0995.pres=36+566|u0995_u09CD.half_u0995.pres=39+566|u0995_u09CD.half_u0995.pres=42+566|u0995_u09CD.half_u0995.pres=45+566|u0995_u09CD.half_u0995.pres=48+566|u0995_u09CD.half_u0995.pres=51+566|u0995_u09CD.half_u0995.pres=54+566|u0995_u09CD.half_u0995.pres=57+566|u0995_u09CD.half_u0995.pres=60+566|u0995_u09CD.half_u0995.pres=63+566|u0995_u09CD.half_u0995.pres=66+566|u0995_u09CD.half_u0995.pres=69+566|u0995_u09CD.half_u0995.pres=72+566|u0995_u09CD.half_u0995.pres=75+566|u0995_u09CD.half_u0995.pres=78+566|u0995_u09CD.half_u0995.pres=81+566|u0995_u09CD.half_u0995.pres=84+566|u0995_u09CD.half_u0995.pres=87+566|u0995_u09CD.half_u0995.pres=90+566|u0995_u09CD.half_u0995.pres=93+566|u0995_u09CD.half_u0995.pres=96+566|space=99+213|u0995_u09B0_u09CD.blwf.vatu
 =100+643|u0995_u09CD.half_u09B2.pres=103+602]
 fonts/sha1sum/1c2fb74c1b2aa173262734c1f616148f1648cfd6.ttf::U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0020,U+0995,U+09CD,U+09B0,U+0995,U+09CD,U+09B2:[u0995_u09CD.half_u0995.pres=0+566|u0995_u09CD.half_u0995.pres=3+566|u0995_u09CD.half_u0995.pres=6+566|u0995_u09CD.half_u0995.pres=9+566|u0995_u09CD.half_u0995.pres=12+566|u0
 995_u09CD.half_u0995.pres=15+566|u0995_u09CD.half_u0995.pres=18+566|u0995_u09CD.half_u0995.pres=21+566|u0995_u09CD.half_u0995.pres=24+566|u0995_u09CD.half_u0995.pres=27+566|u0995_u09CD.half_u0995.pres=30+566|u0995_u09CD.half_u0995.pres=33+566|u0995_u09CD.half_u0995.pres=36+566|u0995_u09CD.half_u0995.pres=39+566|u0995_u09CD.half_u0995.pres=42+566|u0995_u09CD.half_u0995.pres=45+566|u0995_u09CD.half_u0995.pres=48+566|u0995_u09CD.half_u0995.pres=51+566|u0995_u09CD.half_u0995.pres=54+566|u0995_u09CD.half_u0995.pres=57+566|u0995_u09CD.half_u0995.pres=60+566|u0995_u09CD.half_u0995.pres=63+566|u0995_u09CD.half_u0995.pres=66+566|u0995_u09CD.half_u0995.pres=69+566|u0995_u09CD.half_u0995.pres=72+566|u0995_u09CD.half_u0995.pres=75+566|u0995_u09CD.half_u0995.pres=78+566|u0995_u09CD.half_u0995.pres=81+566|u0995_u09CD.half_u0995.pres=84+566|u0995_u09CD.half_u0995.pres=87+566|u0995_u09CD.half_u0995.pres=90+566|u0995_u09CD.half_u0995.pres=93+566|u0995_u09CD.half_u0995.pres=96+566|u0995_u09CD.half_u0
 995.pres=99+566|space=102+213|u0995_u09B0_u09CD.blwf.vatu=103+643|u0995_u09CD.half_u09B2.pres=106+602]
 fonts/sha1sum/1c2fb74c1b2aa173262734c1f616148f1648cfd6.ttf::U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0995,U+09CD,U+0995,U+0020,U+0995,U+09CD,U+09B0,U+0995,U+09CD,U+09B2:[u0995_u09CD.half_u0995.pres=0+566|u0995_u09CD.half_u0995.pres=3+566|u0995_u09CD.half_u0995.pres=6+566|u0995_u09CD.half_u0995.pres=9+566|u0995_u09CD.half
 _u0995.pres=12+566|u0995_u09CD.half_u0995.pres=15+566|u0995_u09CD.half_u0995.pres=18+566|u0995_u09CD.half_u0995.pres=21+566|u0995_u09CD.half_u0995.pres=24+566|u0995_u09CD.half_u0995.pres=27+566|u0995_u09CD.half_u0995.pres=30+566|u0995_u09CD.half_u0995.pres=33+566|u0995_u09CD.half_u0995.pres=36+566|u0995_u09CD.half_u0995.pres=39+566|u0995_u09CD.half_u0995.pres=42+566|u0995_u09CD.half_u0995.pres=45+566|u0995_u09CD.half_u0995.pres=48+566|u0995_u09CD.half_u0995.pres=51+566|u0995_u09CD.half_u0995.pres=54+566|u0995_u09CD.half_u0995.pres=57+566|u0995_u09CD.half_u0995.pres=60+566|u0995_u09CD.half_u0995.pres=63+566|u0995_u09CD.half_u0995.pres=66+566|u0995_u09CD.half_u0995.pres=69+566|u0995_u09CD.half_u0995.pres=72+566|u0995_u09CD.half_u0995.pres=75+566|u0995_u09CD.half_u0995.pres=78+566|u0995_u09CD.half_u0995.pres=81+566|u0995_u09CD.half_u0995.pres=84+566|u0995_u09CD.half_u0995.pres=87+566|u0995_u09CD.half_u0995.pres=90+566|u0995_u09CD.half_u0995.pres=93+566|u0995_u09CD.half_u0995.pres=96+56
 6|u0995_u09CD.half_u0995.pres=99+566|u0995_u09CD.half_u0995.pres=102+566|space=105+213|u0995_u09B0_u09CD.blwf.vatu=106+643|u0995_u09CD.half_u09B2.pres=109+602]
+fonts/sha1sum/a6c76d1bafde4a0b1026ebcc932d2e5c6fd02442.ttf::U+1004,U+103A,U+1039,U+101B,U+103D,U+102D:[uni101B103D=0+450|uni1004103A1039102D=0 at -50,0+0]


More information about the HarfBuzz mailing list