[HarfBuzz] harfbuzz-ng: Branch 'master' - 11 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu May 5 12:15:01 PDT 2011
TODO | 9 ---
src/hb-common.cc | 52 +++++++++-----------
src/hb-mutex-private.hh | 54 +++++++++++++++++++++
src/hb-object-private.hh | 32 +++++++-----
src/hb-ot-map-private.hh | 26 +++-------
src/hb-ot-map.cc | 66 +++++++++++++-------------
src/hb-ot-shape.cc | 2
src/hb-private.hh | 119 ++++++++++++++++++++++++++++-------------------
test/test-object.c | 4 +
9 files changed, 221 insertions(+), 143 deletions(-)
New commits:
commit b8d6183ebc4697a434776cf2aec7857d63a7d881
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 15:14:04 2011 -0400
Use threadsafe set implementation for hb_language lookups
Note that the static variable has to be a global static, as gcc
implements local statics differently and that would require linking
to libstdc++, which we don't want.
diff --git a/src/hb-common.cc b/src/hb-common.cc
index 67988c3..368789a 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -28,6 +28,8 @@
#include "hb-private.hh"
+#include "hb-mutex-private.hh"
+
HB_BEGIN_DECLS
@@ -155,11 +157,11 @@ struct hb_language_item_t {
void finish (void) { free (lang); }
};
+static hb_threadsafe_set_t<hb_language_item_t> langs;
+
hb_language_t
hb_language_from_string (const char *str)
{
- static hb_set_t<hb_language_item_t> langs;
-
if (!str || !*str)
return NULL;
commit d37486d87b65c5abaaa2998fa5c9e48eedde0933
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 15:07:54 2011 -0400
Add hb_threadsafe_set_t
diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh
index cf5beb1..65e5892 100644
--- a/src/hb-mutex-private.hh
+++ b/src/hb-mutex-private.hh
@@ -110,4 +110,58 @@ struct hb_static_mutex_t : hb_mutex_t
HB_END_DECLS
+
+template <typename item_t>
+struct hb_threadsafe_set_t
+{
+ hb_set_t <item_t> set;
+ hb_static_mutex_t mutex;
+
+ template <typename T>
+ inline item_t *insert (T v)
+ {
+ hb_mutex_lock (&mutex);
+ item_t *item = set.insert (v);
+ hb_mutex_unlock (&mutex);
+ return item;
+ }
+
+ template <typename T>
+ inline void remove (T v)
+ {
+ hb_mutex_lock (&mutex);
+ set.remove (v);
+ hb_mutex_unlock (&mutex);
+ }
+
+ template <typename T>
+ inline item_t *find (T v)
+ {
+ hb_mutex_lock (&mutex);
+ item_t *item = set.find (v);
+ hb_mutex_unlock (&mutex);
+ return item;
+ }
+
+ template <typename T>
+ inline item_t *find_or_insert (T v) {
+ hb_mutex_lock (&mutex);
+ item_t *item = set.find_or_insert (v);
+ hb_mutex_unlock (&mutex);
+ return item;
+ }
+
+ void finish (void) {
+ hb_mutex_lock (&mutex);
+ set.finish ();
+ hb_mutex_unlock (&mutex);
+ }
+
+};
+
+
+HB_BEGIN_DECLS
+
+HB_END_DECLS
+
#endif /* HB_MUTEX_PRIVATE_HH */
diff --git a/src/hb-private.hh b/src/hb-private.hh
index d31e014..577389d 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -324,8 +324,6 @@ struct hb_set_t
{
hb_array_t <item_t> items;
- public:
-
template <typename T>
inline item_t *insert (T v)
{
@@ -370,6 +368,7 @@ struct hb_set_t
void finish (void) {
for (unsigned i = 0; i < items.len; i++)
items[i].finish ();
+ items.shrink (0);
}
};
commit b45f32ee4e599c515ce93e44315283d236b073bb
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 15:00:43 2011 -0400
Use hb_array_t for hb_language_t mapping
diff --git a/src/hb-common.cc b/src/hb-common.cc
index b75146d..67988c3 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -136,40 +136,36 @@ lang_hash (const void *key)
#endif
+struct hb_language_item_t {
+
+ hb_language_t lang;
+
+ inline bool operator == (const char *s) const {
+ return lang_equal (lang, s);
+ }
+
+ inline hb_language_item_t & operator = (const char *s) {
+ lang = (hb_language_t) strdup (s);
+ for (unsigned char *p = (unsigned char *) lang; *p; p++)
+ *p = canon_map[*p];
+
+ return *this;
+ }
+
+ void finish (void) { free (lang); }
+};
+
hb_language_t
hb_language_from_string (const char *str)
{
- static unsigned int num_langs;
- static unsigned int num_alloced;
- static hb_language_t *langs;
- unsigned int i;
- unsigned char *p;
-
- /* TODO Use a hash table or something */
+ static hb_set_t<hb_language_item_t> langs;
if (!str || !*str)
return NULL;
- for (i = 0; i < num_langs; i++)
- if (lang_equal (str, langs[i]->s))
- return langs[i];
-
- if (unlikely (num_langs == num_alloced)) {
- unsigned int new_alloced = 2 * (8 + num_alloced);
- hb_language_t *new_langs = (hb_language_t *) realloc (langs, new_alloced * sizeof (langs[0]));
- if (!new_langs)
- return NULL;
- num_alloced = new_alloced;
- langs = new_langs;
- }
-
- langs[i] = (hb_language_t) strdup (str);
- for (p = (unsigned char *) langs[i]->s; *p; p++)
- *p = canon_map[*p];
-
- num_langs++;
+ hb_language_item_t *item = langs.find_or_insert (str);
- return langs[i];
+ return likely (item) ? item->lang : NULL;
}
const char *
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 1add2e7..dc7dba9 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -132,11 +132,11 @@ struct hb_user_data_array_t {
return true;
}
hb_user_data_item_t item = {key, data, destroy};
- return items.insert (item);
+ return !!items.insert (item);
}
inline void *get (hb_user_data_key_t *key) {
- hb_user_data_item_t *item = items.get (key);
+ hb_user_data_item_t *item = items.find (key);
return item ? item->data : NULL;
}
diff --git a/src/hb-private.hh b/src/hb-private.hh
index c37518d..d31e014 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -327,16 +327,16 @@ struct hb_set_t
public:
template <typename T>
- inline bool insert (T v)
+ inline item_t *insert (T v)
{
item_t *item = items.find (v);
if (item)
item->finish ();
else
item = items.push ();
- if (unlikely (!item)) return false;
+ if (unlikely (!item)) return NULL;
*item = v;
- return true;
+ return item;
}
template <typename T>
@@ -351,11 +351,22 @@ struct hb_set_t
}
template <typename T>
- inline item_t *get (T v)
+ inline item_t *find (T v)
{
return items.find (v);
}
+ template <typename T>
+ inline item_t *find_or_insert (T v) {
+ item_t *item = find (v);
+ if (!item) {
+ item = items.push ();
+ if (likely (item))
+ *item = v;
+ }
+ return item;
+ }
+
void finish (void) {
for (unsigned i = 0; i < items.len; i++)
items[i].finish ();
commit 21d2c92fdf7307c7117f8948021f0dd7d5a5d2a3
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 14:47:53 2011 -0400
Move code around
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index ffe87b4..1add2e7 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -106,20 +106,20 @@ typedef struct {
/* XXX make this thread-safe, somehow! */
-struct hb_user_data_t {
- hb_user_data_key_t *key;
- void *data;
- hb_destroy_func_t destroy;
+struct hb_user_data_array_t {
- inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
- inline bool operator == (hb_user_data_t &other) const { return key == other.key; }
+ struct hb_user_data_item_t {
+ hb_user_data_key_t *key;
+ void *data;
+ hb_destroy_func_t destroy;
- void finish (void) { if (destroy) destroy (data); }
-};
+ inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
+ inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
-struct hb_user_data_array_t {
+ void finish (void) { if (destroy) destroy (data); }
+ };
- hb_set_t<hb_user_data_t> items;
+ hb_set_t<hb_user_data_item_t> items;
inline bool set (hb_user_data_key_t *key,
void * data,
@@ -131,13 +131,13 @@ struct hb_user_data_array_t {
items.remove (key);
return true;
}
- hb_user_data_t user_data = {key, data, destroy};
- return items.insert (user_data);
+ hb_user_data_item_t item = {key, data, destroy};
+ return items.insert (item);
}
inline void *get (hb_user_data_key_t *key) {
- hb_user_data_t *user_data = items.get (key);
- return user_data ? user_data->data : NULL;
+ hb_user_data_item_t *item = items.get (key);
+ return item ? item->data : NULL;
}
void finish (void) { items.finish (); }
commit 448ea9bf63104d39f87fff66219034222fa632b8
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 14:39:24 2011 -0400
[TODO] Remove done items
diff --git a/TODO b/TODO
index e95dd4f..1152d5e 100644
--- a/TODO
+++ b/TODO
@@ -7,8 +7,6 @@ General fixes:
- Fix tt kern on/off and GPOS interaction
-- Remove fixed-size feature/lookup arrays in hb-ot-map
-
API issues to fix before 1.0:
============================
@@ -52,16 +50,9 @@ hb-view enhancements:
- Add XML and JSON formats
-Build fixes:
-===========
-
-- GNOME Bug 612402 - (hb-arm) HarfBuzz compilation fix for arm
-
-
Optimizations:
=============
- Avoid allocating blob objects internally for for_data() faces?
- Add caching layer to hb-ft
-
commit 265ac614ea6d26041c7d64739098b76a82bbc4f4
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 14:38:16 2011 -0400
Replace fixed-size lookup_maps array with hb_array_t
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index bd4e868..2a74138 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -36,8 +36,6 @@
HB_BEGIN_DECLS
-#define MAX_LOOKUPS 1000 /* FIXME */
-
static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
struct hb_ot_map_t {
@@ -113,12 +111,12 @@ struct hb_ot_map_t {
}
inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const {
- for (unsigned int i = 0; i < lookup_count[0]; i++)
+ for (unsigned int i = 0; i < lookup_maps[0].len; i++)
hb_ot_layout_substitute_lookup (face, buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask);
}
inline void position (hb_font_t *font, hb_face_t *face, hb_buffer_t *buffer) const {
- for (unsigned int i = 0; i < lookup_count[1]; i++)
+ for (unsigned int i = 0; i < lookup_maps[1].len; i++)
hb_ot_layout_position_lookup (font, buffer, lookup_maps[1][i].index, lookup_maps[1][i].mask);
}
@@ -126,11 +124,10 @@ struct hb_ot_map_t {
hb_mask_t global_mask;
- hb_prealloced_array_t<feature_info_t,16> feature_infos; /* used before compile() only */
- hb_prealloced_array_t<feature_map_t, 16> feature_maps;
+ hb_prealloced_array_t<feature_info_t,8> feature_infos; /* used before compile() only */
+ hb_prealloced_array_t<feature_map_t, 8> feature_maps;
- lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */
- unsigned int lookup_count[2];
+ hb_prealloced_array_t<lookup_map_t, 32> lookup_maps[2]; /* GSUB/GPOS */
};
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 04f41ee..9006bf9 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -39,23 +39,28 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
unsigned int feature_index,
hb_mask_t mask)
{
- unsigned int i = MAX_LOOKUPS - lookup_count[table_index];
- lookup_map_t *lookups = lookup_maps[table_index] + lookup_count[table_index];
-
- unsigned int *lookup_indices = (unsigned int *) lookups;
-
- hb_ot_layout_feature_get_lookup_indexes (face,
- table_tags[table_index],
- feature_index,
- 0, &i,
- lookup_indices);
-
- lookup_count[table_index] += i;
+ unsigned int lookup_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (lookup_indices);
+ hb_ot_layout_feature_get_lookup_indexes (face,
+ table_tags[table_index],
+ feature_index,
+ offset, &len,
+ lookup_indices);
+
+ for (unsigned int i = 0; i < len; i++) {
+ lookup_map_t *lookup = lookup_maps[table_index].push ();
+ if (unlikely (!lookup))
+ return;
+ lookup->mask = mask;
+ lookup->index = lookup_indices[i];
+ }
- while (i--) {
- lookups[i].mask = mask;
- lookups[i].index = lookup_indices[i];
- }
+ offset += len;
+ } while (len == ARRAY_LENGTH (lookup_indices));
}
@@ -64,7 +69,6 @@ hb_ot_map_t::compile (hb_face_t *face,
const hb_segment_properties_t *props)
{
global_mask = 1;
- lookup_count[0] = lookup_count[1] = 0;
if (!feature_infos.len)
return;
@@ -176,17 +180,16 @@ hb_ot_map_t::compile (hb_face_t *face,
add_lookups (face, table_index, feature_maps[i].index[table_index], feature_maps[i].mask);
/* Sort lookups and merge duplicates */
- qsort (lookup_maps[table_index], lookup_count[table_index], sizeof (lookup_maps[table_index][0]), (hb_compare_func_t) lookup_map_t::cmp);
- if (lookup_count[table_index])
+ lookup_maps[table_index].sort ();
+ if (lookup_maps[table_index].len)
{
unsigned int j = 0;
- for (unsigned int i = 1; i < lookup_count[table_index]; i++)
+ for (unsigned int i = 1; i < lookup_maps[table_index].len; i++)
if (lookup_maps[table_index][i].index != lookup_maps[table_index][j].index)
lookup_maps[table_index][++j] = lookup_maps[table_index][i];
else
lookup_maps[table_index][j].mask |= lookup_maps[table_index][i].mask;
- j++;
- lookup_count[table_index] = j;
+ lookup_maps[table_index].shrink (j + 1);
}
}
}
diff --git a/src/hb-private.hh b/src/hb-private.hh
index e776daf..c37518d 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -235,10 +235,8 @@ struct hb_prealloced_array_t {
Type *array;
Type static_array[StaticSize];
- inline Type& operator [] (unsigned int i)
- {
- return array[i];
- }
+ inline Type& operator [] (unsigned int i) { return array[i]; }
+ inline const Type& operator [] (unsigned int i) const { return array[i]; }
inline Type *push (void)
{
commit 6843569d2c70c1771ce964e3d1a4cf91e14e7687
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 14:12:37 2011 -0400
Replace fixed-size feature_maps array with hb_array_t
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 3b0cc19..bd4e868 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -82,8 +82,6 @@ struct hb_ot_map_t {
public:
- hb_ot_map_t (void) : feature_count (0) {}
-
void add_feature (hb_tag_t tag, unsigned int value, bool global)
{
feature_info_t *info = feature_infos.push();
@@ -104,13 +102,13 @@ struct hb_ot_map_t {
inline hb_mask_t get_global_mask (void) const { return global_mask; }
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);
+ const feature_map_t *map = feature_maps.bsearch (&tag);
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);
+ const feature_map_t *map = feature_maps.bsearch (&tag);
return map ? map->_1_mask : 0;
}
@@ -128,10 +126,8 @@ struct hb_ot_map_t {
hb_mask_t global_mask;
- unsigned int feature_count;
hb_prealloced_array_t<feature_info_t,16> feature_infos; /* used before compile() only */
-#define MAX_FEATURES 100
- feature_map_t feature_maps[MAX_FEATURES];
+ hb_prealloced_array_t<feature_map_t, 16> feature_maps;
lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */
unsigned int lookup_count[2];
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index d313da7..04f41ee 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -106,10 +106,8 @@ hb_ot_map_t::compile (hb_face_t *face,
/* Allocate bits now */
- feature_count = feature_infos.len;
unsigned int next_bit = 1;
- j = 0;
- for (unsigned int i = 0; i < feature_count; i++) {
+ for (unsigned int i = 0; i < feature_infos.len; i++) {
const feature_info_t *info = &feature_infos[i];
unsigned int bits_needed;
@@ -137,7 +135,9 @@ hb_ot_map_t::compile (hb_face_t *face,
continue;
- feature_map_t *map = &feature_maps[j++];
+ feature_map_t *map = feature_maps.push ();
+ if (unlikely (!map))
+ break;
map->tag = info->tag;
map->index[0] = feature_index[0];
@@ -156,7 +156,7 @@ hb_ot_map_t::compile (hb_face_t *face,
map->_1_mask = (1 << map->shift) & map->mask;
}
- feature_count = j;
+ feature_infos.shrink (0); /* Done with these */
for (unsigned int table_index = 0; table_index < 2; table_index++) {
@@ -172,7 +172,7 @@ hb_ot_map_t::compile (hb_face_t *face,
&required_feature_index))
add_lookups (face, table_index, required_feature_index, 1);
- for (unsigned i = 0; i < feature_count; i++)
+ for (unsigned i = 0; i < feature_maps.len; i++)
add_lookups (face, table_index, feature_maps[i].index[table_index], feature_maps[i].mask);
/* Sort lookups and merge duplicates */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index e01f372..306bb41 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -370,7 +370,7 @@ hb_ot_shape (hb_font_t *font,
const hb_feature_t *features,
unsigned int num_features)
{
- hb_ot_shape_plan_t plan;
+ hb_ot_shape_plan_t plan = hb_ot_shape_plan_t ();
hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features);
hb_ot_shape_execute (&plan, font, buffer, features, num_features);
diff --git a/src/hb-private.hh b/src/hb-private.hh
index d3edad3..e776daf 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -285,10 +285,36 @@ struct hb_prealloced_array_t {
/* TODO: shrink array if needed */
}
+ template <typename T>
+ inline Type *find (T v) {
+ for (unsigned int i = 0; i < len; i++)
+ if (array[i] == v)
+ return &array[i];
+ return NULL;
+ }
+ template <typename T>
+ inline const Type *find (T v) const {
+ for (unsigned int i = 0; i < len; i++)
+ if (array[i] == v)
+ return &array[i];
+ return NULL;
+ }
+
inline void sort (void)
{
qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
}
+
+ template <typename T>
+ inline Type *bsearch (T *key)
+ {
+ return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ }
+ template <typename T>
+ inline const Type *bsearch (T *key) const
+ {
+ return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ }
};
template <typename Type>
@@ -300,22 +326,12 @@ struct hb_set_t
{
hb_array_t <item_t> items;
- private:
-
- template <typename T>
- inline item_t *find (T v) {
- for (unsigned int i = 0; i < items.len; i++)
- if (items[i] == v)
- return &items[i];
- return NULL;
- }
-
public:
template <typename T>
inline bool insert (T v)
{
- item_t *item = find (v);
+ item_t *item = items.find (v);
if (item)
item->finish ();
else
@@ -328,7 +344,7 @@ struct hb_set_t
template <typename T>
inline void remove (T v)
{
- item_t *item = find (v);
+ item_t *item = items.find (v);
if (!item) return;
item->finish ();
@@ -339,7 +355,7 @@ struct hb_set_t
template <typename T>
inline item_t *get (T v)
{
- return find (v);
+ return items.find (v);
}
void finish (void) {
commit 44b0a4d2fc62689fc56ef57f412b4bb1e439a614
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 13:42:19 2011 -0400
Replace fixed-size feature_infos array with hb_array_t
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index e0fe51b..3b0cc19 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -36,7 +36,6 @@
HB_BEGIN_DECLS
-#define MAX_FEATURES 100 /* FIXME */
#define MAX_LOOKUPS 1000 /* FIXME */
static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
@@ -87,9 +86,10 @@ struct hb_ot_map_t {
void add_feature (hb_tag_t tag, unsigned int value, bool global)
{
- feature_info_t *info = &feature_infos[feature_count++];
+ feature_info_t *info = feature_infos.push();
+ if (unlikely (!info)) return;
info->tag = tag;
- info->seq = feature_count;
+ info->seq = feature_infos.len;
info->max_value = value;
info->global = global;
info->default_value = global ? value : 0;
@@ -129,7 +129,8 @@ struct hb_ot_map_t {
hb_mask_t global_mask;
unsigned int feature_count;
- feature_info_t feature_infos[MAX_FEATURES]; /* used before compile() only */
+ hb_prealloced_array_t<feature_info_t,16> feature_infos; /* used before compile() only */
+#define MAX_FEATURES 100
feature_map_t feature_maps[MAX_FEATURES];
lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 9b15305..d313da7 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -66,7 +66,7 @@ hb_ot_map_t::compile (hb_face_t *face,
global_mask = 1;
lookup_count[0] = lookup_count[1] = 0;
- if (!feature_count)
+ if (!feature_infos.len)
return;
@@ -88,9 +88,9 @@ hb_ot_map_t::compile (hb_face_t *face,
/* Sort features and merge duplicates */
- qsort (feature_infos, feature_count, sizeof (feature_infos[0]), (hb_compare_func_t) feature_info_t::cmp);
+ feature_infos.sort ();
unsigned int j = 0;
- for (unsigned int i = 1; i < feature_count; i++)
+ for (unsigned int i = 1; i < feature_infos.len; i++)
if (feature_infos[i].tag != feature_infos[j].tag)
feature_infos[++j] = feature_infos[i];
else {
@@ -102,10 +102,11 @@ hb_ot_map_t::compile (hb_face_t *face,
/* Inherit default_value from j */
}
}
- feature_count = j + 1;
+ feature_infos.shrink (j + 1);
/* Allocate bits now */
+ feature_count = feature_infos.len;
unsigned int next_bit = 1;
j = 0;
for (unsigned int i = 0; i < feature_count; i++) {
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 26e0a69..d3edad3 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -277,6 +277,18 @@ struct hb_prealloced_array_t {
len--;
/* TODO: shrink array if needed */
}
+
+ inline void shrink (unsigned int l)
+ {
+ if (l < len)
+ len = l;
+ /* TODO: shrink array if needed */
+ }
+
+ inline void sort (void)
+ {
+ qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ }
};
template <typename Type>
commit b214ec3ac0ce6568e9226fd09661d52de11dca96
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 13:24:07 2011 -0400
Minor
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 28c33b7..26e0a69 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -228,7 +228,7 @@ HB_END_DECLS
template <typename Type, unsigned int StaticSize>
-struct hb_static_array_t {
+struct hb_prealloced_array_t {
unsigned int len;
unsigned int allocated;
@@ -280,7 +280,7 @@ struct hb_static_array_t {
};
template <typename Type>
-struct hb_array_t : hb_static_array_t<Type, 2> {};
+struct hb_array_t : hb_prealloced_array_t<Type, 2> {};
template <typename item_t>
commit 811482bd650fb5652a9835471ae8ecf0fb185611
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 13:21:04 2011 -0400
Replace hb_map_t with hb_set_t which is more intuitive and flexible
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 77e0089..ffe87b4 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -106,37 +106,41 @@ typedef struct {
/* XXX make this thread-safe, somehow! */
-typedef struct {
+struct hb_user_data_t {
+ hb_user_data_key_t *key;
void *data;
hb_destroy_func_t destroy;
+ inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
+ inline bool operator == (hb_user_data_t &other) const { return key == other.key; }
+
void finish (void) { if (destroy) destroy (data); }
-} hb_user_data_t;
+};
struct hb_user_data_array_t {
- hb_map_t<hb_user_data_key_t *, hb_user_data_t> map;
+ hb_set_t<hb_user_data_t> items;
inline bool set (hb_user_data_key_t *key,
void * data,
hb_destroy_func_t destroy)
{
+ if (!key)
+ return false;
if (!data && !destroy) {
- map.unset (key);
+ items.remove (key);
return true;
}
- if (!key)
- return false;
- hb_user_data_t user_data = {data, destroy};
- return map.set (key, user_data);
+ hb_user_data_t user_data = {key, data, destroy};
+ return items.insert (user_data);
}
inline void *get (hb_user_data_key_t *key) {
- hb_user_data_t *user_data = map.get (key);
+ hb_user_data_t *user_data = items.get (key);
return user_data ? user_data->data : NULL;
}
- void finish (void) { map.finish (); }
+ void finish (void) { items.finish (); }
};
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 9a23cd3..28c33b7 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -235,8 +235,6 @@ struct hb_static_array_t {
Type *array;
Type static_array[StaticSize];
- void finish (void) { for (unsigned i = 0; i < len; i++) array[i].finish (); }
-
inline Type& operator [] (unsigned int i)
{
return array[i];
@@ -285,25 +283,17 @@ template <typename Type>
struct hb_array_t : hb_static_array_t<Type, 2> {};
-template <typename Key, typename Value>
-struct hb_map_t
+template <typename item_t>
+struct hb_set_t
{
- struct item_t {
- Key key;
- /* unsigned int hash; */
- Value value;
-
- void finish (void) { value.finish (); }
- };
-
hb_array_t <item_t> items;
private:
template <typename T>
- inline item_t *find (T key) {
+ inline item_t *find (T v) {
for (unsigned int i = 0; i < items.len; i++)
- if (items[i].key == key)
+ if (items[i] == v)
return &items[i];
return NULL;
}
@@ -311,25 +301,22 @@ struct hb_map_t
public:
template <typename T>
- inline bool set (T key,
- Value &value)
+ inline bool insert (T v)
{
- item_t *item;
- item = find (key);
+ item_t *item = find (v);
if (item)
item->finish ();
else
item = items.push ();
if (unlikely (!item)) return false;
- item->key = key;
- item->value = value;
+ *item = v;
return true;
}
- inline void unset (Key &key)
+ template <typename T>
+ inline void remove (T v)
{
- item_t *item;
- item = find (key);
+ item_t *item = find (v);
if (!item) return;
item->finish ();
@@ -338,13 +325,16 @@ struct hb_map_t
}
template <typename T>
- inline Value *get (T key)
+ inline item_t *get (T v)
{
- item_t *item = find (key);
- return item ? &item->value : NULL;
+ return find (v);
+ }
+
+ void finish (void) {
+ for (unsigned i = 0; i < items.len; i++)
+ items[i].finish ();
}
- void finish (void) { items.finish (); }
};
diff --git a/test/test-object.c b/test/test-object.c
index 297aa29..3662d30 100644
--- a/test/test-object.c
+++ b/test/test-object.c
@@ -269,6 +269,10 @@ test_object (void)
g_assert (o->get_user_data (obj, &key[i]) == &data[i]);
for (i = 100; i < 1000; i++)
g_assert (o->set_user_data (obj, &key[i], NULL, NULL));
+ for (i = 2; i < 100; i++)
+ g_assert (o->get_user_data (obj, &key[i]) == &data[i]);
+ for (i = 100; i < 1000; i++)
+ g_assert (!o->get_user_data (obj, &key[i]));
g_assert_cmpuint (global_data, ==, 900);
commit 478a42536ff7ab777a7774fbfdb9c5e51334a14e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu May 5 12:39:51 2011 -0400
Make array/map implementation more generic
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 1f49885..77e0089 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -125,6 +125,8 @@ struct hb_user_data_array_t {
map.unset (key);
return true;
}
+ if (!key)
+ return false;
hb_user_data_t user_data = {data, destroy};
return map.set (key, user_data);
}
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 1d40d66..9a23cd3 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -300,20 +300,20 @@ struct hb_map_t
private:
- inline item_t *find (Key key) {
- if (unlikely (!key)) return NULL;
+ template <typename T>
+ inline item_t *find (T key) {
for (unsigned int i = 0; i < items.len; i++)
- if (key == items[i].key)
+ if (items[i].key == key)
return &items[i];
return NULL;
}
public:
- inline bool set (Key key,
+ template <typename T>
+ inline bool set (T key,
Value &value)
{
- if (unlikely (!key)) return NULL;
item_t *item;
item = find (key);
if (item)
@@ -337,7 +337,8 @@ struct hb_map_t
items.pop ();
}
- inline Value *get (Key key)
+ template <typename T>
+ inline Value *get (T key)
{
item_t *item = find (key);
return item ? &item->value : NULL;
More information about the HarfBuzz
mailing list