OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2012 Google, Inc. | 2 * Copyright © 2012 Google, Inc. |
3 * | 3 * |
4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
5 * | 5 * |
6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
10 * all copies of this software. | 10 * all copies of this software. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 138 |
139 /* | 139 /* |
140 * hb_set_t | 140 * hb_set_t |
141 */ | 141 */ |
142 | 142 |
143 | 143 |
144 /* TODO Make this faster and memmory efficient. */ | 144 /* TODO Make this faster and memmory efficient. */ |
145 | 145 |
146 struct hb_set_t | 146 struct hb_set_t |
147 { | 147 { |
| 148 friend struct hb_frozen_set_t; |
| 149 |
148 hb_object_header_t header; | 150 hb_object_header_t header; |
149 ASSERT_POD (); | 151 ASSERT_POD (); |
150 bool in_error; | 152 bool in_error; |
151 | 153 |
152 inline void init (void) { | 154 inline void init (void) { |
153 hb_object_init (this); | 155 hb_object_init (this); |
154 clear (); | 156 clear (); |
155 } | 157 } |
156 inline void fini (void) { | 158 inline void fini (void) { |
157 } | 159 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 321 |
320 typedef uint32_t elt_t; | 322 typedef uint32_t elt_t; |
321 static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */ | 323 static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */ |
322 static const unsigned int SHIFT = 5; | 324 static const unsigned int SHIFT = 5; |
323 static const unsigned int BITS = (1 << SHIFT); | 325 static const unsigned int BITS = (1 << SHIFT); |
324 static const unsigned int MASK = BITS - 1; | 326 static const unsigned int MASK = BITS - 1; |
325 static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS; | 327 static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS; |
326 static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; | 328 static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; |
327 | 329 |
328 elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; } | 330 elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; } |
329 elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } | 331 elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } |
330 elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); } | 332 elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); } |
331 | 333 |
332 elt_t elts[ELTS]; /* XXX 8kb */ | 334 elt_t elts[ELTS]; /* XXX 8kb */ |
333 | 335 |
334 ASSERT_STATIC (sizeof (elt_t) * 8 == BITS); | 336 ASSERT_STATIC (sizeof (elt_t) * 8 == BITS); |
335 ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G); | 337 ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G); |
336 }; | 338 }; |
337 | 339 |
| 340 struct hb_frozen_set_t |
| 341 { |
| 342 static const unsigned int SHIFT = hb_set_t::SHIFT; |
| 343 static const unsigned int BITS = hb_set_t::BITS; |
| 344 static const unsigned int MASK = hb_set_t::MASK; |
| 345 typedef hb_set_t::elt_t elt_t; |
| 346 |
| 347 inline void init (const hb_set_t &set) |
| 348 { |
| 349 start = count = 0; |
| 350 elts = NULL; |
| 351 |
| 352 unsigned int max = set.get_max (); |
| 353 if (max == set.INVALID) |
| 354 return; |
| 355 unsigned int min = set.get_min (); |
| 356 const elt_t &min_elt = set.elt (min); |
| 357 const elt_t &max_elt = set.elt (max); |
| 358 |
| 359 start = min & ~MASK; |
| 360 count = max - start + 1; |
| 361 unsigned int num_elts = (count + BITS - 1) / BITS; |
| 362 unsigned int elts_size = num_elts * sizeof (elt_t); |
| 363 elts = (elt_t *) malloc (elts_size); |
| 364 if (unlikely (!elts)) |
| 365 { |
| 366 start = count = 0; |
| 367 return; |
| 368 } |
| 369 memcpy (elts, &min_elt, elts_size); |
| 370 } |
| 371 |
| 372 inline void fini (void) |
| 373 { |
| 374 if (elts) |
| 375 free (elts); |
| 376 } |
| 377 |
| 378 inline bool has (hb_codepoint_t g) const |
| 379 { |
| 380 /* hb_codepoint_t is unsigned. */ |
| 381 g -= start; |
| 382 if (unlikely (g > count)) return false; |
| 383 return !!(elt (g) & mask (g)); |
| 384 } |
| 385 |
| 386 elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } |
| 387 elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); } |
| 388 |
| 389 private: |
| 390 hb_codepoint_t start, count; |
| 391 elt_t *elts; |
| 392 }; |
338 | 393 |
339 | 394 |
340 #endif /* HB_SET_PRIVATE_HH */ | 395 #endif /* HB_SET_PRIVATE_HH */ |
OLD | NEW |