Index: third_party/harfbuzz-ng/src/hb-set-private.hh |
diff --git a/third_party/harfbuzz-ng/src/hb-set-private.hh b/third_party/harfbuzz-ng/src/hb-set-private.hh |
index 5cdf8a0f2b95af8ff000fba7b9a57e51f1fb6b09..441357929d87d02ed25ec5cbec7bb845ca9bf3cd 100644 |
--- a/third_party/harfbuzz-ng/src/hb-set-private.hh |
+++ b/third_party/harfbuzz-ng/src/hb-set-private.hh |
@@ -32,9 +32,108 @@ |
#include "hb-object-private.hh" |
+struct hb_set_digest_common_bits_t |
+{ |
+ ASSERT_POD (); |
+ |
+ typedef unsigned int mask_t; |
+ |
+ inline void init (void) { |
+ mask = ~0; |
+ value = (mask_t) -1; |
+ } |
+ |
+ inline void add (hb_codepoint_t g) { |
+ if (unlikely (value == (mask_t) -1)) { |
+ value = g; |
+ return; |
+ } |
+ |
+ mask ^= (g & mask) ^ value; |
+ value &= mask; |
+ } |
+ |
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { |
+ /* The negation here stands for ~(x-1). */ |
+ mask &= -(1 << _hb_bit_storage (a ^ b)); |
+ value &= mask; |
+ } |
+ |
+ inline bool may_have (hb_codepoint_t g) const { |
+ return (g & mask) == value; |
+ } |
+ |
+ private: |
+ mask_t mask; |
+ mask_t value; |
+}; |
+ |
+struct hb_set_digest_lowest_bits_t |
+{ |
+ ASSERT_POD (); |
+ |
+ typedef unsigned long mask_t; |
+ |
+ inline void init (void) { |
+ mask = 0; |
+ } |
+ |
+ inline void add (hb_codepoint_t g) { |
+ mask |= mask_for (g); |
+ } |
+ |
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { |
+ if (b - a >= sizeof (mask_t) * 8 - 1) |
+ mask = (mask_t) -1; |
+ else { |
+ mask_t ma = mask_for (a); |
+ mask_t mb = mask_for (b); |
+ mask |= mb + (mb - ma) - (mb < ma); |
+ } |
+ } |
+ |
+ inline bool may_have (hb_codepoint_t g) const { |
+ return !!(mask & mask_for (g)); |
+ } |
+ |
+ private: |
+ |
+ mask_t mask_for (hb_codepoint_t g) const { return ((mask_t) 1) << (g & (sizeof (mask_t) * 8 - 1)); } |
+ mask_t mask; |
+}; |
+ |
+struct hb_set_digest_t |
+{ |
+ ASSERT_POD (); |
+ |
+ inline void init (void) { |
+ digest1.init (); |
+ digest2.init (); |
+ } |
+ |
+ inline void add (hb_codepoint_t g) { |
+ digest1.add (g); |
+ digest2.add (g); |
+ } |
+ |
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { |
+ digest1.add_range (a, b); |
+ digest2.add_range (a, b); |
+ } |
+ |
+ inline bool may_have (hb_codepoint_t g) const { |
+ return digest1.may_have (g) && digest2.may_have (g); |
+ } |
+ |
+ private: |
+ hb_set_digest_common_bits_t digest1; |
+ hb_set_digest_lowest_bits_t digest2; |
+}; |
+ |
+ |
/* TODO Make this faster and memmory efficient. */ |
-struct _hb_set_t |
+struct hb_set_t |
{ |
hb_object_header_t header; |
ASSERT_POD (); |
@@ -60,6 +159,11 @@ struct _hb_set_t |
if (unlikely (g > MAX_G)) return; |
elt (g) |= mask (g); |
} |
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b) |
+ { |
+ for (unsigned int i = a; i < b + 1; i++) |
+ add (i); |
+ } |
inline void del (hb_codepoint_t g) |
{ |
if (unlikely (g > MAX_G)) return; |