On Tue, Jul 11, 2017 at 11:20:19PM +0100, 'Richard Wordingham' via Khaled Hosny 
wrote:
> This bug (https://github.com/behdad/harfbuzz/issues/180) was fixed on
> 17 December 2015.  It was present in at least HarfBuzz Versions 1.0.1
> and 1.1.2, and was gone in Version 1.1.3.
> 
> It's been annoying me in LibreOffice for some time now.  The problem is
> that I'm using a long-term-support version of Ubuntu, 16.04 Xenial.
> Xenial's distribution provides Version 1.0.1 of HarfBuzz - Package
> libharfbuzz0b Version 1.0.1-1ubuntu0.1 to be precise.  We can cite it
> for at least two living scripts, Balinese and Tai Tham (for Tai
> Khuen - example string is ᩉ᩠ᩅᩯᩁ /wɛːn/ 'ring (n.)').

This is out of HarfBuzz developers control. But what you can do is
backport the patch to 1.0.1 and convince Ubuntu to include it into their
package. The patch seems to apply almost cleanly to 1.0.1 with small conflict
in the test harness, so here is a backported version of the patch that
applies cleanly if it is of any help (you can also setup a PPA with the
patched version if you couldn’t convince Ubuntu maintainers).

Regards,
Khaled
>From c9a0f7e97329579ed09949bcd8762f75d7dfd45a Mon Sep 17 00:00:00 2001
From: Behdad Esfahbod <beh...@behdad.org>
Date: Thu, 17 Dec 2015 11:59:15 +0000
Subject: [PATCH] [use] Fix halant detection

Before, we were just checking the use_category().  This detects as
halant a ligature that had the halant as first glyph (as seen in
NotoSansBalinese.)  Change that to use the is_ligated() glyph prop
bit.  The font is forming this ligature in ccmp, which is before
the rphf / pref tests.  So we need to make sure the "ligated" bit
survives those tests.  Since those only check the "substituted" bit,
we now only clear that bit for them and "ligated" survives.

Fixes https://github.com/behdad/harfbuzz/issues/180
---
 src/hb-ot-layout-private.hh                          |   6 ++----
 src/hb-ot-shape-complex-use.cc                       |  19 ++++++++++++-------
 test/shaping/Makefile.am                             |   1 +
 test/shaping/fonts/sha1sum/MANIFEST                  |   1 +
 .../fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf     | Bin 0 -> 2616 bytes
 test/shaping/tests/MANIFEST                          |   1 +
 test/shaping/tests/use.tests                         |   1 +
 7 files changed, 18 insertions(+), 11 deletions(-)
 create mode 100644 test/shaping/fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf
 create mode 100644 test/shaping/tests/use.tests

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index d168e27f..bf69d468 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -442,11 +442,9 @@ _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info)
 }
 
 static inline void
-_hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *info)
+_hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
 {
-  info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
-			   HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
-			   HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
+  info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
 }
 
 
diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc
index 1d44d220..1639ff09 100644
--- a/src/hb-ot-shape-complex-use.cc
+++ b/src/hb-ot-shape-complex-use.cc
@@ -368,7 +368,7 @@ clear_substitution_flags (const hb_ot_shape_plan_t *plan,
   hb_glyph_info_t *info = buffer->info;
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
-    _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]);
+    _hb_glyph_info_clear_substituted (&info[i]);
 }
 
 static void
@@ -413,6 +413,12 @@ record_pref (const hb_ot_shape_plan_t *plan,
   }
 }
 
+static inline bool
+is_halant (const hb_glyph_info_t &info)
+{
+  return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info);
+}
+
 static void
 reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
 {
@@ -428,7 +434,6 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
 
   hb_glyph_info_t *info = buffer->info;
 
-#define HALANT_FLAGS FLAG(USE_H)
 #define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV))
 
   /* Move things forward. */
@@ -436,12 +441,12 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
   {
     /* Got a repha.  Reorder it to after first base, before first halant. */
     for (unsigned int i = start + 1; i < end; i++)
-      if (FLAG_UNSAFE (info[i].use_category()) & (HALANT_FLAGS | BASE_FLAGS))
+      if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (info[i]))
       {
 	/* If we hit a halant, move before it; otherwise it's a base: move to it's
 	 * place, and shift things in between backward. */
 
-	if (info[i].use_category() == USE_H)
+	if (is_halant (info[i]))
 	  i--;
 
 	hb_glyph_info_t t = info[start];
@@ -458,11 +463,11 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
   for (unsigned int i = start; i < end; i++)
   {
     uint32_t flag = FLAG_UNSAFE (info[i].use_category());
-    if (flag & (HALANT_FLAGS | BASE_FLAGS))
+    if ((flag & (BASE_FLAGS)) || is_halant (info[i]))
     {
-      /* If we hit a halant, move before it; otherwise it's a base: move to it's
+      /* If we hit a halant, move after it; otherwise it's a base: move to it's
        * place, and shift things in between backward. */
-      if (info[i].use_category() == USE_H)
+      if (is_halant (info[i]))
 	j = i + 1;
       else
 	j = i;
diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am
index 22e326e3..05667a27 100644
--- a/test/shaping/Makefile.am
+++ b/test/shaping/Makefile.am
@@ -45,6 +45,7 @@ TESTS = \
 	tests/indic-old-spec.tests \
 	tests/indic-pref-blocking.tests \
 	tests/mongolian-variation-selector.tests \
+	tests/use.tests \
 	tests/vertical.tests \
 	tests/zero-width-marks.tests \
 	$(NULL)
diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST
index 2881f0a8..6cf0541e 100644
--- a/test/shaping/fonts/sha1sum/MANIFEST
+++ b/test/shaping/fonts/sha1sum/MANIFEST
@@ -19,3 +19,4 @@ df768b9c257e0c9c35786c47cae15c46571d56be.ttf
 e207635780b42f898d58654b65098763e340f5c7.ttf
 ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf
 f499fbc23865022234775c43503bba2e63978fe1.ttf
+fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf
diff --git a/test/shaping/fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf b/test/shaping/fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..d49432dd824a0e11a9d9fbdca9c2d88f4c574086
GIT binary patch
literal 2616
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

literal 0
HcmV?d00001

diff --git a/test/shaping/tests/MANIFEST b/test/shaping/tests/MANIFEST
index 323ad460..7e1548d1 100644
--- a/test/shaping/tests/MANIFEST
+++ b/test/shaping/tests/MANIFEST
@@ -7,5 +7,6 @@ indic-joiner-candrabindu.tests
 indic-old-spec.tests
 indic-pref-blocking.tests
 mongolian-variation-selector.tests
+use.tests
 vertical.tests
 zero-width-marks.tests
diff --git a/test/shaping/tests/use.tests b/test/shaping/tests/use.tests
new file mode 100644
index 00000000..ceb82941
--- /dev/null
+++ b/test/shaping/tests/use.tests
@@ -0,0 +1 @@
+fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf::U+1B1B,U+1B44,U+1B13,U+1B3E:[gid3=0+990|gid7=0+2473|gid5=0@-293,-400+0]
-- 
2.13.2

_______________________________________________
HarfBuzz mailing list
HarfBuzz@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/harfbuzz

Reply via email to