summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2016-02-24 20:27:13 +0900
committerBehdad Esfahbod <behdad@behdad.org>2016-02-24 20:27:13 +0900
commit23335deaad9d4d9824ff41343264514d3f9f7e37 (patch)
tree72f5dbcfc6874196b31823c25e7541ce5c0ead9f
parente0f16a715bc3e621ff21a8be88102e9672630574 (diff)
[ot-font] Accelerate cmap format4 get_glyph
-rw-r--r--src/hb-ot-cmap-table.hh111
-rw-r--r--src/hb-ot-font.cc14
2 files changed, 77 insertions, 48 deletions
diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index 886d348e..d7a94a1e 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 e7dbcffc..61c70365 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)