From aec89de5641fbe1c3031d63dd5f40ec99bf2a538 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 15 Nov 2012 16:15:42 -0800 Subject: [PATCH] Add / modify set API a bit --- src/hb-ot-shape.cc | 2 +- src/hb-set-private.hh | 35 +++++++++++++-- src/hb-set.cc | 88 +++++++++++++++++++++++++------------ src/hb-set.h | 55 +++++++++++++++-------- util/hb-ot-shape-closure.cc | 2 +- 5 files changed, 129 insertions(+), 53 deletions(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index ee0796e31..4b9afb7e1 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -613,7 +613,7 @@ hb_ot_shape_glyphs_closure (hb_font_t *font, do { copy.set (glyphs); HB_SHAPER_DATA_GET (shape_plan)->substitute_closure (font->face, glyphs); - } while (!copy.equal (glyphs)); + } while (!copy.is_equal (glyphs)); hb_shape_plan_destroy (shape_plan); } diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index 43cf925bf..c736b6993 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -147,7 +147,7 @@ struct hb_set_t inline void clear (void) { memset (elts, 0, sizeof elts); } - inline bool empty (void) const { + inline bool is_empty (void) const { for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++) if (elts[i]) return false; @@ -161,6 +161,7 @@ struct hb_set_t } inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { + /* TODO Speedup */ for (unsigned int i = a; i < b + 1; i++) add (i); } @@ -169,6 +170,12 @@ struct hb_set_t if (unlikely (g > MAX_G)) return; elt (g) &= ~mask (g); } + inline void del_range (hb_codepoint_t a, hb_codepoint_t b) + { + /* TODO Speedup */ + for (unsigned int i = a; i < b + 1; i++) + del (i); + } inline bool has (hb_codepoint_t g) const { if (unlikely (g > MAX_G)) return false; @@ -185,7 +192,7 @@ struct hb_set_t return true; return false; } - inline bool equal (const hb_set_t *other) const + inline bool is_equal (const hb_set_t *other) const { for (unsigned int i = 0; i < ELTS; i++) if (elts[i] != other->elts[i]) @@ -217,7 +224,7 @@ struct hb_set_t for (unsigned int i = 0; i < ELTS; i++) elts[i] ^= other->elts[i]; } - inline bool next (hb_codepoint_t *codepoint) + inline bool next (hb_codepoint_t *codepoint) const { if (unlikely (*codepoint == SENTINEL)) { hb_codepoint_t i = get_min (); @@ -234,6 +241,28 @@ struct hb_set_t } return false; } + inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const + { + hb_codepoint_t i; + + i = *last; + if (!next (&i)) + return false; + + *last = *first = i; + while (next (&i) && i == *last + 1) + (*last)++; + + return true; + } + + inline unsigned int get_population (void) const + { + unsigned int count = 0; + for (unsigned int i = 0; i < ELTS; i++) + count += _hb_popcount32 (elts[i]); + return count; + } inline hb_codepoint_t get_min (void) const { for (unsigned int i = 0; i < ELTS; i++) diff --git a/src/hb-set.cc b/src/hb-set.cc index 4225e3c98..37866c40a 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -32,7 +32,7 @@ hb_set_t * -hb_set_create () +hb_set_create (void) { hb_set_t *set; @@ -73,25 +73,25 @@ hb_set_destroy (hb_set_t *set) } hb_bool_t -hb_set_set_user_data (hb_set_t *set, - hb_user_data_key_t *key, - void * data, - hb_destroy_func_t destroy, - hb_bool_t replace) +hb_set_set_user_data (hb_set_t *set, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) { return hb_object_set_user_data (set, key, data, destroy, replace); } void * -hb_set_get_user_data (hb_set_t *set, - hb_user_data_key_t *key) +hb_set_get_user_data (hb_set_t *set, + hb_user_data_key_t *key) { return hb_object_get_user_data (set, key); } hb_bool_t -hb_set_allocation_successful (hb_set_t *set HB_UNUSED) +hb_set_allocation_successful (const hb_set_t *set HB_UNUSED) { return true; } @@ -103,13 +103,13 @@ hb_set_clear (hb_set_t *set) } hb_bool_t -hb_set_empty (hb_set_t *set) +hb_set_is_empty (const hb_set_t *set) { - return set->empty (); + return set->is_empty (); } hb_bool_t -hb_set_has (hb_set_t *set, +hb_set_has (const hb_set_t *set, hb_codepoint_t codepoint) { return set->has (codepoint); @@ -122,6 +122,14 @@ hb_set_add (hb_set_t *set, set->add (codepoint); } +void +hb_set_add_range (hb_set_t *set, + hb_codepoint_t first, + hb_codepoint_t last) +{ + set->add_range (first, last); +} + void hb_set_del (hb_set_t *set, hb_codepoint_t codepoint) @@ -129,63 +137,85 @@ hb_set_del (hb_set_t *set, set->del (codepoint); } -hb_bool_t -hb_set_equal (hb_set_t *set, - hb_set_t *other) +void +hb_set_del_range (hb_set_t *set, + hb_codepoint_t first, + hb_codepoint_t last) { - return set->equal (other); + set->del_range (first, last); +} + +hb_bool_t +hb_set_is_equal (const hb_set_t *set, + const hb_set_t *other) +{ + return set->is_equal (other); } void -hb_set_set (hb_set_t *set, - hb_set_t *other) +hb_set_set (hb_set_t *set, + const hb_set_t *other) { set->set (other); } void -hb_set_union (hb_set_t *set, - hb_set_t *other) +hb_set_union (hb_set_t *set, + const hb_set_t *other) { set->union_ (other); } void -hb_set_intersect (hb_set_t *set, - hb_set_t *other) +hb_set_intersect (hb_set_t *set, + const hb_set_t *other) { set->intersect (other); } void -hb_set_subtract (hb_set_t *set, - hb_set_t *other) +hb_set_subtract (hb_set_t *set, + const hb_set_t *other) { set->subtract (other); } void -hb_set_symmetric_difference (hb_set_t *set, - hb_set_t *other) +hb_set_symmetric_difference (hb_set_t *set, + const hb_set_t *other) { set->symmetric_difference (other); } +unsigned int +hb_set_population (const hb_set_t *set) +{ + return set->get_population (); +} + hb_codepoint_t -hb_set_min (hb_set_t *set) +hb_set_get_min (const hb_set_t *set) { return set->get_min (); } hb_codepoint_t -hb_set_max (hb_set_t *set) +hb_set_get_max (const hb_set_t *set) { return set->get_max (); } hb_bool_t -hb_set_next (hb_set_t *set, +hb_set_next (const hb_set_t *set, hb_codepoint_t *codepoint) { return set->next (codepoint); } + +hb_bool_t +hb_set_next_range (const hb_set_t *set, + hb_codepoint_t *first, + hb_codepoint_t *last) +{ + return set->next_range (first, last); +} diff --git a/src/hb-set.h b/src/hb-set.h index 1838889f2..06f358272 100644 --- a/src/hb-set.h +++ b/src/hb-set.h @@ -65,16 +65,16 @@ hb_set_get_user_data (hb_set_t *set, /* Returns false if allocation has failed before */ hb_bool_t -hb_set_allocation_successful (hb_set_t *set); +hb_set_allocation_successful (const hb_set_t *set); void hb_set_clear (hb_set_t *set); hb_bool_t -hb_set_empty (hb_set_t *set); +hb_set_is_empty (const hb_set_t *set); hb_bool_t -hb_set_has (hb_set_t *set, +hb_set_has (const hb_set_t *set, hb_codepoint_t codepoint); /* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1 @@ -83,48 +83,65 @@ void hb_set_add (hb_set_t *set, hb_codepoint_t codepoint); +void +hb_set_add_range (hb_set_t *set, + hb_codepoint_t first, + hb_codepoint_t last); + void hb_set_del (hb_set_t *set, hb_codepoint_t codepoint); +void +hb_set_del_range (hb_set_t *set, + hb_codepoint_t first, + hb_codepoint_t last); + hb_bool_t -hb_set_equal (hb_set_t *set, - hb_set_t *other); +hb_set_is_equal (const hb_set_t *set, + const hb_set_t *other); void -hb_set_set (hb_set_t *set, - hb_set_t *other); +hb_set_set (hb_set_t *set, + const hb_set_t *other); void -hb_set_union (hb_set_t *set, - hb_set_t *other); +hb_set_union (hb_set_t *set, + const hb_set_t *other); void -hb_set_intersect (hb_set_t *set, - hb_set_t *other); +hb_set_intersect (hb_set_t *set, + const hb_set_t *other); void -hb_set_subtract (hb_set_t *set, - hb_set_t *other); +hb_set_subtract (hb_set_t *set, + const hb_set_t *other); void -hb_set_symmetric_difference (hb_set_t *set, - hb_set_t *other); +hb_set_symmetric_difference (hb_set_t *set, + const hb_set_t *other); + +unsigned int +hb_set_population (const hb_set_t *set); /* Returns -1 if set empty. */ hb_codepoint_t -hb_set_min (hb_set_t *set); +hb_set_get_min (const hb_set_t *set); /* Returns -1 if set empty. */ hb_codepoint_t -hb_set_max (hb_set_t *set); +hb_set_get_max (const hb_set_t *set); /* Pass -1 in to get started. */ hb_bool_t -hb_set_next (hb_set_t *set, +hb_set_next (const hb_set_t *set, hb_codepoint_t *codepoint); -/* TODO: Add faster iteration API? */ +/* Pass -1 for first and last to get started. */ +hb_bool_t +hb_set_next_range (const hb_set_t *set, + hb_codepoint_t *first, + hb_codepoint_t *last); HB_END_DECLS diff --git a/util/hb-ot-shape-closure.cc b/util/hb-ot-shape-closure.cc index 2289605cd..41517f232 100644 --- a/util/hb-ot-shape-closure.cc +++ b/util/hb-ot-shape-closure.cc @@ -68,7 +68,7 @@ struct shape_closure_consumer_t : option_group_t hb_set_clear (glyphs); shaper.shape_closure (text, text_len, font, buffer, glyphs); - if (hb_set_empty (glyphs)) + if (hb_set_is_empty (glyphs)) return; /* Print it out! */