From 23335deaad9d4d9824ff41343264514d3f9f7e37 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Feb 2016 20:27:13 +0900 Subject: [PATCH] [ot-font] Accelerate cmap format4 get_glyph --- src/hb-ot-cmap-table.hh | 111 ++++++++++++++++++++++++++++-------------------- src/hb-ot-font.cc | 14 +++++- 2 files changed, 77 insertions(+), 48 deletions(-) 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; this->get_glyph_data = subtable; + switch (subtable->u.format) { + /* Accelerate format 4 and format 12. */ + default: this->get_glyph_func = get_glyph_from; break; + case 12: this->get_glyph_func = get_glyph_from; 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) -- 2.7.4