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