< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh

Print this page

        

*** 25,60 **** */ #ifndef HB_OT_CMAP_TABLE_HH #define HB_OT_CMAP_TABLE_HH ! #include "hb-open-type-private.hh" ! #include "hb-set-private.hh" ! #include "hb-subset-plan.hh" /* * cmap -- Character to Glyph Index Mapping * https://docs.microsoft.com/en-us/typography/opentype/spec/cmap */ #define HB_OT_TAG_cmap HB_TAG('c','m','a','p') - namespace OT { struct CmapSubtableFormat0 { ! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0; if (!gid) return false; *glyph = gid; return true; } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); } --- 25,64 ---- */ #ifndef HB_OT_CMAP_TABLE_HH #define HB_OT_CMAP_TABLE_HH ! #include "hb-open-type.hh" ! #include "hb-set.hh" /* * cmap -- Character to Glyph Index Mapping * https://docs.microsoft.com/en-us/typography/opentype/spec/cmap */ #define HB_OT_TAG_cmap HB_TAG('c','m','a','p') namespace OT { struct CmapSubtableFormat0 { ! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0; if (!gid) return false; *glyph = gid; return true; } + void collect_unicodes (hb_set_t *out) const + { + for (unsigned int i = 0; i < 256; i++) + if (glyphIdArray[i]) + out->add (i); + } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); }
*** 86,112 **** if (unlikely (!c->extend_min (*this))) return_trace (false); this->format.set (4); this->length.set (get_sub_table_size (segments)); ! this->segCountX2.set (segments.len * 2); ! this->entrySelector.set (MAX (1u, _hb_bit_storage (segments.len)) - 1); this->searchRange.set (2 * (1u << this->entrySelector)); ! this->rangeShift.set (segments.len * 2 > this->searchRange ! ? 2 * segments.len - this->searchRange : 0); ! HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding. ! HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); ! HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.len); ! HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); if (id_range_offset == nullptr) return_trace (false); ! for (unsigned int i = 0; i < segments.len; i++) { end_count[i].set (segments[i].end_code); start_count[i].set (segments[i].start_code); if (segments[i].use_delta) { --- 90,116 ---- if (unlikely (!c->extend_min (*this))) return_trace (false); this->format.set (4); this->length.set (get_sub_table_size (segments)); ! this->segCountX2.set (segments.length * 2); ! this->entrySelector.set (MAX (1u, hb_bit_storage (segments.length)) - 1); this->searchRange.set (2 * (1u << this->entrySelector)); ! this->rangeShift.set (segments.length * 2 > this->searchRange ! ? 2 * segments.length - this->searchRange : 0); ! HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length); c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding. ! HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length); ! HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.length); ! HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length); if (id_range_offset == nullptr) return_trace (false); ! for (unsigned int i = 0; i < segments.length; i++) { end_count[i].set (segments[i].end_code); start_count[i].set (segments[i].start_code); if (segments[i].use_delta) {
*** 148,161 **** } return_trace (true); } ! static inline size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments) { size_t segment_size = 0; ! for (unsigned int i = 0; i < segments.len; i++) { // Parallel array entries segment_size += 2 // end count + 2 // start count --- 152,165 ---- } return_trace (true); } ! static size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments) { size_t segment_size = 0; ! for (unsigned int i = 0; i < segments.length; i++) { // Parallel array entries segment_size += 2 // end count + 2 // start count
*** 170,180 **** return min_size + 2 // Padding + segment_size; } ! static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, hb_vector_t<segment_plan> *segments) { segment_plan *segment = nullptr; hb_codepoint_t last_gid = 0; --- 174,184 ---- return min_size + 2 // Padding + segment_size; } ! static bool create_sub_table_plan (const hb_subset_plan_t *plan, hb_vector_t<segment_plan> *segments) { segment_plan *segment = nullptr; hb_codepoint_t last_gid = 0;
*** 185,201 **** { DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); return false; } ! if (cp > 0xFFFF) { ! // We are now outside of unicode BMP, stop adding to this cmap. ! break; ! } ! if (!segment ! || cp != segment->end_code + 1u) { segment = segments->push (); segment->start_code.set (cp); segment->end_code.set (cp); segment->use_delta = true; --- 189,203 ---- { DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); return false; } ! /* Stop adding to cmap if we are now outside of unicode BMP. */ ! if (cp > 0xFFFF) break; ! if (!segment || ! cp != segment->end_code + 1u) { segment = segments->push (); segment->start_code.set (cp); segment->end_code.set (cp); segment->use_delta = true;
*** 222,254 **** return true; } struct accelerator_t { ! inline void init (const CmapSubtableFormat4 *subtable) { segCount = subtable->segCountX2 / 2; ! endCount = subtable->values; startCount = endCount + segCount + 1; idDelta = startCount + segCount; idRangeOffset = idDelta + segCount; glyphIdArray = idRangeOffset + segCount; glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2; } ! static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { - const accelerator_t *thiz = (const accelerator_t *) obj; - /* Custom two-array bsearch. */ ! int min = 0, max = (int) thiz->segCount - 1; ! const HBUINT16 *startCount = thiz->startCount; ! const HBUINT16 *endCount = thiz->endCount; unsigned int i; while (min <= max) { ! int mid = (min + max) / 2; if (codepoint < startCount[mid]) max = mid - 1; else if (codepoint > endCount[mid]) min = mid + 1; else --- 224,259 ---- return true; } struct accelerator_t { ! accelerator_t () {} ! accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); } ! ~accelerator_t () { fini (); } ! ! void init (const CmapSubtableFormat4 *subtable) { segCount = subtable->segCountX2 / 2; ! endCount = subtable->values.arrayZ; startCount = endCount + segCount + 1; idDelta = startCount + segCount; idRangeOffset = idDelta + segCount; glyphIdArray = idRangeOffset + segCount; glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2; } + void fini () {} ! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { /* Custom two-array bsearch. */ ! int min = 0, max = (int) this->segCount - 1; ! const HBUINT16 *startCount = this->startCount; ! const HBUINT16 *endCount = this->endCount; unsigned int i; while (min <= max) { ! int mid = ((unsigned int) min + (unsigned int) max) / 2; if (codepoint < startCount[mid]) max = mid - 1; else if (codepoint > endCount[mid]) min = mid + 1; else
*** 259,295 **** } return false; found: hb_codepoint_t gid; ! unsigned int rangeOffset = thiz->idRangeOffset[i]; if (rangeOffset == 0) ! gid = codepoint + thiz->idDelta[i]; else { /* Somebody has been smoking... */ ! unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i]) + i - thiz->segCount; ! if (unlikely (index >= thiz->glyphIdArrayLength)) return false; ! gid = thiz->glyphIdArray[index]; if (unlikely (!gid)) return false; ! gid += thiz->idDelta[i]; } ! ! *glyph = gid & 0xFFFFu; return true; } ! ! static inline void get_all_codepoints_func (const void *obj, hb_set_t *out) { ! const accelerator_t *thiz = (const accelerator_t *) obj; ! for (unsigned int i = 0; i < thiz->segCount; i++) { ! if (thiz->startCount[i] != 0xFFFFu ! || thiz->endCount[i] != 0xFFFFu) // Skip the last segment (0xFFFF) ! hb_set_add_range (out, thiz->startCount[i], thiz->endCount[i]); } } const HBUINT16 *endCount; const HBUINT16 *startCount; --- 264,322 ---- } return false; found: hb_codepoint_t gid; ! unsigned int rangeOffset = this->idRangeOffset[i]; if (rangeOffset == 0) ! gid = codepoint + this->idDelta[i]; else { /* Somebody has been smoking... */ ! unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount; ! if (unlikely (index >= this->glyphIdArrayLength)) return false; ! gid = this->glyphIdArray[index]; if (unlikely (!gid)) return false; ! gid += this->idDelta[i]; } ! gid &= 0xFFFFu; ! if (!gid) ! return false; ! *glyph = gid; return true; } ! static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) ! { ! return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); ! } ! void collect_unicodes (hb_set_t *out) const { ! unsigned int count = this->segCount; ! if (count && this->startCount[count - 1] == 0xFFFFu) ! count--; /* Skip sentinel segment. */ ! for (unsigned int i = 0; i < count; i++) { ! unsigned int rangeOffset = this->idRangeOffset[i]; ! if (rangeOffset == 0) ! out->add_range (this->startCount[i], this->endCount[i]); ! else ! { ! for (hb_codepoint_t codepoint = this->startCount[i]; ! codepoint <= this->endCount[i]; ! codepoint++) ! { ! unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount; ! if (unlikely (index >= this->glyphIdArrayLength)) ! break; ! hb_codepoint_t gid = this->glyphIdArray[index]; ! if (unlikely (!gid)) ! continue; ! out->add (codepoint); ! } ! } } } const HBUINT16 *endCount; const HBUINT16 *startCount;
*** 298,315 **** const HBUINT16 *glyphIdArray; unsigned int segCount; unsigned int glyphIdArrayLength; }; ! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { ! accelerator_t accel; ! accel.init (this); return accel.get_glyph_func (&accel, codepoint, glyph); } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); --- 325,346 ---- const HBUINT16 *glyphIdArray; unsigned int segCount; unsigned int glyphIdArrayLength; }; ! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { ! accelerator_t accel (this); return accel.get_glyph_func (&accel, codepoint, glyph); } + void collect_unicodes (hb_set_t *out) const + { + accelerator_t accel (this); + accel.collect_unicodes (out); + } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false);
*** 338,356 **** HBUINT16 segCountX2; /* 2 x segCount. */ HBUINT16 searchRange; /* 2 * (2**floor(log2(segCount))) */ HBUINT16 entrySelector; /* log2(searchRange/2) */ HBUINT16 rangeShift; /* 2 x segCount - searchRange */ ! HBUINT16 values[VAR]; #if 0 HBUINT16 endCount[segCount]; /* End characterCode for each segment, * last=0xFFFFu. */ HBUINT16 reservedPad; /* Set to 0. */ HBUINT16 startCount[segCount]; /* Start character code for each segment. */ HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */ HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ ! HBUINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ #endif public: DEFINE_SIZE_ARRAY (14, values); }; --- 369,389 ---- HBUINT16 segCountX2; /* 2 x segCount. */ HBUINT16 searchRange; /* 2 * (2**floor(log2(segCount))) */ HBUINT16 entrySelector; /* log2(searchRange/2) */ HBUINT16 rangeShift; /* 2 x segCount - searchRange */ ! UnsizedArrayOf<HBUINT16> ! values; #if 0 HBUINT16 endCount[segCount]; /* End characterCode for each segment, * last=0xFFFFu. */ HBUINT16 reservedPad; /* Set to 0. */ HBUINT16 startCount[segCount]; /* Start character code for each segment. */ HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */ HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ ! UnsizedArrayOf<HBUINT16> ! glyphIdArray; /* Glyph index array (arbitrary length) */ #endif public: DEFINE_SIZE_ARRAY (14, values); };
*** 368,378 **** if (codepoint < startCharCode) return -1; if (codepoint > endCharCode) return +1; return 0; } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); } --- 401,411 ---- if (codepoint < startCharCode) return -1; if (codepoint > endCharCode) return +1; return 0; } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); }
*** 382,406 **** HBUINT32 glyphID; /* Glyph index; interpretation depends on * subtable format. */ public: DEFINE_SIZE_STATIC (12); }; template <typename UINT> struct CmapSubtableTrimmed { ! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { /* Rely on our implicit array bound-checking. */ hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode]; if (!gid) return false; *glyph = gid; return true; } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && glyphIdArray.sanitize (c)); } --- 415,448 ---- HBUINT32 glyphID; /* Glyph index; interpretation depends on * subtable format. */ public: DEFINE_SIZE_STATIC (12); }; + DECLARE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup); template <typename UINT> struct CmapSubtableTrimmed { ! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { /* Rely on our implicit array bound-checking. */ hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode]; if (!gid) return false; *glyph = gid; return true; } + void collect_unicodes (hb_set_t *out) const + { + hb_codepoint_t start = startCharCode; + unsigned int count = glyphIdArray.len; + for (unsigned int i = 0; i < count; i++) + if (glyphIdArray[i]) + out->add (start + i); + } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && glyphIdArray.sanitize (c)); }
*** 422,462 **** template <typename T> struct CmapSubtableLongSegmented { friend struct cmap; ! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { ! int i = groups.bsearch (codepoint); ! if (i == -1) return false; ! *glyph = T::group_get_glyph (groups[i], codepoint); return true; } ! inline void get_all_codepoints (hb_set_t *out) const { for (unsigned int i = 0; i < this->groups.len; i++) { ! hb_set_add_range (out, ! this->groups[i].startCharCode, ! this->groups[i].endCharCode); } } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && groups.sanitize (c)); } ! inline bool serialize (hb_serialize_context_t *c, const hb_vector_t<CmapSubtableLongGroup> &group_data) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); ! Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ, group_data.len); ! if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false); return true; } protected: HBUINT16 format; /* Subtable format; set to 12. */ --- 464,503 ---- template <typename T> struct CmapSubtableLongSegmented { friend struct cmap; ! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { ! hb_codepoint_t gid = T::group_get_glyph (groups.bsearch (codepoint), codepoint); ! if (!gid) return false; ! *glyph = gid; return true; } ! void collect_unicodes (hb_set_t *out) const { for (unsigned int i = 0; i < this->groups.len; i++) { ! out->add_range (this->groups[i].startCharCode, ! MIN ((hb_codepoint_t) this->groups[i].endCharCode, ! (hb_codepoint_t) HB_UNICODE_MAX)); } } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && groups.sanitize (c)); } ! bool serialize (hb_serialize_context_t *c, const hb_vector_t<CmapSubtableLongGroup> &group_data) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); ! if (unlikely (!groups.serialize (c, group_data.as_array ()))) return_trace (false); return true; } protected: HBUINT16 format; /* Subtable format; set to 12. */
*** 469,481 **** DEFINE_SIZE_ARRAY (16, groups); }; struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> { ! static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u) ! { return group.glyphID + (u - group.startCharCode); } bool serialize (hb_serialize_context_t *c, const hb_vector_t<CmapSubtableLongGroup> &groups) { --- 510,523 ---- DEFINE_SIZE_ARRAY (16, groups); }; struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> { ! static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u) ! { return likely (group.startCharCode <= group.endCharCode) ? ! group.glyphID + (u - group.startCharCode) : 0; } bool serialize (hb_serialize_context_t *c, const hb_vector_t<CmapSubtableLongGroup> &groups) {
*** 486,501 **** this->length.set (get_sub_table_size (groups)); return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups); } ! static inline size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups) { ! return 16 + 12 * groups.len; } ! static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, hb_vector_t<CmapSubtableLongGroup> *groups) { CmapSubtableLongGroup *group = nullptr; hb_codepoint_t cp = HB_SET_VALUE_INVALID; --- 528,543 ---- this->length.set (get_sub_table_size (groups)); return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups); } ! static size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups) { ! return 16 + 12 * groups.length; } ! static bool create_sub_table_plan (const hb_subset_plan_t *plan, hb_vector_t<CmapSubtableLongGroup> *groups) { CmapSubtableLongGroup *group = nullptr; hb_codepoint_t cp = HB_SET_VALUE_INVALID;
*** 511,537 **** { group = groups->push (); group->startCharCode.set (cp); group->endCharCode.set (cp); group->glyphID.set (new_gid); - } else - { - group->endCharCode.set (cp); } } DEBUG_MSG(SUBSET, nullptr, "cmap"); ! for (unsigned int i = 0; i < groups->len; i++) { CmapSubtableLongGroup& group = (*groups)[i]; DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); } return true; } private: ! static inline bool _is_gid_consecutive (CmapSubtableLongGroup *group, hb_codepoint_t cp, hb_codepoint_t new_gid) { return (cp - 1 == group->endCharCode) && new_gid == group->glyphID + (cp - group->startCharCode); --- 553,577 ---- { group = groups->push (); group->startCharCode.set (cp); group->endCharCode.set (cp); group->glyphID.set (new_gid); } + else group->endCharCode.set (cp); } DEBUG_MSG(SUBSET, nullptr, "cmap"); ! for (unsigned int i = 0; i < groups->length; i++) { CmapSubtableLongGroup& group = (*groups)[i]; DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); } return true; } private: ! static bool _is_gid_consecutive (CmapSubtableLongGroup *group, hb_codepoint_t cp, hb_codepoint_t new_gid) { return (cp - 1 == group->endCharCode) && new_gid == group->glyphID + (cp - group->startCharCode);
*** 539,549 **** }; struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> { ! static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u HB_UNUSED) { return group.glyphID; } }; typedef enum --- 579,589 ---- }; struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> { ! static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u HB_UNUSED) { return group.glyphID; } }; typedef enum
*** 553,570 **** GLYPH_VARIANT_USE_DEFAULT = 2 } glyph_variant_t; struct UnicodeValueRange { ! inline int cmp (const hb_codepoint_t &codepoint) const { if (codepoint < startUnicodeValue) return -1; if (codepoint > startUnicodeValue + additionalCount) return +1; return 0; } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); } --- 593,610 ---- GLYPH_VARIANT_USE_DEFAULT = 2 } glyph_variant_t; struct UnicodeValueRange { ! int cmp (const hb_codepoint_t &codepoint) const { if (codepoint < startUnicodeValue) return -1; if (codepoint > startUnicodeValue + additionalCount) return +1; return 0; } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); }
*** 573,592 **** * range. */ public: DEFINE_SIZE_STATIC (4); }; ! typedef SortedArrayOf<UnicodeValueRange, HBUINT32> DefaultUVS; struct UVSMapping { ! inline int cmp (const hb_codepoint_t &codepoint) const { return unicodeValue.cmp (codepoint); } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); } --- 613,648 ---- * range. */ public: DEFINE_SIZE_STATIC (4); }; ! struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32> ! { ! void collect_unicodes (hb_set_t *out) const ! { ! unsigned int count = len; ! for (unsigned int i = 0; i < count; i++) ! { ! hb_codepoint_t first = arrayZ[i].startUnicodeValue; ! hb_codepoint_t last = MIN ((hb_codepoint_t) (first + arrayZ[i].additionalCount), ! (hb_codepoint_t) HB_UNICODE_MAX); ! out->add_range (first, last); ! } ! } ! ! public: ! DEFINE_SIZE_ARRAY (4, *this); ! }; struct UVSMapping { ! int cmp (const hb_codepoint_t &codepoint) const { return unicodeValue.cmp (codepoint); } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); }
*** 594,632 **** GlyphID glyphID; /* Glyph ID of the UVS */ public: DEFINE_SIZE_STATIC (5); }; ! typedef SortedArrayOf<UVSMapping, HBUINT32> NonDefaultUVS; struct VariationSelectorRecord { ! inline glyph_variant_t get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph, const void *base) const { ! int i; ! const DefaultUVS &defaults = base+defaultUVS; ! i = defaults.bsearch (codepoint); ! if (i != -1) return GLYPH_VARIANT_USE_DEFAULT; ! const NonDefaultUVS &nonDefaults = base+nonDefaultUVS; ! i = nonDefaults.bsearch (codepoint); ! if (i != -1) { ! *glyph = nonDefaults[i].glyphID; return GLYPH_VARIANT_FOUND; } return GLYPH_VARIANT_NOT_FOUND; } ! inline int cmp (const hb_codepoint_t &variation_selector) const { return varSelector.cmp (variation_selector); } ! inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && defaultUVS.sanitize (c, base) && nonDefaultUVS.sanitize (c, base)); --- 650,701 ---- GlyphID glyphID; /* Glyph ID of the UVS */ public: DEFINE_SIZE_STATIC (5); }; ! struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32> ! { ! void collect_unicodes (hb_set_t *out) const ! { ! unsigned int count = len; ! for (unsigned int i = 0; i < count; i++) ! out->add (arrayZ[i].glyphID); ! } ! ! public: ! DEFINE_SIZE_ARRAY (4, *this); ! }; struct VariationSelectorRecord { ! glyph_variant_t get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph, const void *base) const { ! if ((base+defaultUVS).bfind (codepoint)) return GLYPH_VARIANT_USE_DEFAULT; ! const UVSMapping &nonDefault = (base+nonDefaultUVS).bsearch (codepoint); ! if (nonDefault.glyphID) { ! *glyph = nonDefault.glyphID; return GLYPH_VARIANT_FOUND; } return GLYPH_VARIANT_NOT_FOUND; } ! void collect_unicodes (hb_set_t *out, const void *base) const ! { ! (base+defaultUVS).collect_unicodes (out); ! (base+nonDefaultUVS).collect_unicodes (out); ! } ! ! int cmp (const hb_codepoint_t &variation_selector) const { return varSelector.cmp (variation_selector); } ! bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && defaultUVS.sanitize (c, base) && nonDefaultUVS.sanitize (c, base));
*** 641,658 **** DEFINE_SIZE_STATIC (11); }; struct CmapSubtableFormat14 { ! inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) const { ! return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && record.sanitize (c, this)); } --- 710,739 ---- DEFINE_SIZE_STATIC (11); }; struct CmapSubtableFormat14 { ! glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) const { ! return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this); } ! void collect_variation_selectors (hb_set_t *out) const ! { ! unsigned int count = record.len; ! for (unsigned int i = 0; i < count; i++) ! out->add (record.arrayZ[i].varSelector); ! } ! void collect_variation_unicodes (hb_codepoint_t variation_selector, ! hb_set_t *out) const ! { ! record.bsearch (variation_selector).collect_unicodes (out, this); ! } ! ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && record.sanitize (c, this)); }
*** 669,679 **** struct CmapSubtable { /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ ! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { switch (u.format) { case 0: return u.format0 .get_glyph (codepoint, glyph); case 4: return u.format4 .get_glyph (codepoint, glyph); --- 750,760 ---- struct CmapSubtable { /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ ! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { switch (u.format) { case 0: return u.format0 .get_glyph (codepoint, glyph); case 4: return u.format4 .get_glyph (codepoint, glyph);
*** 683,694 **** case 13: return u.format13.get_glyph (codepoint, glyph); case 14: default: return false; } } ! inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { case 0: return_trace (u.format0 .sanitize (c)); --- 764,788 ---- case 13: return u.format13.get_glyph (codepoint, glyph); case 14: default: return false; } } + void collect_unicodes (hb_set_t *out) const + { + switch (u.format) { + case 0: u.format0 .collect_unicodes (out); return; + case 4: u.format4 .collect_unicodes (out); return; + case 6: u.format6 .collect_unicodes (out); return; + case 10: u.format10.collect_unicodes (out); return; + case 12: u.format12.collect_unicodes (out); return; + case 13: u.format13.collect_unicodes (out); return; + case 14: + default: return; + } + } ! bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { case 0: return_trace (u.format0 .sanitize (c));
*** 718,738 **** }; struct EncodingRecord { ! inline int cmp (const EncodingRecord &other) const { int ret; ret = platformID.cmp (other.platformID); if (ret) return ret; ret = encodingID.cmp (other.encodingID); if (ret) return ret; return 0; } ! inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && subtable.sanitize (c, base)); } --- 812,832 ---- }; struct EncodingRecord { ! int cmp (const EncodingRecord &other) const { int ret; ret = platformID.cmp (other.platformID); if (ret) return ret; ret = encodingID.cmp (other.encodingID); if (ret) return ret; return 0; } ! bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && subtable.sanitize (c, base)); }
*** 745,849 **** DEFINE_SIZE_STATIC (8); }; struct cmap { ! static const hb_tag_t tableTag = HB_OT_TAG_cmap; ! struct subset_plan { ! subset_plan(void) { ! format4_segments.init(); ! format12_groups.init(); ! } ! ! ~subset_plan(void) ! { ! format4_segments.fini(); ! format12_groups.fini(); ! } ! ! inline size_t final_size() const { return 4 // header + 8 * 3 // 3 EncodingRecord + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); } - // Format 4 hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments; - // Format 12 hb_vector_t<CmapSubtableLongGroup> format12_groups; }; ! inline bool sanitize (hb_sanitize_context_t *c) const ! { ! TRACE_SANITIZE (this); ! return_trace (c->check_struct (this) && ! likely (version == 0) && ! encodingRecord.sanitize (c, this)); ! } ! ! inline bool _create_plan (const hb_subset_plan_t *plan, subset_plan *cmap_plan) const { ! if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments))) return false; return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups); } ! inline bool _subset (const hb_subset_plan_t *plan, const subset_plan &cmap_subset_plan, size_t dest_sz, void *dest) const { hb_serialize_context_t c (dest, dest_sz); ! OT::cmap *cmap = c.start_serialize<OT::cmap> (); ! if (unlikely (!c.extend_min (*cmap))) { return false; } ! cmap->version.set (0); ! if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3))) return false; // TODO(grieger): Convert the below to a for loop // Format 4, Plat 0 Encoding Record ! EncodingRecord &format4_plat0_rec = cmap->encodingRecord[0]; format4_plat0_rec.platformID.set (0); // Unicode format4_plat0_rec.encodingID.set (3); // Format 4, Plat 3 Encoding Record ! EncodingRecord &format4_plat3_rec = cmap->encodingRecord[1]; format4_plat3_rec.platformID.set (3); // Windows format4_plat3_rec.encodingID.set (1); // Unicode BMP // Format 12 Encoding Record ! EncodingRecord &format12_rec = cmap->encodingRecord[2]; format12_rec.platformID.set (3); // Windows format12_rec.encodingID.set (10); // Unicode UCS-4 // Write out format 4 sub table { ! CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap); format4_plat3_rec.subtable.set (format4_plat0_rec.subtable); subtable.u.format.set (4); CmapSubtableFormat4 &format4 = subtable.u.format4; if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) return false; } // Write out format 12 sub table. { ! CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap); subtable.u.format.set (12); CmapSubtableFormat12 &format12 = subtable.u.format12; if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) return false; --- 839,922 ---- DEFINE_SIZE_STATIC (8); }; struct cmap { ! static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap; ! struct subset_plan { ! size_t final_size () const { return 4 // header + 8 * 3 // 3 EncodingRecord + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); } hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments; hb_vector_t<CmapSubtableLongGroup> format12_groups; }; ! bool _create_plan (const hb_subset_plan_t *plan, subset_plan *cmap_plan) const { ! if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments))) return false; return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups); } ! bool _subset (const hb_subset_plan_t *plan, const subset_plan &cmap_subset_plan, size_t dest_sz, void *dest) const { hb_serialize_context_t c (dest, dest_sz); ! cmap *table = c.start_serialize<cmap> (); ! if (unlikely (!c.extend_min (*table))) { return false; } ! table->version.set (0); ! if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ 3))) return false; // TODO(grieger): Convert the below to a for loop // Format 4, Plat 0 Encoding Record ! EncodingRecord &format4_plat0_rec = table->encodingRecord[0]; format4_plat0_rec.platformID.set (0); // Unicode format4_plat0_rec.encodingID.set (3); // Format 4, Plat 3 Encoding Record ! EncodingRecord &format4_plat3_rec = table->encodingRecord[1]; format4_plat3_rec.platformID.set (3); // Windows format4_plat3_rec.encodingID.set (1); // Unicode BMP // Format 12 Encoding Record ! EncodingRecord &format12_rec = table->encodingRecord[2]; format12_rec.platformID.set (3); // Windows format12_rec.encodingID.set (10); // Unicode UCS-4 // Write out format 4 sub table { ! CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table); format4_plat3_rec.subtable.set (format4_plat0_rec.subtable); subtable.u.format.set (4); CmapSubtableFormat4 &format4 = subtable.u.format4; if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) return false; } // Write out format 12 sub table. { ! CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table); subtable.u.format.set (12); CmapSubtableFormat12 &format12 = subtable.u.format12; if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) return false;
*** 852,873 **** c.end_serialize (); return true; } ! inline bool subset (hb_subset_plan_t *plan) const { subset_plan cmap_subset_plan; if (unlikely (!_create_plan (plan, &cmap_subset_plan))) { DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan."); return false; } // We now know how big our blob needs to be ! size_t dest_sz = cmap_subset_plan.final_size(); void *dest = malloc (dest_sz); if (unlikely (!dest)) { DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); return false; } --- 925,946 ---- c.end_serialize (); return true; } ! bool subset (hb_subset_plan_t *plan) const { subset_plan cmap_subset_plan; if (unlikely (!_create_plan (plan, &cmap_subset_plan))) { DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan."); return false; } // We now know how big our blob needs to be ! size_t dest_sz = cmap_subset_plan.final_size (); void *dest = malloc (dest_sz); if (unlikely (!dest)) { DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); return false; }
*** 878,1028 **** free (dest); return false; } // all done, write the blob into dest ! hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest, dest_sz, HB_MEMORY_MODE_READONLY, dest, free); bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime); hb_blob_destroy (cmap_prime); return result; } ! struct accelerator_t { ! inline void init (hb_face_t *face) ! { ! this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap)); ! const OT::cmap *cmap = this->blob->as<OT::cmap> (); ! const OT::CmapSubtable *subtable = nullptr; ! const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; - bool symbol = false; /* 32-bit subtables. */ ! if (!subtable) subtable = cmap->find_subtable (3, 10); ! if (!subtable) subtable = cmap->find_subtable (0, 6); ! if (!subtable) subtable = cmap->find_subtable (0, 4); /* 16-bit subtables. */ ! if (!subtable) subtable = cmap->find_subtable (3, 1); ! if (!subtable) subtable = cmap->find_subtable (0, 3); ! if (!subtable) subtable = cmap->find_subtable (0, 2); ! if (!subtable) subtable = cmap->find_subtable (0, 1); ! if (!subtable) subtable = cmap->find_subtable (0, 0); ! if (!subtable) { ! subtable = cmap->find_subtable (3, 0); ! if (subtable) symbol = true; } /* Meh. */ ! if (!subtable) subtable = &Null(OT::CmapSubtable); ! /* UVS subtable. */ ! if (!subtable_uvs) { ! const OT::CmapSubtable *st = cmap->find_subtable (0, 5); if (st && st->u.format == 14) subtable_uvs = &st->u.format14; } - /* Meh. */ - if (!subtable_uvs) subtable_uvs = &Null(OT::CmapSubtableFormat14); - - this->uvs_table = subtable_uvs; this->get_glyph_data = subtable; if (unlikely (symbol)) { ! this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>; ! this->get_all_codepoints_func = null_get_all_codepoints_func; } else { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ default: ! this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; ! this->get_all_codepoints_func = null_get_all_codepoints_func; break; case 12: ! this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; ! this->get_all_codepoints_func = get_all_codepoints_from<OT::CmapSubtableFormat12>; break; case 4: { this->format4_accel.init (&subtable->u.format4); this->get_glyph_data = &this->format4_accel; ! this->get_glyph_func = this->format4_accel.get_glyph_func; ! this->get_all_codepoints_func = this->format4_accel.get_all_codepoints_func; } break; } } } ! inline void fini (void) { ! hb_blob_destroy (this->blob); } ! inline bool get_nominal_glyph (hb_codepoint_t unicode, ! hb_codepoint_t *glyph) const { ! return this->get_glyph_func (this->get_glyph_data, unicode, glyph); } ! inline bool get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) const { ! switch (this->uvs_table->get_glyph_variant (unicode, variation_selector, glyph)) { ! case OT::GLYPH_VARIANT_NOT_FOUND: return false; ! case OT::GLYPH_VARIANT_FOUND: return true; ! case OT::GLYPH_VARIANT_USE_DEFAULT: break; } return get_nominal_glyph (unicode, glyph); } ! inline void get_all_codepoints (hb_set_t *out) const { ! this->get_all_codepoints_func (get_glyph_data, out); } protected: typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); - typedef void (*hb_cmap_get_all_codepoints_func_t) (const void *obj, - hb_set_t *out); - - static inline void null_get_all_codepoints_func (const void *obj, hb_set_t *out) - { - // NOOP - } template <typename Type> ! static inline bool get_glyph_from (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { const Type *typed_obj = (const Type *) obj; return typed_obj->get_glyph (codepoint, glyph); } template <typename Type> ! static inline void get_all_codepoints_from (const void *obj, ! hb_set_t *out) ! { ! const Type *typed_obj = (const Type *) obj; ! typed_obj->get_all_codepoints (out); ! } ! ! template <typename Type> ! static inline bool get_glyph_from_symbol (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { const Type *typed_obj = (const Type *) obj; if (likely (typed_obj->get_glyph (codepoint, glyph))) --- 951,1113 ---- free (dest); return false; } // all done, write the blob into dest ! hb_blob_t *cmap_prime = hb_blob_create ((const char *) dest, dest_sz, HB_MEMORY_MODE_READONLY, dest, free); bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime); hb_blob_destroy (cmap_prime); return result; } ! const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const { ! if (symbol) *symbol = false; ! ! const CmapSubtable *subtable; /* 32-bit subtables. */ ! if ((subtable = this->find_subtable (3, 10))) return subtable; ! if ((subtable = this->find_subtable (0, 6))) return subtable; ! if ((subtable = this->find_subtable (0, 4))) return subtable; ! /* 16-bit subtables. */ ! if ((subtable = this->find_subtable (3, 1))) return subtable; ! if ((subtable = this->find_subtable (0, 3))) return subtable; ! if ((subtable = this->find_subtable (0, 2))) return subtable; ! if ((subtable = this->find_subtable (0, 1))) return subtable; ! if ((subtable = this->find_subtable (0, 0))) return subtable; ! ! /* Symbol subtable. */ ! if ((subtable = this->find_subtable (3, 0))) { ! if (symbol) *symbol = true; ! return subtable; } + /* Meh. */ ! return &Null (CmapSubtable); ! } ! struct accelerator_t ! { ! void init (hb_face_t *face) ! { ! this->table = hb_sanitize_context_t ().reference_table<cmap> (face); ! bool symbol; ! this->subtable = table->find_best_subtable (&symbol); ! this->subtable_uvs = &Null (CmapSubtableFormat14); { ! const CmapSubtable *st = table->find_subtable (0, 5); if (st && st->u.format == 14) subtable_uvs = &st->u.format14; } this->get_glyph_data = subtable; if (unlikely (symbol)) { ! this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>; } else { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ default: ! this->get_glyph_funcZ = get_glyph_from<CmapSubtable>; break; case 12: ! this->get_glyph_funcZ = get_glyph_from<CmapSubtableFormat12>; break; case 4: { this->format4_accel.init (&subtable->u.format4); this->get_glyph_data = &this->format4_accel; ! this->get_glyph_funcZ = this->format4_accel.get_glyph_func; } break; } } } ! void fini () { this->table.destroy (); } ! ! bool get_nominal_glyph (hb_codepoint_t unicode, ! hb_codepoint_t *glyph) const { ! if (unlikely (!this->get_glyph_funcZ)) return false; ! return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph); } + unsigned int get_nominal_glyphs (unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride) const + { + if (unlikely (!this->get_glyph_funcZ)) return 0; ! hb_cmap_get_glyph_func_t get_glyph_funcZ = this->get_glyph_funcZ; ! const void *get_glyph_data = this->get_glyph_data; ! ! unsigned int done; ! for (done = 0; ! done < count && get_glyph_funcZ (get_glyph_data, *first_unicode, first_glyph); ! done++) { ! first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride); ! first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); ! } ! return done; } ! bool get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) const { ! switch (this->subtable_uvs->get_glyph_variant (unicode, variation_selector, glyph)) { ! case GLYPH_VARIANT_NOT_FOUND: return false; ! case GLYPH_VARIANT_FOUND: return true; ! case GLYPH_VARIANT_USE_DEFAULT: break; } return get_nominal_glyph (unicode, glyph); } ! void collect_unicodes (hb_set_t *out) const ! { ! subtable->collect_unicodes (out); ! } ! void collect_variation_selectors (hb_set_t *out) const { ! subtable_uvs->collect_variation_selectors (out); ! } ! void collect_variation_unicodes (hb_codepoint_t variation_selector, ! hb_set_t *out) const ! { ! subtable_uvs->collect_variation_unicodes (variation_selector, out); } protected: typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); template <typename Type> ! static bool get_glyph_from (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { const Type *typed_obj = (const Type *) obj; return typed_obj->get_glyph (codepoint, glyph); } template <typename Type> ! static bool get_glyph_from_symbol (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { const Type *typed_obj = (const Type *) obj; if (likely (typed_obj->get_glyph (codepoint, glyph)))
*** 1040,1086 **** return false; } private: ! hb_cmap_get_glyph_func_t get_glyph_func; const void *get_glyph_data; - hb_cmap_get_all_codepoints_func_t get_all_codepoints_func; ! OT::CmapSubtableFormat4::accelerator_t format4_accel; ! const OT::CmapSubtableFormat14 *uvs_table; ! hb_blob_t *blob; }; protected: ! inline const CmapSubtable *find_subtable (unsigned int platform_id, unsigned int encoding_id) const { EncodingRecord key; key.platformID.set (platform_id); key.encodingID.set (encoding_id); ! /* Note: We can use bsearch, but since it has no performance ! * implications, we use lsearch and as such accept fonts with ! * unsorted subtable list. */ ! int result = encodingRecord./*bsearch*/lsearch (key); ! if (result == -1 || !encodingRecord[result].subtable) return nullptr; ! return &(this+encodingRecord[result].subtable); } protected: HBUINT16 version; /* Table version number (0). */ SortedArrayOf<EncodingRecord> encodingRecord; /* Encoding tables. */ public: DEFINE_SIZE_ARRAY (4, encodingRecord); }; } /* namespace OT */ #endif /* HB_OT_CMAP_TABLE_HH */ --- 1125,1180 ---- return false; } private: ! hb_nonnull_ptr_t<const CmapSubtable> subtable; ! hb_nonnull_ptr_t<const CmapSubtableFormat14> subtable_uvs; ! ! hb_cmap_get_glyph_func_t get_glyph_funcZ; const void *get_glyph_data; ! CmapSubtableFormat4::accelerator_t format4_accel; ! hb_blob_ptr_t<cmap> table; }; protected: ! const CmapSubtable *find_subtable (unsigned int platform_id, unsigned int encoding_id) const { EncodingRecord key; key.platformID.set (platform_id); key.encodingID.set (encoding_id); ! const EncodingRecord &result = encodingRecord.bsearch (key); ! if (!result.subtable) return nullptr; ! return &(this+result.subtable); ! } ! ! public: ! ! bool sanitize (hb_sanitize_context_t *c) const ! { ! TRACE_SANITIZE (this); ! return_trace (c->check_struct (this) && ! likely (version == 0) && ! encodingRecord.sanitize (c, this)); } protected: HBUINT16 version; /* Table version number (0). */ SortedArrayOf<EncodingRecord> encodingRecord; /* Encoding tables. */ public: DEFINE_SIZE_ARRAY (4, encodingRecord); }; + struct cmap_accelerator_t : cmap::accelerator_t {}; } /* namespace OT */ #endif /* HB_OT_CMAP_TABLE_HH */
< prev index next >