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 59e8f4559f5921e1ccaf766c421bbb0cc0f58df2..acba4e946b6c4d581c99d1bc838599b83f73ec81 100644 |
--- a/third_party/harfbuzz-ng/src/hb-set-private.hh |
+++ b/third_party/harfbuzz-ng/src/hb-set-private.hh |
@@ -145,6 +145,8 @@ typedef hb_set_digest_combiner_t |
struct hb_set_t |
{ |
+ friend struct hb_frozen_set_t; |
+ |
hb_object_header_t header; |
ASSERT_POD (); |
bool in_error; |
@@ -326,7 +328,7 @@ struct hb_set_t |
static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; |
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; } |
- elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } |
+ elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } |
elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); } |
elt_t elts[ELTS]; /* XXX 8kb */ |
@@ -335,6 +337,59 @@ struct hb_set_t |
ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G); |
}; |
+struct hb_frozen_set_t |
+{ |
+ static const unsigned int SHIFT = hb_set_t::SHIFT; |
+ static const unsigned int BITS = hb_set_t::BITS; |
+ static const unsigned int MASK = hb_set_t::MASK; |
+ typedef hb_set_t::elt_t elt_t; |
+ |
+ inline void init (const hb_set_t &set) |
+ { |
+ start = count = 0; |
+ elts = NULL; |
+ |
+ unsigned int max = set.get_max (); |
+ if (max == set.INVALID) |
+ return; |
+ unsigned int min = set.get_min (); |
+ const elt_t &min_elt = set.elt (min); |
+ const elt_t &max_elt = set.elt (max); |
+ |
+ start = min & ~MASK; |
+ count = max - start + 1; |
+ unsigned int num_elts = (count + BITS - 1) / BITS; |
+ unsigned int elts_size = num_elts * sizeof (elt_t); |
+ elts = (elt_t *) malloc (elts_size); |
+ if (unlikely (!elts)) |
+ { |
+ start = count = 0; |
+ return; |
+ } |
+ memcpy (elts, &min_elt, elts_size); |
+ } |
+ |
+ inline void fini (void) |
+ { |
+ if (elts) |
+ free (elts); |
+ } |
+ |
+ inline bool has (hb_codepoint_t g) const |
+ { |
+ /* hb_codepoint_t is unsigned. */ |
+ g -= start; |
+ if (unlikely (g > count)) return false; |
+ return !!(elt (g) & mask (g)); |
+ } |
+ |
+ elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } |
+ elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); } |
+ |
+ private: |
+ hb_codepoint_t start, count; |
+ elt_t *elts; |
+}; |
#endif /* HB_SET_PRIVATE_HH */ |