From ffe347844803a6a9036d8357b744a982f5e5a6c9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 14:14:03 -0700 Subject: [PATCH] [aat] Allow enabling/disabling features Only works at entire-buffer range, not sub-ranges. Test with: $ hb-shape Zapfino.dfont Zapfino [Z_a_p_f_i_n_o=0+2333] $ hb-shape Zapfino.dfont Zapfino --features=-dlig [Z=0+416|a=1@-21,0+264|p_f=2+433|i=4+181|n=5+261|o=6+250] $ hb-shape Zapfino.dfont Zapfino --features=+dlig [Z_a_p_f_i_n_o=0+2333] Fixes https://github.com/harfbuzz/harfbuzz/issues/1303 --- src/Makefile.sources | 2 ++ src/hb-aat-layout-morx-table.hh | 29 +++++++++++++++++++++++++---- src/hb-aat-layout.cc | 8 ++++++++ src/hb-aat-layout.hh | 3 +++ src/hb-ot-shape.cc | 4 ++++ src/hb-ot-shape.hh | 5 +++++ 6 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/Makefile.sources b/src/Makefile.sources index 72968aee9..e13bd4f09 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -101,6 +101,8 @@ HB_OT_sources = \ hb-aat-layout-trak-table.hh \ hb-aat-layout.hh \ hb-aat-ltag-table.hh \ + hb-aat-map.cc \ + hb-aat-map.hh \ hb-ot-face.hh \ hb-ot-face.cc \ hb-ot-font.cc \ diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 5577efe86..ff791cb7f 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" #include "hb-ot-layout-common.hh" +#include "hb-aat-map.hh" /* * morx -- Extended Glyph Metamorphosis @@ -839,9 +840,9 @@ struct ChainSubtable struct Chain { - inline void apply (hb_aat_apply_context_t *c) const + inline hb_mask_t compile_flags (const hb_aat_map_builder_t *map) const { - uint32_t flags = defaultFlags; + hb_mask_t flags = defaultFlags; { /* Compute applicable flags. TODO Should move this to planning * stage and take user-requested features into account. */ @@ -849,14 +850,22 @@ struct Chain for (unsigned i = 0; i < count; i++) { const Feature &feature = featureZ[i]; - if (false) /* XXX Check if feature enabled... */ + uint16_t type = feature.featureType; + uint16_t setting = feature.featureSetting; + const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch (type); + if (info && info->setting == setting) { flags &= feature.disableFlags; flags |= feature.enableFlags; } } } + return flags; + } + inline void apply (hb_aat_apply_context_t *c, + hb_mask_t flags) const + { const ChainSubtable *subtable = &StructAtOffset (&featureZ, featureZ[0].static_size * featureCount); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) @@ -976,6 +985,18 @@ struct morx inline bool has_data (void) const { return version != 0; } + inline void compile_flags (const hb_aat_map_builder_t *mapper, + hb_aat_map_t *map) const + { + const Chain *chain = &firstChain; + unsigned int count = chainCount; + for (unsigned int i = 0; i < count; i++) + { + map->chain_flags.push (chain->compile_flags (mapper)); + chain = &StructAfter (*chain); + } + } + inline void apply (hb_aat_apply_context_t *c) const { if (unlikely (!c->buffer->successful)) return; @@ -984,7 +1005,7 @@ struct morx unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { - chain->apply (c); + chain->apply (c, c->plan->aat_map.chain_flags[i]); if (unlikely (!c->buffer->successful)) return; chain = &StructAfter (*chain); } diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index e9da850b3..1e1c7b4f4 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -183,6 +183,14 @@ _get_trak (hb_face_t *face) } +void +hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, + hb_aat_map_t *map) +{ + _get_morx (mapper->face).compile_flags (mapper, map); +} + + hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face) { diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index d0eb0190d..aea545689 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -52,6 +52,9 @@ struct hb_aat_feature_mapping_t HB_INTERNAL const hb_aat_feature_mapping_t * hb_aat_layout_find_feature_mapping (hb_tag_t tag); +HB_INTERNAL void +hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, + hb_aat_map_t *map); HB_INTERNAL hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face); diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 0de182f4c..23da56c2f 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -57,6 +57,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan face (master_plan->face_unsafe), props (master_plan->props), map (face, &props), + aat_map (face, &props), apply_morx (_hb_apply_morx (face)), shaper (apply_morx ? &_hb_ot_complex_shaper_default : @@ -70,6 +71,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.props = props; plan.shaper = shaper; map.compile (plan.map, coords, num_coords); + aat_map.compile (plan.aat_map, coords, num_coords); plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r')); @@ -160,6 +162,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, unsigned int num_user_features) { hb_ot_map_builder_t *map = &planner->map; + hb_aat_map_builder_t *aat_map = &planner->aat_map; map->enable_feature (HB_TAG('r','v','r','n')); map->add_gsub_pause (nullptr); @@ -225,6 +228,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, (feature->start == HB_FEATURE_GLOBAL_START && feature->end == HB_FEATURE_GLOBAL_END) ? F_GLOBAL : F_NONE, feature->value); + aat_map->add_feature (feature->tag, feature->value); } } diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh index 3fa594a85..e7d6204a8 100644 --- a/src/hb-ot-shape.hh +++ b/src/hb-ot-shape.hh @@ -30,6 +30,7 @@ #include "hb.hh" #include "hb-ot-map.hh" +#include "hb-aat-map.hh" #include "hb-shape-plan.hh" @@ -39,6 +40,7 @@ struct hb_ot_shape_plan_t hb_segment_properties_t props; const struct hb_ot_complex_shaper_t *shaper; hb_ot_map_t map; + hb_aat_map_t aat_map; const void *data; hb_mask_t frac_mask, numr_mask, dnom_mask; hb_mask_t rtlm_mask; @@ -77,9 +79,11 @@ struct hb_ot_shape_plan_t { memset (this, 0, sizeof (*this)); map.init (); + aat_map.init (); } void fini (void) { map.fini (); + aat_map.fini (); } }; @@ -89,6 +93,7 @@ struct hb_ot_shape_planner_t hb_face_t *face; hb_segment_properties_t props; hb_ot_map_builder_t map; + hb_aat_map_builder_t aat_map; bool apply_morx : 1; const struct hb_ot_complex_shaper_t *shaper;