[ot-font] Add hb_ot_face_cmap_accelerator_t

This commit is contained in:
Behdad Esfahbod 2014-09-25 17:45:49 +03:00
parent d088ccaf11
commit 156852991e
1 changed files with 66 additions and 47 deletions

View File

@ -91,14 +91,72 @@ struct hb_ot_face_metrics_accelerator_t
}
};
struct hb_ot_face_cmap_accelerator_t
{
const OT::CmapSubtable *table;
const OT::CmapSubtable *uvs_table;
hb_blob_t *blob;
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 = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
const OT::CmapSubtable *subtable = NULL;
const OT::CmapSubtable *subtable_uvs = NULL;
/* 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);
/* Meh. */
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
/* UVS subtable. */
if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
/* Meh. */
if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
this->table = subtable;
this->uvs_table = subtable_uvs;
}
inline void fini (void)
{
hb_blob_destroy (this->blob);
}
inline bool get_glyph (hb_codepoint_t unicode,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph) const
{
if (unlikely (variation_selector))
{
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 this->table->get_glyph (unicode, glyph);
}
};
struct hb_ot_font_t
{
hb_ot_face_cmap_accelerator_t cmap;
hb_ot_face_metrics_accelerator_t h_metrics;
hb_ot_face_metrics_accelerator_t v_metrics;
const OT::CmapSubtable *cmap;
const OT::CmapSubtable *cmap_uvs;
hb_blob_t *cmap_blob;
};
@ -113,35 +171,9 @@ _hb_ot_font_create (hb_font_t *font)
unsigned int upem = face->get_upem ();
ot_font->cmap.init (face);
ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1);
/* TODO Can we do this lazily? */
ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem);
ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
const OT::CmapSubtable *subtable = NULL;
const OT::CmapSubtable *subtable_uvs = NULL;
/* 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);
/* Meh. */
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
/* UVS subtable. */
if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
/* Meh. */
if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
ot_font->cmap = subtable;
ot_font->cmap_uvs = subtable_uvs;
ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */
return ot_font;
}
@ -149,7 +181,7 @@ _hb_ot_font_create (hb_font_t *font)
static void
_hb_ot_font_destroy (hb_ot_font_t *ot_font)
{
hb_blob_destroy (ot_font->cmap_blob);
ot_font->cmap.fini ();
ot_font->h_metrics.fini ();
ot_font->v_metrics.fini ();
@ -167,20 +199,7 @@ hb_ot_get_glyph (hb_font_t *font HB_UNUSED,
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
if (unlikely (variation_selector))
{
switch (ot_font->cmap_uvs->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 ot_font->cmap->get_glyph (unicode, glyph);
return ot_font->cmap.get_glyph (unicode, variation_selector, glyph);
}
static hb_position_t