| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2014 Google, Inc. | 2 * Copyright © 2014 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 USHORT lengthZ; /* Byte length of this subtable. */ | 62 USHORT lengthZ; /* Byte length of this subtable. */ |
| 63 USHORT languageZ; /* Ignore. */ | 63 USHORT languageZ; /* Ignore. */ |
| 64 BYTE glyphIdArray[256];/* An array that maps character | 64 BYTE glyphIdArray[256];/* An array that maps character |
| 65 * code to glyph index values. */ | 65 * code to glyph index values. */ |
| 66 public: | 66 public: |
| 67 DEFINE_SIZE_STATIC (6 + 256); | 67 DEFINE_SIZE_STATIC (6 + 256); |
| 68 }; | 68 }; |
| 69 | 69 |
| 70 struct CmapSubtableFormat4 | 70 struct CmapSubtableFormat4 |
| 71 { | 71 { |
| 72 inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const | 72 struct accelerator_t |
| 73 { | 73 { |
| 74 unsigned int segCount; | 74 inline void init (const CmapSubtableFormat4 *subtable) |
| 75 { |
| 76 segCount = subtable->segCountX2 / 2; |
| 77 endCount = subtable->values; |
| 78 startCount = endCount + segCount + 1; |
| 79 idDelta = startCount + segCount; |
| 80 idRangeOffset = idDelta + segCount; |
| 81 glyphIdArray = idRangeOffset + segCount; |
| 82 glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2; |
| 83 } |
| 84 |
| 85 static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint
, hb_codepoint_t *glyph) |
| 86 { |
| 87 const accelerator_t *thiz = (const accelerator_t *) obj; |
| 88 |
| 89 /* Custom two-array bsearch. */ |
| 90 int min = 0, max = (int) thiz->segCount - 1; |
| 91 const USHORT *startCount = thiz->startCount; |
| 92 const USHORT *endCount = thiz->endCount; |
| 93 unsigned int i; |
| 94 while (min <= max) |
| 95 { |
| 96 » int mid = (min + max) / 2; |
| 97 » if (codepoint < startCount[mid]) |
| 98 » max = mid - 1; |
| 99 » else if (codepoint > endCount[mid]) |
| 100 » min = mid + 1; |
| 101 » else |
| 102 » { |
| 103 » i = mid; |
| 104 » goto found; |
| 105 » } |
| 106 } |
| 107 return false; |
| 108 |
| 109 found: |
| 110 hb_codepoint_t gid; |
| 111 unsigned int rangeOffset = thiz->idRangeOffset[i]; |
| 112 if (rangeOffset == 0) |
| 113 » gid = codepoint + thiz->idDelta[i]; |
| 114 else |
| 115 { |
| 116 » /* Somebody has been smoking... */ |
| 117 » unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i])
+ i - thiz->segCount; |
| 118 » if (unlikely (index >= thiz->glyphIdArrayLength)) |
| 119 » return false; |
| 120 » gid = thiz->glyphIdArray[index]; |
| 121 » if (unlikely (!gid)) |
| 122 » return false; |
| 123 » gid += thiz->idDelta[i]; |
| 124 } |
| 125 |
| 126 *glyph = gid & 0xFFFFu; |
| 127 return true; |
| 128 } |
| 129 |
| 75 const USHORT *endCount; | 130 const USHORT *endCount; |
| 76 const USHORT *startCount; | 131 const USHORT *startCount; |
| 77 const USHORT *idDelta; | 132 const USHORT *idDelta; |
| 78 const USHORT *idRangeOffset; | 133 const USHORT *idRangeOffset; |
| 79 const USHORT *glyphIdArray; | 134 const USHORT *glyphIdArray; |
| 135 unsigned int segCount; |
| 80 unsigned int glyphIdArrayLength; | 136 unsigned int glyphIdArrayLength; |
| 137 }; |
| 81 | 138 |
| 82 segCount = this->segCountX2 / 2; | 139 inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const |
| 83 endCount = this->values; | 140 { |
| 84 startCount = endCount + segCount + 1; | 141 accelerator_t accel; |
| 85 idDelta = startCount + segCount; | 142 accel.init (this); |
| 86 idRangeOffset = idDelta + segCount; | 143 return accel.get_glyph_func (&accel, codepoint, glyph); |
| 87 glyphIdArray = idRangeOffset + segCount; | |
| 88 glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; | |
| 89 | |
| 90 /* Custom two-array bsearch. */ | |
| 91 int min = 0, max = (int) segCount - 1; | |
| 92 unsigned int i; | |
| 93 while (min <= max) | |
| 94 { | |
| 95 int mid = (min + max) / 2; | |
| 96 if (codepoint < startCount[mid]) | |
| 97 max = mid - 1; | |
| 98 else if (codepoint > endCount[mid]) | |
| 99 min = mid + 1; | |
| 100 else | |
| 101 { | |
| 102 » i = mid; | |
| 103 » goto found; | |
| 104 } | |
| 105 } | |
| 106 return false; | |
| 107 | |
| 108 found: | |
| 109 hb_codepoint_t gid; | |
| 110 unsigned int rangeOffset = idRangeOffset[i]; | |
| 111 if (rangeOffset == 0) | |
| 112 gid = codepoint + idDelta[i]; | |
| 113 else | |
| 114 { | |
| 115 /* Somebody has been smoking... */ | |
| 116 unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - s
egCount; | |
| 117 if (unlikely (index >= glyphIdArrayLength)) | |
| 118 » return false; | |
| 119 gid = glyphIdArray[index]; | |
| 120 if (unlikely (!gid)) | |
| 121 » return false; | |
| 122 gid += idDelta[i]; | |
| 123 } | |
| 124 | |
| 125 *glyph = gid & 0xFFFFu; | |
| 126 return true; | |
| 127 } | 144 } |
| 128 | 145 |
| 129 inline bool sanitize (hb_sanitize_context_t *c) const | 146 inline bool sanitize (hb_sanitize_context_t *c) const |
| 130 { | 147 { |
| 131 TRACE_SANITIZE (this); | 148 TRACE_SANITIZE (this); |
| 132 if (unlikely (!c->check_struct (this))) | 149 if (unlikely (!c->check_struct (this))) |
| 133 return_trace (false); | 150 return_trace (false); |
| 134 | 151 |
| 135 if (unlikely (!c->check_range (this, length))) | 152 if (unlikely (!c->check_range (this, length))) |
| 136 { | 153 { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 } | 398 } |
| 382 | 399 |
| 383 inline bool sanitize (hb_sanitize_context_t *c) const | 400 inline bool sanitize (hb_sanitize_context_t *c) const |
| 384 { | 401 { |
| 385 TRACE_SANITIZE (this); | 402 TRACE_SANITIZE (this); |
| 386 return_trace (c->check_struct (this) && | 403 return_trace (c->check_struct (this) && |
| 387 record.sanitize (c, this)); | 404 record.sanitize (c, this)); |
| 388 } | 405 } |
| 389 | 406 |
| 390 protected: | 407 protected: |
| 391 USHORT» format;»» /* Format number is set to 0. */ | 408 USHORT» format;»» /* Format number is set to 14. */ |
| 392 ULONG lengthZ; /* Byte length of this subtable. */ | 409 ULONG lengthZ; /* Byte length of this subtable. */ |
| 393 SortedArrayOf<VariationSelectorRecord, ULONG> | 410 SortedArrayOf<VariationSelectorRecord, ULONG> |
| 394 record; /* Variation selector records; sorted | 411 record; /* Variation selector records; sorted |
| 395 * in increasing order of `varSelector'. */ | 412 * in increasing order of `varSelector'. */ |
| 396 public: | 413 public: |
| 397 DEFINE_SIZE_ARRAY (10, record); | 414 DEFINE_SIZE_ARRAY (10, record); |
| 398 }; | 415 }; |
| 399 | 416 |
| 400 struct CmapSubtable | 417 struct CmapSubtable |
| 401 { | 418 { |
| 402 /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ | 419 /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ |
| 403 | 420 |
| 404 inline bool get_glyph (hb_codepoint_t codepoint, | 421 inline bool get_glyph (hb_codepoint_t codepoint, |
| 405 hb_codepoint_t *glyph) const | 422 hb_codepoint_t *glyph) const |
| 406 { | 423 { |
| 407 switch (u.format) { | 424 switch (u.format) { |
| 408 case 0: return u.format0 .get_glyph(codepoint, glyph); | 425 case 0: return u.format0 .get_glyph(codepoint, glyph); |
| 409 case 4: return u.format4 .get_glyph(codepoint, glyph); | 426 case 4: return u.format4 .get_glyph(codepoint, glyph); |
| 410 case 6: return u.format6 .get_glyph(codepoint, glyph); | 427 case 6: return u.format6 .get_glyph(codepoint, glyph); |
| 411 case 10: return u.format10.get_glyph(codepoint, glyph); | 428 case 10: return u.format10.get_glyph(codepoint, glyph); |
| 412 case 12: return u.format12.get_glyph(codepoint, glyph); | 429 case 12: return u.format12.get_glyph(codepoint, glyph); |
| 413 case 13: return u.format13.get_glyph(codepoint, glyph); | 430 case 13: return u.format13.get_glyph(codepoint, glyph); |
| 414 case 14: | 431 case 14: |
| 415 default: return false; | 432 default: return false; |
| 416 } | 433 } |
| 417 } | 434 } |
| 418 | 435 |
| 419 inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, | |
| 420 hb_codepoint_t variation_selector, | |
| 421 hb_codepoint_t *glyph) const | |
| 422 { | |
| 423 switch (u.format) { | |
| 424 case 14: return u.format14.get_glyph_variant(codepoint, variation_selector,
glyph); | |
| 425 default: return GLYPH_VARIANT_NOT_FOUND; | |
| 426 } | |
| 427 } | |
| 428 | |
| 429 inline bool sanitize (hb_sanitize_context_t *c) const | 436 inline bool sanitize (hb_sanitize_context_t *c) const |
| 430 { | 437 { |
| 431 TRACE_SANITIZE (this); | 438 TRACE_SANITIZE (this); |
| 432 if (!u.format.sanitize (c)) return_trace (false); | 439 if (!u.format.sanitize (c)) return_trace (false); |
| 433 switch (u.format) { | 440 switch (u.format) { |
| 434 case 0: return_trace (u.format0 .sanitize (c)); | 441 case 0: return_trace (u.format0 .sanitize (c)); |
| 435 case 4: return_trace (u.format4 .sanitize (c)); | 442 case 4: return_trace (u.format4 .sanitize (c)); |
| 436 case 6: return_trace (u.format6 .sanitize (c)); | 443 case 6: return_trace (u.format6 .sanitize (c)); |
| 437 case 10: return_trace (u.format10.sanitize (c)); | 444 case 10: return_trace (u.format10.sanitize (c)); |
| 438 case 12: return_trace (u.format12.sanitize (c)); | 445 case 12: return_trace (u.format12.sanitize (c)); |
| 439 case 13: return_trace (u.format13.sanitize (c)); | 446 case 13: return_trace (u.format13.sanitize (c)); |
| 440 case 14: return_trace (u.format14.sanitize (c)); | 447 case 14: return_trace (u.format14.sanitize (c)); |
| 441 default:return_trace (true); | 448 default:return_trace (true); |
| 442 } | 449 } |
| 443 } | 450 } |
| 444 | 451 |
| 445 protected: | 452 public: |
| 446 union { | 453 union { |
| 447 USHORT format; /* Format identifier */ | 454 USHORT format; /* Format identifier */ |
| 448 CmapSubtableFormat0 format0; | 455 CmapSubtableFormat0 format0; |
| 449 CmapSubtableFormat4 format4; | 456 CmapSubtableFormat4 format4; |
| 450 CmapSubtableFormat6 format6; | 457 CmapSubtableFormat6 format6; |
| 451 CmapSubtableFormat10 format10; | 458 CmapSubtableFormat10 format10; |
| 452 CmapSubtableFormat12 format12; | 459 CmapSubtableFormat12 format12; |
| 453 CmapSubtableFormat13 format13; | 460 CmapSubtableFormat13 format13; |
| 454 CmapSubtableFormat14 format14; | 461 CmapSubtableFormat14 format14; |
| 455 } u; | 462 } u; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 encodingRecord; /* Encoding tables. */ | 526 encodingRecord; /* Encoding tables. */ |
| 520 public: | 527 public: |
| 521 DEFINE_SIZE_ARRAY (4, encodingRecord); | 528 DEFINE_SIZE_ARRAY (4, encodingRecord); |
| 522 }; | 529 }; |
| 523 | 530 |
| 524 | 531 |
| 525 } /* namespace OT */ | 532 } /* namespace OT */ |
| 526 | 533 |
| 527 | 534 |
| 528 #endif /* HB_OT_CMAP_TABLE_HH */ | 535 #endif /* HB_OT_CMAP_TABLE_HH */ |
| OLD | NEW |