Make sure boolean features always use value=1

Previously boolean features turned on the entire feature mask.  This is
wrong if feature is Alternate and user has provided values bigger than one.
Though, I don't think other engines support such corner cases.
This commit is contained in:
Behdad Esfahbod 2010-10-13 15:54:06 -04:00
parent 3506b2e78d
commit 39dede9fff
4 changed files with 12 additions and 5 deletions

View File

@ -61,6 +61,7 @@ struct hb_ot_map_t {
unsigned int index[2]; /* GSUB, GPOS */
unsigned int shift;
hb_mask_t mask;
hb_mask_t _1_mask; /* mask for value=1, for quick access */
static int cmp (const feature_map_t *a, const feature_map_t *b)
{ return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
@ -100,14 +101,19 @@ struct hb_ot_map_t {
HB_INTERNAL void compile (hb_face_t *face,
const hb_segment_properties_t *props);
hb_mask_t get_global_mask (void) const { return global_mask; }
inline hb_mask_t get_global_mask (void) const { return global_mask; }
hb_mask_t get_mask (hb_tag_t tag, unsigned int *shift = NULL) const {
inline hb_mask_t get_mask (hb_tag_t tag, unsigned int *shift = NULL) const {
const feature_map_t *map = (const feature_map_t *) bsearch (&tag, feature_maps, feature_count, sizeof (feature_maps[0]), (hb_compare_func_t) feature_map_t::cmp);
if (shift) *shift = map ? map->shift : 0;
return map ? map->mask : 0;
}
inline hb_mask_t get_1_mask (hb_tag_t tag) const {
const feature_map_t *map = (const feature_map_t *) bsearch (&tag, feature_maps, feature_count, sizeof (feature_maps[0]), (hb_compare_func_t) feature_map_t::cmp);
return map ? map->_1_mask : 0;
}
inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const {
for (unsigned int i = 0; i < lookup_count[0]; i++)
hb_ot_layout_substitute_lookup (face, buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask);

View File

@ -150,8 +150,9 @@ hb_ot_map_t::compile (hb_face_t *face,
map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
next_bit += bits_needed;
if (info->global)
global_mask |= ((info->default_value << map->shift) & map->mask);
global_mask |= (info->default_value << map->shift) & map->mask;
}
map->_1_mask = (1 << map->shift) & map->mask;
}
feature_count = j;

View File

@ -706,7 +706,7 @@ _hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c)
hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
unsigned int num_masks = c->buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
for (unsigned int i = 0; i < num_masks; i++)
mask_array[i] = c->plan->map.get_mask (arabic_syriac_features[i]);
mask_array[i] = c->plan->map.get_1_mask (arabic_syriac_features[i]);
for (unsigned int i = 0; i < count; i++)
c->buffer->info[i].mask |= mask_array[c->buffer->info[i].gproperty];

View File

@ -174,7 +174,7 @@ hb_mirror_chars (hb_ot_shape_context_t *c)
if (HB_DIRECTION_IS_FORWARD (c->buffer->props.direction))
return;
hb_mask_t rtlm_mask = c->plan->map.get_mask (HB_TAG ('r','t','l','m'));
hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++) {