src/hb-ot-cmap-table.hh | 125 +++++++++++++++++++++++++----------------------- src/hb-ot-font.cc | 48 +++++++++++++++--- 2 files changed, 107 insertions(+), 66 deletions(-)
New commits: commit 23335deaad9d4d9824ff41343264514d3f9f7e37 Author: Behdad Esfahbod <[email protected]> Date: Wed Feb 24 20:27:13 2016 +0900 [ot-font] Accelerate cmap format4 get_glyph diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 886d348..d7a94a1 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -69,61 +69,78 @@ struct CmapSubtableFormat0 struct CmapSubtableFormat4 { - inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + struct accelerator_t { - unsigned int segCount; - const USHORT *endCount; - const USHORT *startCount; - const USHORT *idDelta; - const USHORT *idRangeOffset; - const USHORT *glyphIdArray; - unsigned int glyphIdArrayLength; + 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; + } - segCount = this->segCountX2 / 2; - endCount = this->values; - startCount = endCount + segCount + 1; - idDelta = startCount + segCount; - idRangeOffset = idDelta + segCount; - glyphIdArray = idRangeOffset + segCount; - glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; - - /* Custom two-array bsearch. */ - int min = 0, max = (int) segCount - 1; - unsigned int i; - while (min <= max) + static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { - int mid = (min + max) / 2; - if (codepoint < startCount[mid]) - max = mid - 1; - else if (codepoint > endCount[mid]) - min = mid + 1; + const accelerator_t *thiz = (const accelerator_t *) obj; + + /* Custom two-array bsearch. */ + int min = 0, max = (int) thiz->segCount - 1; + const USHORT *startCount = thiz->startCount; + const USHORT *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 + { + i = mid; + goto found; + } + } + return false; + + found: + hb_codepoint_t gid; + unsigned int rangeOffset = thiz->idRangeOffset[i]; + if (rangeOffset == 0) + gid = codepoint + thiz->idDelta[i]; else { - i = mid; - goto found; + /* 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]; } - } - return false; - - found: - hb_codepoint_t gid; - unsigned int rangeOffset = idRangeOffset[i]; - if (rangeOffset == 0) - gid = codepoint + idDelta[i]; - else - { - /* Somebody has been smoking... */ - unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount; - if (unlikely (index >= glyphIdArrayLength)) - return false; - gid = glyphIdArray[index]; - if (unlikely (!gid)) - return false; - gid += idDelta[i]; + + *glyph = gid & 0xFFFFu; + return true; } - *glyph = gid & 0xFFFFu; - return true; + const USHORT *endCount; + const USHORT *startCount; + const USHORT *idDelta; + const USHORT *idRangeOffset; + const USHORT *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 diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index e7dbcff..61c7036 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -218,6 +218,7 @@ struct hb_ot_face_cmap_accelerator_t { hb_cmap_get_glyph_func_t get_glyph_func; const void *get_glyph_data; + OT::CmapSubtableFormat4::accelerator_t format4_accel; const OT::CmapSubtableFormat14 *uvs_table; hb_blob_t *blob; @@ -255,8 +256,19 @@ struct hb_ot_face_cmap_accelerator_t this->uvs_table = subtable_uvs; - this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; this->get_glyph_data = subtable; + switch (subtable->u.format) { + /* Accelerate format 4 and format 12. */ + default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break; + case 12: this->get_glyph_func = get_glyph_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; + } + break; + } } inline void fini (void) commit e0f16a715bc3e621ff21a8be88102e9672630574 Author: Behdad Esfahbod <[email protected]> Date: Wed Feb 24 19:52:36 2016 +0900 [ot-font] Towards accelerating get_glyph() diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index fe6f806..e7dbcff 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -201,9 +201,24 @@ struct hb_ot_face_glyf_accelerator_t } }; +typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph); + +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); +} + struct hb_ot_face_cmap_accelerator_t { - const OT::CmapSubtable *table; + hb_cmap_get_glyph_func_t get_glyph_func; + const void *get_glyph_data; + const OT::CmapSubtableFormat14 *uvs_table; hb_blob_t *blob; @@ -238,8 +253,10 @@ struct hb_ot_face_cmap_accelerator_t /* Meh. */ if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14); - this->table = subtable; this->uvs_table = subtable_uvs; + + this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; + this->get_glyph_data = subtable; } inline void fini (void) @@ -250,7 +267,7 @@ struct hb_ot_face_cmap_accelerator_t inline bool get_nominal_glyph (hb_codepoint_t unicode, hb_codepoint_t *glyph) const { - return this->table->get_glyph (unicode, glyph); + return this->get_glyph_func (this->get_glyph_data, unicode, glyph); } inline bool get_variation_glyph (hb_codepoint_t unicode, commit 5473ebfb84c7b6059ac16e04676b363acc51aa00 Author: Behdad Esfahbod <[email protected]> Date: Wed Feb 24 19:32:43 2016 +0900 [ot-font] Remove level of indirection in get_glyph_variant diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index c9161f0..886d348 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -388,7 +388,7 @@ struct CmapSubtableFormat14 } protected: - USHORT format; /* Format number is set to 0. */ + USHORT format; /* Format number is set to 14. */ ULONG lengthZ; /* Byte length of this subtable. */ SortedArrayOf<VariationSelectorRecord, ULONG> record; /* Variation selector records; sorted @@ -416,16 +416,6 @@ struct CmapSubtable } } - inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph) const - { - switch (u.format) { - case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph); - default: return GLYPH_VARIANT_NOT_FOUND; - } - } - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -442,7 +432,7 @@ struct CmapSubtable } } - protected: + public: union { USHORT format; /* Format identifier */ CmapSubtableFormat0 format0; diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index bba6132..fe6f806 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -204,7 +204,7 @@ struct hb_ot_face_glyf_accelerator_t struct hb_ot_face_cmap_accelerator_t { const OT::CmapSubtable *table; - const OT::CmapSubtable *uvs_table; + const OT::CmapSubtableFormat14 *uvs_table; hb_blob_t *blob; inline void init (hb_face_t *face) @@ -212,7 +212,7 @@ struct hb_ot_face_cmap_accelerator_t this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); const OT::CmapSubtable *subtable = NULL; - const OT::CmapSubtable *subtable_uvs = NULL; + const OT::CmapSubtableFormat14 *subtable_uvs = NULL; /* 32-bit subtables. */ if (!subtable) subtable = cmap->find_subtable (3, 10); @@ -229,9 +229,14 @@ struct hb_ot_face_cmap_accelerator_t if (!subtable) subtable = &OT::Null(OT::CmapSubtable); /* UVS subtable. */ - if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5); + 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 = &OT::Null(OT::CmapSubtable); + if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14); this->table = subtable; this->uvs_table = subtable_uvs; _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
