[arabic] Make ZWJ prevent ligatures instead of facilitating it Unicode 6.2.0 Section 16.2 / Figure 16.3 says: "For backward compatibility, between Arabic characters a ZWJ acts just like the sequence <ZWJ, ZWNJ, ZWJ>, preventing a ligature from forming instead of requesting the use of a ligature that would not normally be used. As a result, there is no plain text mechanism for requesting the use of a ligature in Arabic text." As such, we flip internal zwj to zwnj flags for GSUB matching, which means it will block ligation in all features, unless the font explicitly matches U+200D glyph. This doesn't affect joining behavior.
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 4e20a8f..3f02c80 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh
@@ -107,6 +107,12 @@ return !!(info->unicode_props0() & MASK0_ZWJ); } +inline void +_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) +{ + info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ; +} + #define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index a57e81a..d549945 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc
@@ -157,6 +157,11 @@ static void +nuke_joiners (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +static void arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); @@ -176,6 +181,8 @@ * TODO: Add test cases for these two. */ + map->add_gsub_pause (nuke_joiners); + map->add_global_bool_feature (HB_TAG('c','c','m','p')); map->add_global_bool_feature (HB_TAG('l','o','c','l')); @@ -314,6 +321,17 @@ static void +nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + if (_hb_glyph_info_is_zwj (&buffer->info[i])) + _hb_glyph_info_flip_joiners (&buffer->info[i]); +} + +static void arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer)