Add hb_ot_map_feature_flags_t

Code cleanup.  No (intended) functional change.
This commit is contained in:
Behdad Esfahbod 2013-02-14 11:25:10 -05:00
parent e7ffcfafb1
commit ec5448667b
7 changed files with 74 additions and 50 deletions

View File

@ -145,6 +145,27 @@ struct hb_ot_map_t
hb_prealloced_array_t<pause_map_t, 1> pauses[2]; /* GSUB/GPOS */ hb_prealloced_array_t<pause_map_t, 1> pauses[2]; /* GSUB/GPOS */
}; };
enum hb_ot_map_feature_flags_t {
F_NONE = 0x0000,
F_GLOBAL = 0x0001,
F_HAS_FALLBACK = 0x0002
};
inline hb_ot_map_feature_flags_t
operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
inline hb_ot_map_feature_flags_t
operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
inline hb_ot_map_feature_flags_t
operator ~ (hb_ot_map_feature_flags_t r)
{ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
inline hb_ot_map_feature_flags_t&
operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
{ l = l | r; return l; }
inline hb_ot_map_feature_flags_t&
operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
{ l = l & r; return l; }
struct hb_ot_map_builder_t struct hb_ot_map_builder_t
{ {
@ -153,10 +174,11 @@ struct hb_ot_map_builder_t
HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_, HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
const hb_segment_properties_t *props_); const hb_segment_properties_t *props_);
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback = false); HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
hb_ot_map_feature_flags_t flags);
inline void add_global_bool_feature (hb_tag_t tag) inline void add_global_bool_feature (hb_tag_t tag)
{ add_feature (tag, 1, true, false); } { add_feature (tag, 1, F_GLOBAL); }
inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func) inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
{ add_pause (0, pause_func); } { add_pause (0, pause_func); }
@ -177,8 +199,7 @@ struct hb_ot_map_builder_t
hb_tag_t tag; hb_tag_t tag;
unsigned int seq; /* sequence#, used for stable sorting only */ unsigned int seq; /* sequence#, used for stable sorting only */
unsigned int max_value; unsigned int max_value;
bool global; /* whether the feature applies value to every glyph in the buffer */ hb_ot_map_feature_flags_t flags;
bool has_fallback; /* whether to allocate bits even if feature not found */
unsigned int default_value; /* for non-global features, what should the unset glyphs take */ unsigned int default_value; /* for non-global features, what should the unset glyphs take */
unsigned int stage[2]; /* GSUB/GPOS */ unsigned int stage[2]; /* GSUB/GPOS */

View File

@ -84,16 +84,16 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
} }
} }
void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback) void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
hb_ot_map_feature_flags_t flags)
{ {
feature_info_t *info = feature_infos.push(); feature_info_t *info = feature_infos.push();
if (unlikely (!info)) return; if (unlikely (!info)) return;
info->tag = tag; info->tag = tag;
info->seq = feature_infos.len; info->seq = feature_infos.len;
info->max_value = value; info->max_value = value;
info->global = global; info->flags = flags;
info->has_fallback = has_fallback; info->default_value = (flags & F_GLOBAL) ? value : 0;
info->default_value = global ? value : 0;
info->stage[0] = current_stage[0]; info->stage[0] = current_stage[0];
info->stage[1] = current_stage[1]; info->stage[1] = current_stage[1];
} }
@ -176,15 +176,15 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
if (feature_infos[i].tag != feature_infos[j].tag) if (feature_infos[i].tag != feature_infos[j].tag)
feature_infos[++j] = feature_infos[i]; feature_infos[++j] = feature_infos[i];
else { else {
if (feature_infos[i].global) { if (feature_infos[i].flags & F_GLOBAL) {
feature_infos[j].global = true; feature_infos[j].flags |= F_GLOBAL;
feature_infos[j].max_value = feature_infos[i].max_value; feature_infos[j].max_value = feature_infos[i].max_value;
feature_infos[j].default_value = feature_infos[i].default_value; feature_infos[j].default_value = feature_infos[i].default_value;
} else { } else {
feature_infos[j].global = false; feature_infos[j].flags &= ~F_GLOBAL;
feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value); feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
} }
feature_infos[j].has_fallback = feature_infos[j].has_fallback || feature_infos[i].has_fallback; feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]); feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]); feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
/* Inherit default_value from j */ /* Inherit default_value from j */
@ -200,7 +200,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
unsigned int bits_needed; unsigned int bits_needed;
if (info->global && info->max_value == 1) if ((info->flags & F_GLOBAL) && info->max_value == 1)
/* Uses the global bit */ /* Uses the global bit */
bits_needed = 0; bits_needed = 0;
else else
@ -219,7 +219,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
language_index[table_index], language_index[table_index],
info->tag, info->tag,
&feature_index[table_index]); &feature_index[table_index]);
if (!found && !info->has_fallback) if (!found && !(info->flags & F_HAS_FALLBACK))
continue; continue;
@ -232,7 +232,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
map->index[1] = feature_index[1]; map->index[1] = feature_index[1];
map->stage[0] = info->stage[0]; map->stage[0] = info->stage[0];
map->stage[1] = info->stage[1]; map->stage[1] = info->stage[1];
if (info->global && info->max_value == 1) { if ((info->flags & F_GLOBAL) && info->max_value == 1) {
/* Uses the global bit */ /* Uses the global bit */
map->shift = 0; map->shift = 0;
map->mask = 1; map->mask = 1;
@ -240,7 +240,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
map->shift = next_bit; map->shift = next_bit;
map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
next_bit += bits_needed; next_bit += bits_needed;
if (info->global) if ((info->flags & F_GLOBAL))
m.global_mask |= (info->default_value << map->shift) & map->mask; m.global_mask |= (info->default_value << map->shift) & map->mask;
} }
map->_1_mask = (1 << map->shift) & map->mask; map->_1_mask = (1 << map->shift) & map->mask;

View File

@ -184,11 +184,11 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_gsub_pause (NULL); map->add_gsub_pause (NULL);
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
map->add_feature (arabic_features[i], 1, false, i < 4); /* The first four features have fallback. */ map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /* The first four features have fallback. */
map->add_gsub_pause (NULL); map->add_gsub_pause (NULL);
map->add_feature (HB_TAG('r','l','i','g'), 1, true, true); map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
map->add_gsub_pause (arabic_fallback_shape); map->add_gsub_pause (arabic_fallback_shape);
map->add_global_bool_feature (HB_TAG('c','a','l','t')); map->add_global_bool_feature (HB_TAG('c','a','l','t'));

View File

@ -329,7 +329,7 @@ static const indic_config_t indic_configs[] =
struct feature_list_t { struct feature_list_t {
hb_tag_t tag; hb_tag_t tag;
hb_bool_t is_global; hb_ot_map_feature_flags_t flags;
}; };
static const feature_list_t static const feature_list_t
@ -339,32 +339,32 @@ indic_features[] =
* Basic features. * Basic features.
* These features are applied in order, one at a time, after initial_reordering. * These features are applied in order, one at a time, after initial_reordering.
*/ */
{HB_TAG('n','u','k','t'), true}, {HB_TAG('n','u','k','t'), F_GLOBAL},
{HB_TAG('a','k','h','n'), true}, {HB_TAG('a','k','h','n'), F_GLOBAL},
{HB_TAG('r','p','h','f'), false}, {HB_TAG('r','p','h','f'), F_NONE},
{HB_TAG('r','k','r','f'), true}, {HB_TAG('r','k','r','f'), F_GLOBAL},
{HB_TAG('p','r','e','f'), false}, {HB_TAG('p','r','e','f'), F_NONE},
{HB_TAG('b','l','w','f'), false}, {HB_TAG('b','l','w','f'), F_NONE},
{HB_TAG('h','a','l','f'), false}, {HB_TAG('h','a','l','f'), F_NONE},
{HB_TAG('a','b','v','f'), false}, {HB_TAG('a','b','v','f'), F_NONE},
{HB_TAG('p','s','t','f'), false}, {HB_TAG('p','s','t','f'), F_NONE},
{HB_TAG('c','f','a','r'), false}, {HB_TAG('c','f','a','r'), F_NONE},
{HB_TAG('v','a','t','u'), true}, {HB_TAG('v','a','t','u'), F_GLOBAL},
{HB_TAG('c','j','c','t'), true}, {HB_TAG('c','j','c','t'), F_GLOBAL},
/* /*
* Other features. * Other features.
* These features are applied all at once, after final_reordering. * These features are applied all at once, after final_reordering.
*/ */
{HB_TAG('i','n','i','t'), false}, {HB_TAG('i','n','i','t'), F_NONE},
{HB_TAG('p','r','e','s'), true}, {HB_TAG('p','r','e','s'), F_GLOBAL},
{HB_TAG('a','b','v','s'), true}, {HB_TAG('a','b','v','s'), F_GLOBAL},
{HB_TAG('b','l','w','s'), true}, {HB_TAG('b','l','w','s'), F_GLOBAL},
{HB_TAG('p','s','t','s'), true}, {HB_TAG('p','s','t','s'), F_GLOBAL},
{HB_TAG('h','a','l','n'), true}, {HB_TAG('h','a','l','n'), F_GLOBAL},
/* Positioning features, though we don't care about the types. */ /* Positioning features, though we don't care about the types. */
{HB_TAG('d','i','s','t'), true}, {HB_TAG('d','i','s','t'), F_GLOBAL},
{HB_TAG('a','b','v','m'), true}, {HB_TAG('a','b','v','m'), F_GLOBAL},
{HB_TAG('b','l','w','m'), true}, {HB_TAG('b','l','w','m'), F_GLOBAL},
}; };
/* /*
@ -428,12 +428,12 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
unsigned int i = 0; unsigned int i = 0;
map->add_gsub_pause (initial_reordering); map->add_gsub_pause (initial_reordering);
for (; i < INDIC_BASIC_FEATURES; i++) { for (; i < INDIC_BASIC_FEATURES; i++) {
map->add_feature (indic_features[i].tag, 1, indic_features[i].is_global); map->add_feature (indic_features[i].tag, 1, indic_features[i].flags);
map->add_gsub_pause (NULL); map->add_gsub_pause (NULL);
} }
map->add_gsub_pause (final_reordering); map->add_gsub_pause (final_reordering);
for (; i < INDIC_NUM_FEATURES; i++) { for (; i < INDIC_NUM_FEATURES; i++) {
map->add_feature (indic_features[i].tag, 1, indic_features[i].is_global); map->add_feature (indic_features[i].tag, 1, indic_features[i].flags);
} }
} }
@ -442,9 +442,9 @@ override_features_indic (hb_ot_shape_planner_t *plan)
{ {
/* Uniscribe does not apply 'kern'. */ /* Uniscribe does not apply 'kern'. */
if (hb_options ().uniscribe_bug_compatible) if (hb_options ().uniscribe_bug_compatible)
plan->map.add_feature (HB_TAG('k','e','r','n'), 0, true); plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true); plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
} }
@ -532,7 +532,8 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f')); indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'));
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++) for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
indic_plan->mask_array[i] = indic_features[i].is_global ? 0 : plan->map.get_1_mask (indic_features[i].tag); indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
0 : plan->map.get_1_mask (indic_features[i].tag);
return indic_plan; return indic_plan;
} }

View File

@ -119,7 +119,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
static void static void
override_features_myanmar (hb_ot_shape_planner_t *plan) override_features_myanmar (hb_ot_shape_planner_t *plan)
{ {
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true); plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
/* /*
* Note: * Note:
@ -130,7 +130,7 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
* 'mkmk' however. * 'mkmk' however.
*/ */
if (hb_options ().uniscribe_bug_compatible) if (hb_options ().uniscribe_bug_compatible)
plan->map.add_feature (HB_TAG('m','a','r','k'), 0, true); plan->map.add_feature (HB_TAG('m','a','r','k'), 0, F_GLOBAL);
} }

View File

@ -121,7 +121,7 @@ collect_features_sea (hb_ot_shape_planner_t *plan)
static void static void
override_features_sea (hb_ot_shape_planner_t *plan) override_features_sea (hb_ot_shape_planner_t *plan)
{ {
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true); plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
} }

View File

@ -88,7 +88,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
break; break;
case HB_DIRECTION_RTL: case HB_DIRECTION_RTL:
map->add_global_bool_feature (HB_TAG ('r','t','l','a')); map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
map->add_feature (HB_TAG ('r','t','l','m'), 1, false); map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
break; break;
case HB_DIRECTION_TTB: case HB_DIRECTION_TTB:
case HB_DIRECTION_BTT: case HB_DIRECTION_BTT:
@ -120,7 +120,9 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
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, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1)); map->add_feature (feature->tag, feature->value,
(feature->start == 0 && feature->end == (unsigned int) -1) ?
F_GLOBAL : F_NONE);
} }
} }