From 3583fb03b14a10ec5ab5f9c480e150934101fd0b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 23 Sep 2018 22:33:38 -0400 Subject: [PATCH] Simplify ZWJ-skipping a bit Towards disabling ZWJ-skipping in certain GPOS contexts. Part of https://github.com/flutter/flutter/issues/16886 --- src/hb-ot-layout-gsubgpos.hh | 6 +++--- src/hb-ot-shape-complex-indic.cc | 21 ++++++++++++++++----- src/hb-ot-shape-complex-khmer.cc | 21 ++++++++++++++------- src/hb-ot-shape-complex-myanmar.cc | 15 ++++++++++++++- src/hb-ot-shape-complex-use.cc | 15 +++++++++++++-- 5 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 6ff19e232..031b39b9b 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -344,10 +344,10 @@ struct hb_ot_apply_context_t : match_glyph_data = nullptr; matcher.set_match_func (nullptr, nullptr); matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ + /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); - /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ - matcher.set_ignore_zwj (c->table_index == 1 || (context_match || c->auto_zwj)); + /* Ignore ZWJ if we are matching context, or asked to. */ + matcher.set_ignore_zwj (context_match || c->auto_zwj); matcher.set_mask (context_match ? -1 : c->lookup_mask); } inline void set_lookup_props (unsigned int lookup_props) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 369078cb2..c1aa1d0fe 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -95,7 +95,8 @@ static const indic_config_t indic_configs[] = * Indic shaper. */ -struct feature_list_t { +struct feature_list_t +{ hb_tag_t tag; hb_ot_map_feature_flags_t flags; }; @@ -130,7 +131,10 @@ indic_features[] = {HB_TAG('b','l','w','s'), F_GLOBAL}, {HB_TAG('p','s','t','s'), F_GLOBAL}, {HB_TAG('h','a','l','n'), F_GLOBAL}, - /* Positioning features, though we don't care about the types. */ + /* + * Positioning features. + * We don't care about the types. + */ {HB_TAG('d','i','s','t'), F_GLOBAL}, {HB_TAG('a','b','v','m'), F_GLOBAL}, {HB_TAG('b','l','w','m'), F_GLOBAL}, @@ -158,12 +162,14 @@ enum { _BLWS, _PSTS, _HALN, + _DIST, _ABVM, _BLWM, INDIC_NUM_FEATURES, - INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */ + INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */ + INDIC_SUBST_FEATURES = _DIST /* Don't forget to update this! */ }; static void @@ -199,14 +205,19 @@ collect_features_indic (hb_ot_shape_planner_t *plan) unsigned int i = 0; map->add_gsub_pause (initial_reordering); + for (; i < INDIC_BASIC_FEATURES; i++) { map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); map->add_gsub_pause (nullptr); } + map->add_gsub_pause (final_reordering); - for (; i < INDIC_NUM_FEATURES; i++) { + + for (; i < INDIC_SUBST_FEATURES; i++) map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); - } + + for (; i < INDIC_NUM_FEATURES; i++) + map->add_feature (indic_features[i].tag, 1, indic_features[i].flags); map->add_global_bool_feature (HB_TAG('c','a','l','t')); map->add_global_bool_feature (HB_TAG('c','l','i','g')); diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 0b5b50a97..7a88aaa25 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -32,7 +32,8 @@ * Khmer shaper. */ -struct feature_list_t { +struct feature_list_t +{ hb_tag_t tag; hb_ot_map_feature_flags_t flags; }; @@ -57,7 +58,10 @@ khmer_features[] = {HB_TAG('a','b','v','s'), F_GLOBAL}, {HB_TAG('b','l','w','s'), F_GLOBAL}, {HB_TAG('p','s','t','s'), F_GLOBAL}, - /* Positioning features, though we don't care about the types. */ + /* + * Positioning features. + * We don't care about the types. + */ {HB_TAG('d','i','s','t'), F_GLOBAL}, {HB_TAG('a','b','v','m'), F_GLOBAL}, {HB_TAG('b','l','w','m'), F_GLOBAL}, @@ -77,12 +81,14 @@ enum { _ABVS, _BLWS, _PSTS, + _DIST, _ABVM, _BLWM, KHMER_NUM_FEATURES, - KHMER_BASIC_FEATURES = _PRES /* Don't forget to update this! */ + KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */ + KHMER_SUBST_FEATURES = _DIST, /* Don't forget to update this! */ }; static void @@ -121,15 +127,16 @@ collect_features_khmer (hb_ot_shape_planner_t *plan) map->add_global_bool_feature (HB_TAG('c','c','m','p')); unsigned int i = 0; - for (; i < KHMER_BASIC_FEATURES; i++) { + for (; i < KHMER_BASIC_FEATURES; i++) map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); - } map->add_gsub_pause (clear_syllables); - for (; i < KHMER_NUM_FEATURES; i++) { + for (; i < KHMER_SUBST_FEATURES; i++) map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); - } + + for (; i < KHMER_NUM_FEATURES; i++) + map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags); map->add_global_bool_feature (HB_TAG('c','a','l','t')); map->add_global_bool_feature (HB_TAG('c','l','i','g')); diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index 8466f8129..8069e3d99 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -54,7 +54,14 @@ other_features[] = HB_TAG('a','b','v','s'), HB_TAG('b','l','w','s'), HB_TAG('p','s','t','s'), - /* Positioning features, though we don't care about the types. */ +}; +static const hb_tag_t +positioning_features[] = +{ + /* + * Positioning features. + * We don't care about the types. + */ HB_TAG('d','i','s','t'), /* Pre-release version of Windows 8 Myanmar font had abvm,blwm * features. The released Windows 8 version of the font (as well @@ -96,14 +103,20 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan) map->add_gsub_pause (initial_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) { map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); map->add_gsub_pause (nullptr); } + map->add_gsub_pause (final_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + + for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++) + map->add_feature (positioning_features[i], 1, F_GLOBAL); } static void diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 676b15b6e..62aef7e6f 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -86,7 +86,14 @@ other_features[] = HB_TAG('h','a','l','n'), HB_TAG('p','r','e','s'), HB_TAG('p','s','t','s'), - /* Positioning features, though we don't care about the types. */ +}; +static const hb_tag_t +positioning_features[] = +{ + /* + * Positioning features. + * We don't care about the types. + */ HB_TAG('d','i','s','t'), HB_TAG('a','b','v','m'), HB_TAG('b','l','w','m'), @@ -146,9 +153,13 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_feature (arabic_features[i], 1, F_NONE); map->add_gsub_pause (nullptr); - /* "Standard typographic presentation" and "Positional feature application" */ + /* "Standard typographic presentation" */ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + + /* "Positional feature application" */ + for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++) + map->add_feature (positioning_features[i], 1, F_GLOBAL); } struct use_shape_plan_t