[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
pull/199/head
Behdad Esfahbod 9 years ago
parent 86bcbd65b0
commit 2ab0de9fbd
  1. 6
      src/hb-ot-layout-private.hh
  2. 19
      src/hb-ot-shape-complex-use.cc
  3. 1
      test/shaping/Makefile.am
  4. 1
      test/shaping/fonts/sha1sum/MANIFEST
  5. BIN
      test/shaping/fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf
  6. 1
      test/shaping/tests/MANIFEST
  7. 1
      test/shaping/tests/use.tests

@ -517,11 +517,9 @@ _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info)
} }
static inline void 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 | info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
} }

@ -360,7 +360,7 @@ clear_substitution_flags (const hb_ot_shape_plan_t *plan,
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len; unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++) 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 static void
@ -405,6 +405,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 static void
reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
{ {
@ -420,7 +426,6 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
hb_glyph_info_t *info = buffer->info; 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)) #define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV))
/* Move things forward. */ /* Move things forward. */
@ -428,12 +433,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. */ /* Got a repha. Reorder it to after first base, before first halant. */
for (unsigned int i = start + 1; i < end; i++) 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 /* If we hit a halant, move before it; otherwise it's a base: move to it's
* place, and shift things in between backward. */ * place, and shift things in between backward. */
if (info[i].use_category() == USE_H) if (is_halant (info[i]))
i--; i--;
buffer->merge_clusters (start, i + 1); buffer->merge_clusters (start, i + 1);
@ -450,11 +455,11 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
for (unsigned int i = start; i < end; i++) for (unsigned int i = start; i < end; i++)
{ {
uint32_t flag = FLAG_UNSAFE (info[i].use_category()); 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. */ * place, and shift things in between backward. */
if (info[i].use_category() == USE_H) if (is_halant (info[i]))
j = i + 1; j = i + 1;
else else
j = i; j = i;

@ -55,6 +55,7 @@ TESTS = \
tests/mongolian-variation-selector.tests \ tests/mongolian-variation-selector.tests \
tests/spaces.tests \ tests/spaces.tests \
tests/simple.tests \ tests/simple.tests \
tests/use.tests \
tests/vertical.tests \ tests/vertical.tests \
tests/zero-width-marks.tests \ tests/zero-width-marks.tests \
$(NULL) $(NULL)

@ -36,3 +36,4 @@ e207635780b42f898d58654b65098763e340f5c7.ttf
ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf
f499fbc23865022234775c43503bba2e63978fe1.ttf f499fbc23865022234775c43503bba2e63978fe1.ttf
fab39d60d758cb586db5a504f218442cd1395725.ttf fab39d60d758cb586db5a504f218442cd1395725.ttf
fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf

@ -13,5 +13,6 @@ indic-pref-blocking.tests
mongolian-variation-selector.tests mongolian-variation-selector.tests
simple.tests simple.tests
spaces.tests spaces.tests
use.tests
vertical.tests vertical.tests
zero-width-marks.tests zero-width-marks.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]
Loading…
Cancel
Save