Make sure boolean features always use value=1
authorBehdad Esfahbod <behdad@behdad.org>
Wed, 13 Oct 2010 19:54:06 +0000 (15:54 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 13 Oct 2010 19:54:06 +0000 (15:54 -0400)
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.

src/hb-ot-map-private.hh
src/hb-ot-map.cc
src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape.cc

index 65f57ea..0a1d9f6 100644 (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);
index 8c696f8..ca96ba9 100644 (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;
index 74d7125..4055e36 100644 (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];
index 16bec61..ee5f796 100644 (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++) {