Allow requesting a specific glyph for 'rand'

Randomization only happens by default. If the user specifies a value for
'rand', that value is respected.
This commit is contained in:
David Corbett 2018-01-26 21:36:15 -05:00 committed by Behdad Esfahbod
parent c2a75e07e5
commit f05df643b4
3 changed files with 11 additions and 3 deletions

View File

@ -254,6 +254,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
map->stage[1] = info->stage[1]; map->stage[1] = info->stage[1];
map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ); map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ);
map->auto_zwj = !(info->flags & F_MANUAL_ZWJ); map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
map->random = !!(info->flags & F_RANDOM);
if ((info->flags & F_GLOBAL) && info->max_value == 1) { if ((info->flags & F_GLOBAL) && info->max_value == 1) {
/* Uses the global bit */ /* Uses the global bit */
map->shift = global_bit_shift; map->shift = global_bit_shift;
@ -304,7 +305,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
m.features[i].mask, m.features[i].mask,
m.features[i].auto_zwnj, m.features[i].auto_zwnj,
m.features[i].auto_zwj, m.features[i].auto_zwj,
m.features[i].tag == HB_TAG ('r','a','n','d')); m.features[i].random);
/* Sort lookups and merge duplicates */ /* Sort lookups and merge duplicates */
if (last_num_lookups < m.lookups[table_index].len) if (last_num_lookups < m.lookups[table_index].len)

View File

@ -52,6 +52,7 @@ struct hb_ot_map_t
unsigned int needs_fallback : 1; unsigned int needs_fallback : 1;
unsigned int auto_zwnj : 1; unsigned int auto_zwnj : 1;
unsigned int auto_zwj : 1; unsigned int auto_zwj : 1;
unsigned int random : 1;
inline int cmp (const hb_tag_t *tag_) const inline int cmp (const hb_tag_t *tag_) const
{ return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; } { return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; }
@ -168,7 +169,8 @@ enum hb_ot_map_feature_flags_t {
F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */ F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */
F_MANUAL_ZWNJ = 0x0004u, /* Don't skip over ZWNJ when matching **context**. */ F_MANUAL_ZWNJ = 0x0004u, /* Don't skip over ZWNJ when matching **context**. */
F_MANUAL_ZWJ = 0x0008u, /* Don't skip over ZWJ when matching **input**. */ F_MANUAL_ZWJ = 0x0008u, /* Don't skip over ZWJ when matching **input**. */
F_GLOBAL_SEARCH = 0x0010u /* If feature not found in LangSys, look for it in global feature list and pick one. */ F_GLOBAL_SEARCH = 0x0010u, /* If feature not found in LangSys, look for it in global feature list and pick one. */
F_RANDOM = 0x0020u /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
}; };
HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t); HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t);
/* Macro version for where const is desired. */ /* Macro version for where const is desired. */

View File

@ -49,7 +49,6 @@ static hb_tag_t common_features[] = {
HB_TAG('m','a','r','k'), HB_TAG('m','a','r','k'),
HB_TAG('m','k','m','k'), HB_TAG('m','k','m','k'),
HB_TAG('r','l','i','g'), HB_TAG('r','l','i','g'),
HB_TAG('r','a','n','d'),
}; };
@ -71,6 +70,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
unsigned int num_user_features) unsigned int num_user_features)
{ {
hb_ot_map_builder_t *map = &planner->map; hb_ot_map_builder_t *map = &planner->map;
bool default_rand = true;
map->add_global_bool_feature (HB_TAG('r','v','r','n')); map->add_global_bool_feature (HB_TAG('r','v','r','n'));
map->add_gsub_pause (nullptr); map->add_gsub_pause (nullptr);
@ -123,7 +123,12 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
map->add_feature (feature->tag, feature->value, map->add_feature (feature->tag, feature->value,
(feature->start == 0 && feature->end == (unsigned int) -1) ? (feature->start == 0 && feature->end == (unsigned int) -1) ?
F_GLOBAL : F_NONE); F_GLOBAL : F_NONE);
if (feature->tag == HB_TAG ('r','a','n','d'))
default_rand = false;
} }
if (default_rand)
map->add_feature (HB_TAG ('r','a','n','d'), 1, F_GLOBAL | F_RANDOM);
} }