[ot-font] Accelerate cmap format4 get_glyph
This commit is contained in:
parent
e0f16a715b
commit
23335deaad
|
@ -69,61 +69,78 @@ struct CmapSubtableFormat0
|
||||||
|
|
||||||
struct CmapSubtableFormat4
|
struct CmapSubtableFormat4
|
||||||
{
|
{
|
||||||
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
struct accelerator_t
|
||||||
{
|
{
|
||||||
unsigned int segCount;
|
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 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
|
||||||
|
{
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
const USHORT *endCount;
|
const USHORT *endCount;
|
||||||
const USHORT *startCount;
|
const USHORT *startCount;
|
||||||
const USHORT *idDelta;
|
const USHORT *idDelta;
|
||||||
const USHORT *idRangeOffset;
|
const USHORT *idRangeOffset;
|
||||||
const USHORT *glyphIdArray;
|
const USHORT *glyphIdArray;
|
||||||
|
unsigned int segCount;
|
||||||
unsigned int glyphIdArrayLength;
|
unsigned int glyphIdArrayLength;
|
||||||
|
};
|
||||||
|
|
||||||
segCount = this->segCountX2 / 2;
|
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||||
endCount = this->values;
|
{
|
||||||
startCount = endCount + segCount + 1;
|
accelerator_t accel;
|
||||||
idDelta = startCount + segCount;
|
accel.init (this);
|
||||||
idRangeOffset = idDelta + segCount;
|
return accel.get_glyph_func (&accel, codepoint, glyph);
|
||||||
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)
|
|
||||||
{
|
|
||||||
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 = 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
|
|
@ -218,6 +218,7 @@ struct hb_ot_face_cmap_accelerator_t
|
||||||
{
|
{
|
||||||
hb_cmap_get_glyph_func_t get_glyph_func;
|
hb_cmap_get_glyph_func_t get_glyph_func;
|
||||||
const void *get_glyph_data;
|
const void *get_glyph_data;
|
||||||
|
OT::CmapSubtableFormat4::accelerator_t format4_accel;
|
||||||
|
|
||||||
const OT::CmapSubtableFormat14 *uvs_table;
|
const OT::CmapSubtableFormat14 *uvs_table;
|
||||||
hb_blob_t *blob;
|
hb_blob_t *blob;
|
||||||
|
@ -255,8 +256,19 @@ struct hb_ot_face_cmap_accelerator_t
|
||||||
|
|
||||||
this->uvs_table = subtable_uvs;
|
this->uvs_table = subtable_uvs;
|
||||||
|
|
||||||
this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;
|
|
||||||
this->get_glyph_data = subtable;
|
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)
|
inline void fini (void)
|
||||||
|
|
Loading…
Reference in New Issue