From 35e28c7a733eaffcd9f062b18d7db9fbb3d990fc Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Sun, 27 Apr 2014 14:05:24 +0100 Subject: [PATCH] rework handling of requiredFeature to solve problem with rlig in arial.ttf from winxp [mozilla bug 986802] --- src/hb-ot-layout.cc | 26 +++++++++++++++----------- src/hb-ot-layout.h | 11 ++++++----- src/hb-ot-map.cc | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 183726e63cf..6181a61c7de 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -321,15 +321,18 @@ hb_ot_layout_script_find_language (hb_face_t *face, } hb_bool_t -hb_ot_layout_language_get_required_feature_index (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - unsigned int language_index, - unsigned int *feature_index) +hb_ot_layout_language_get_required_feature (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_index, + unsigned int language_index, + hb_tag_t *feature_tag, + unsigned int *feature_index) { - const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index); + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); if (feature_index) *feature_index = l.get_required_feature_index (); + if (feature_tag) *feature_tag = g.get_feature_tag (l.get_required_feature_index ()); return l.has_required_feature (); } @@ -468,11 +471,12 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face, if (!features) { unsigned int required_feature_index; - if (hb_ot_layout_language_get_required_feature_index (face, - table_tag, - script_index, - language_index, - &required_feature_index)) + if (hb_ot_layout_language_get_required_feature (face, + table_tag, + script_index, + language_index, + NULL, + &required_feature_index)) _hb_ot_layout_collect_lookups_lookups (face, table_tag, required_feature_index, diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index d90eff374d7..a5585f6219c 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -140,11 +140,12 @@ hb_ot_layout_script_find_language (hb_face_t *face, unsigned int *language_index); hb_bool_t -hb_ot_layout_language_get_required_feature_index (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - unsigned int language_index, - unsigned int *feature_index); +hb_ot_layout_language_get_required_feature (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_index, + unsigned int language_index, + hb_tag_t *feature_tag, + unsigned int *feature_index); unsigned int hb_ot_layout_language_get_feature_indexes (hb_face_t *face, diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 559193c1bae..63b8112addc 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -131,9 +131,19 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) { m.global_mask = 1; + hb_tag_t required_feature_tag[2]; + unsigned int required_feature_index[2]; + for (unsigned int table_index = 0; table_index < 2; table_index++) { m.chosen_script[table_index] = chosen_script[table_index]; m.found_script[table_index] = found_script[table_index]; + + hb_ot_layout_language_get_required_feature (face, + table_tags[table_index], + script_index[table_index], + language_index[table_index], + &required_feature_tag[table_index], + &required_feature_index[table_index]); } if (!feature_infos.len) @@ -183,13 +193,21 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) hb_bool_t found = false; unsigned int feature_index[2]; - for (unsigned int table_index = 0; table_index < 2; table_index++) + for (unsigned int table_index = 0; table_index < 2; table_index++) { + if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX && + required_feature_tag[table_index] == info->tag) { + feature_index[table_index] = required_feature_index[table_index]; + required_feature_index[table_index] = HB_OT_LAYOUT_NO_FEATURE_INDEX; + found = true; + continue; + } found |= hb_ot_layout_language_find_feature (face, table_tags[table_index], script_index[table_index], language_index[table_index], info->tag, &feature_index[table_index]); + } if (!found && !(info->flags & F_HAS_FALLBACK)) continue; @@ -229,13 +247,15 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) /* Collect lookup indices for features */ - unsigned int required_feature_index; - if (hb_ot_layout_language_get_required_feature_index (face, - table_tag, - script_index[table_index], - language_index[table_index], - &required_feature_index)) - m.add_lookups (face, table_index, required_feature_index, 1, true); + /* XXX + * Normally, any required feature will have been handled by the allocate-bits + * loop above. However, if the feature tag was not known among the features + * being applied by the shaper, then it won't have been processed yet - and + * we have no basis for knowing which stage to assign it to. We arbitrarily + * add its lookups here, before everything else, and hope that'll be OK. + */ + if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX) + m.add_lookups (face, table_index, required_feature_index[table_index], 1, true); unsigned int stage_index = 0; unsigned int last_num_lookups = 0;