diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 6cbed8269..ca7245bb2 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -740,7 +740,7 @@ struct StateTableDriver num_glyphs (face_->get_num_glyphs ()) {} template - void drive (context_t *c) + void drive (context_t *c, hb_mask_t mask) { if (!c->in_place) buffer->clear_output (); @@ -753,7 +753,7 @@ struct StateTableDriver (unsigned) StateTableT::CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); const EntryT &entry = machine.get_entry (state, klass); - const int next_state = machine.new_state (entry.newState); + int next_state = machine.new_state (entry.newState); /* Conditions under which it's guaranteed safe-to-break before current glyph: * @@ -822,7 +822,10 @@ struct StateTableDriver if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); - c->transition (this, entry); + if (buffer->cur().mask & mask) + c->transition (this, entry); + else + next_state = StateTableT::STATE_START_OF_TEXT; state = next_state; DEBUG_MSG (APPLY, nullptr, "s%d", state); @@ -864,9 +867,11 @@ struct hb_aat_apply_context_t : const ankr *ankr_table; const OT::GDEF *gdef_table; + hb_mask_t mask; /* Unused. For debug tracing only. */ unsigned int lookup_index; + HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_, hb_font_t *font_, hb_buffer_t *buffer_, @@ -877,6 +882,7 @@ struct hb_aat_apply_context_t : HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_); void set_lookup_index (unsigned int i) { lookup_index = i; } + void set_mask (hb_mask_t mask_) { mask = mask_; } }; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 995492cd5..1e24ea43e 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -350,7 +350,7 @@ struct KerxSubTableFormat1 driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->font->face); - driver.drive (&dc); + driver.drive (&dc, c->mask); return_trace (true); } @@ -594,7 +594,7 @@ struct KerxSubTableFormat4 driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->font->face); - driver.drive (&dc); + driver.drive (&dc, c->mask); return_trace (true); } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 8b9190d0b..32745ef85 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -169,7 +169,7 @@ struct RearrangementSubtable driver_context_t dc (this); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c->mask); return_trace (dc.ret); } @@ -325,7 +325,7 @@ struct ContextualSubtable driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c->mask); return_trace (dc.ret); } @@ -577,7 +577,7 @@ struct LigatureSubtable driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c->mask); return_trace (dc.ret); } @@ -820,7 +820,7 @@ struct InsertionSubtable driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->face); - driver.drive (&dc); + driver.drive (&dc, c->mask); return_trace (dc.ret); } @@ -954,9 +954,11 @@ struct Chain { typedef typename Types::HBUINT HBUINT; - hb_mask_t compile_flags (const hb_aat_map_builder_t *map) const + hb_aat_map_t::chain_info_t compile_info (const hb_aat_map_builder_t *map, + const hb_ot_map_t *ot_map) const { hb_mask_t flags = defaultFlags; + hb_mask_t mask = ot_map->get_global_mask (); { unsigned int count = featureCount; for (unsigned i = 0; i < count; i++) @@ -967,9 +969,11 @@ struct Chain retry: // Check whether this type/setting pair was requested in the map, and if so, apply its flags. // (The search here only looks at the type and setting fields of feature_info_t.) - hb_aat_map_builder_t::feature_info_t info = { type, setting, false, 0 }; - if (map->features.bsearch (info)) + hb_aat_map_builder_t::feature_info_t info = { HB_TAG_NONE, type, setting, false, 0 }; + auto *found = map->features.bsearch (info); + if (found) { + mask = ot_map->get_mask (found->tag); flags &= feature.disableFlags; flags |= feature.enableFlags; } @@ -991,11 +995,14 @@ struct Chain #endif } } - return flags; + hb_aat_map_t::chain_info_t info; + info.flags = flags; + info.mask = mask; + return info; } void apply (hb_aat_apply_context_t *c, - hb_mask_t flags) const + hb_aat_map_t::chain_info_t info) const { const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); unsigned int count = subtableCount; @@ -1003,8 +1010,8 @@ struct Chain { bool reverse; - if (!(subtable->subFeatureFlags & flags)) - goto skip; + //if (!(subtable->subFeatureFlags & info.flags)) + //goto skip; if (!(subtable->get_coverage() & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != @@ -1049,6 +1056,8 @@ struct Chain if (reverse) c->buffer->reverse (); + c->set_mask (info.mask); + subtable->apply (c); if (reverse) @@ -1115,14 +1124,15 @@ struct mortmorx bool has_data () const { return version != 0; } - void compile_flags (const hb_aat_map_builder_t *mapper, - hb_aat_map_t *map) const + void compile_info (const hb_aat_map_builder_t *mapper, + hb_aat_map_t *map, + const hb_ot_map_t *ot_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)); + map->chain_info.push (chain->compile_info (mapper, ot_map)); chain = &StructAfter> (*chain); } } @@ -1135,7 +1145,7 @@ struct mortmorx unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { - chain->apply (c, c->plan->aat_map.chain_flags[i]); + chain->apply (c, c->plan->aat_map.chain_info[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 78427b0d5..51fcfe5ec 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -203,19 +203,20 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, - hb_aat_map_t *map) + hb_aat_map_t *map, + const hb_ot_map_t *ot_map) { const AAT::morx& morx = *mapper->face->table.morx; if (morx.has_data ()) { - morx.compile_flags (mapper, map); + morx.compile_info (mapper, map, ot_map); return; } const AAT::mort& mort = *mapper->face->table.mort; if (mort.has_data ()) { - mort.compile_flags (mapper, map); + mort.compile_info (mapper, map, ot_map); return; } } diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 5e4e3bda1..566c1f899 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -48,7 +48,8 @@ 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_aat_map_t *map, + const hb_ot_map_t *ot_map); HB_INTERNAL void hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index 2c38c3502..139aac552 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -45,6 +45,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value) if (!face->table.feat->exposes_feature (HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES)) return; feature_info_t *info = features.push(); + info->tag = tag; info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; info->setting = (hb_aat_layout_feature_selector_t) value; info->seq = features.length; @@ -58,7 +59,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value) const AAT::FeatureName* feature = &face->table.feat->get_feature (mapping->aatFeatureType); if (!feature->has_data ()) { - /* Special case: Chain::compile_flags will fall back to the deprecated version of + /* Special case: Chain::compile_info will fall back to the deprecated version of * small-caps if necessary, so we need to check for that possibility. * https://github.com/harfbuzz/harfbuzz/issues/2307 */ if (mapping->aatFeatureType == HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE && @@ -71,6 +72,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value) } feature_info_t *info = features.push(); + info->tag = tag; info->type = mapping->aatFeatureType; info->setting = value ? mapping->selectorToEnable : mapping->selectorToDisable; info->seq = features.length; @@ -78,7 +80,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value) } void -hb_aat_map_builder_t::compile (hb_aat_map_t &m) +hb_aat_map_builder_t::compile (hb_aat_map_t &m, const hb_ot_map_t &ot_m) { /* Sort features and merge duplicates */ if (features.length) @@ -95,7 +97,7 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) features.shrink (j + 1); } - hb_aat_layout_compile_map (this, &m); + hb_aat_layout_compile_map (this, &m, &ot_m); } diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index d0ee7d672..1ed916939 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -29,6 +29,8 @@ #include "hb.hh" +#include "hb-ot-map.hh" + struct hb_aat_map_t { @@ -36,15 +38,21 @@ struct hb_aat_map_t public: + struct chain_info_t + { + hb_mask_t flags; + hb_mask_t mask; + }; + void init () { hb_memset (this, 0, sizeof (*this)); - chain_flags.init (); + chain_info.init (); } - void fini () { chain_flags.fini (); } + void fini () { chain_info.fini (); } public: - hb_vector_t chain_flags; + hb_vector_t chain_info; }; struct hb_aat_map_builder_t @@ -58,11 +66,12 @@ struct hb_aat_map_builder_t HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1); - HB_INTERNAL void compile (hb_aat_map_t &m); + HB_INTERNAL void compile (hb_aat_map_t &m, const hb_ot_map_t &ot_m); public: struct feature_info_t { + hb_tag_t tag; hb_aat_layout_feature_type_t type; hb_aat_layout_feature_selector_t setting; bool is_exclusive; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index bbdfc214a..683070944 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -107,7 +107,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, map.compile (plan.map, key); #ifndef HB_NO_AAT_SHAPE if (apply_morx) - aat_map.compile (plan.aat_map); + aat_map.compile (plan.aat_map, plan.map); #endif #ifndef HB_NO_OT_SHAPE_FRACTIONS @@ -397,12 +397,18 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->enable_feature (HB_TAG ('v','e','r','t'), F_GLOBAL_SEARCH); } + hb_ot_map_feature_flags_t flags = F_NONE; +#ifndef HB_NO_AAT_SHAPE + if (planner->apply_morx) + flags |= F_HAS_FALLBACK; // Allocate bits for all user features so AAT planner can use +#endif + for (unsigned int i = 0; i < num_user_features; i++) { const hb_feature_t *feature = &user_features[i]; map->add_feature (feature->tag, - (feature->start == HB_FEATURE_GLOBAL_START && - feature->end == HB_FEATURE_GLOBAL_END) ? F_GLOBAL : F_NONE, + ((feature->start == HB_FEATURE_GLOBAL_START && + feature->end == HB_FEATURE_GLOBAL_END) ? F_GLOBAL : F_NONE) | flags, feature->value); }