[HarfBuzz] harfbuzz-ng: Branch 'master' - 6 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Wed Oct 13 12:55:19 PDT 2010
TODO | 4 ++--
src/hb-buffer.cc | 4 ++++
src/hb-ot-map-private.hh | 20 ++++++++++++++------
src/hb-ot-map.cc | 14 ++++++++------
src/hb-ot-shape-complex-arabic.cc | 2 +-
src/hb-ot-shape.cc | 6 +++---
6 files changed, 32 insertions(+), 18 deletions(-)
New commits:
commit 39dede9ffffe732f78cbd092ccb3b48d77ddd66d
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 13 15:54:06 2010 -0400
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.
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 65f57ea..0a1d9f6 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -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);
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 8c696f8..ca96ba9 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -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;
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 74d7125..4055e36 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -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];
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 16bec61..ee5f796 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -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++) {
commit 3506b2e78db27e7835bd2c09c053a9807c9cac40
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 13 15:38:52 2010 -0400
Return early if mask is 0
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index d6e38e9..36a5e13 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -478,6 +478,9 @@ _hb_buffer_add_masks (hb_buffer_t *buffer,
hb_mask_t not_mask = ~mask;
value &= mask;
+ if (!mask)
+ return;
+
if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
commit 5c1c8c9c50ddbe66ea595afb245a208b7775b27c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 13 15:36:38 2010 -0400
Make sure feature values don't leak out of their mask
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 800a34d..d6e38e9 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -476,6 +476,7 @@ _hb_buffer_add_masks (hb_buffer_t *buffer,
unsigned int cluster_end)
{
hb_mask_t not_mask = ~mask;
+ value &= mask;
if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
unsigned int count = buffer->len;
commit 852912fc2db06b6183a2dc87c45ec1b563063572
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 13 15:34:50 2010 -0400
Fix applying default-value for features
Previously if a default global feature was overrided by a non-global
user feature, we were not setting any default mask for the feature,
essentially disabling the feature by default. Fix that.
diff --git a/TODO b/TODO
index efd0a31..0345d4c 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,6 @@
General fixes:
=============
-- Fix feature mask bugs
-
- Fix tt kern on/off
- Remove hb_internal_glyph_info_t, etc
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 8e65f49..65f57ea 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -47,9 +47,10 @@ struct hb_ot_map_t {
struct feature_info_t {
hb_tag_t tag;
- unsigned int value;
- unsigned int seq;
- bool global;
+ unsigned int seq; /* sequence#, used for stable sorting only */
+ unsigned int max_value;
+ bool global; /* whether the feature applies value to every glyph in the buffer */
+ unsigned int default_value; /* for non-global features, what should the unset glyphs take */
static int cmp (const feature_info_t *a, const feature_info_t *b)
{ return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); }
@@ -87,9 +88,10 @@ struct hb_ot_map_t {
{
feature_info_t *info = &feature_infos[feature_count++];
info->tag = tag;
- info->value = value;
info->seq = feature_count;
+ info->max_value = value;
info->global = global;
+ info->default_value = global ? value : 0;
}
inline void add_bool_feature (hb_tag_t tag, bool global = true)
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 94be14f..8c696f8 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -98,7 +98,8 @@ hb_ot_map_t::compile (hb_face_t *face,
feature_infos[j] = feature_infos[i];
else {
feature_infos[j].global = false;
- feature_infos[j].value = MAX (feature_infos[j].value, feature_infos[i].value);
+ feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
+ /* Inherit default_value from j */
}
}
feature_count = j + 1;
@@ -112,13 +113,13 @@ hb_ot_map_t::compile (hb_face_t *face,
unsigned int bits_needed;
- if (info->global && info->value == 1)
+ if (info->global && info->max_value == 1)
/* Uses the global bit */
bits_needed = 0;
else
- bits_needed = _hb_bit_storage (info->value);
+ bits_needed = _hb_bit_storage (info->max_value);
- if (!info->value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
+ if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
continue; /* Feature disabled, or not enough bits. */
@@ -140,7 +141,7 @@ hb_ot_map_t::compile (hb_face_t *face,
map->tag = info->tag;
map->index[0] = feature_index[0];
map->index[1] = feature_index[1];
- if (info->global && info->value == 1) {
+ if (info->global && info->max_value == 1) {
/* Uses the global bit */
map->shift = 0;
map->mask = 1;
@@ -149,7 +150,7 @@ 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 |= map->mask;
+ global_mask |= ((info->default_value << map->shift) & map->mask);
}
}
commit 2989be4919242670c94825bded96db20a7b2035b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 13 15:18:29 2010 -0400
Set user masks after complex masks
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 0ce3896..16bec61 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -86,6 +86,8 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
hb_mask_t global_mask = c->plan->map.get_global_mask ();
c->buffer->reset_masks (global_mask);
+ hb_ot_shape_complex_setup_masks (c);
+
for (unsigned int i = 0; i < c->num_user_features; i++)
{
const hb_feature_t *feature = &c->user_features[i];
@@ -95,8 +97,6 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
c->buffer->add_masks (feature->value << shift, mask, feature->start, feature->end);
}
}
-
- hb_ot_shape_complex_setup_masks (c);
}
commit a7820b7b15a809b4a1a4077147ceed7bea528483
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 13 14:20:48 2010 -0400
Add TODO item
diff --git a/TODO b/TODO
index ffa83c8..efd0a31 100644
--- a/TODO
+++ b/TODO
@@ -9,6 +9,8 @@ General fixes:
- Remove synthesized GDEF
+- Remove fixed-size feature/lookup arrays in hb-ot-map
+
- Use size_t in sanitize
More information about the HarfBuzz
mailing list