[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,34 +91,16 @@ struct hb_ot_face_metrics_accelerator_t
} }
}; };
struct hb_ot_font_t struct hb_ot_face_cmap_accelerator_t
{ {
hb_ot_face_metrics_accelerator_t h_metrics; const OT::CmapSubtable *table;
hb_ot_face_metrics_accelerator_t v_metrics; const OT::CmapSubtable *uvs_table;
hb_blob_t *blob;
const OT::CmapSubtable *cmap; inline void init (hb_face_t *face)
const OT::CmapSubtable *cmap_uvs; {
hb_blob_t *cmap_blob; 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);
static hb_ot_font_t *
_hb_ot_font_create (hb_font_t *font)
{
hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
hb_face_t *face = font->face;
if (unlikely (!ot_font))
return NULL;
unsigned int upem = face->get_upem ();
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 = NULL;
const OT::CmapSubtable *subtable_uvs = NULL; const OT::CmapSubtable *subtable_uvs = NULL;
@ -140,8 +122,58 @@ _hb_ot_font_create (hb_font_t *font)
/* Meh. */ /* Meh. */
if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable); if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
ot_font->cmap = subtable; this->table = subtable;
ot_font->cmap_uvs = subtable_uvs; 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;
};
static hb_ot_font_t *
_hb_ot_font_create (hb_font_t *font)
{
hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
hb_face_t *face = font->face;
if (unlikely (!ot_font))
return NULL;
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);
ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */
return ot_font; return ot_font;
} }
@ -149,7 +181,7 @@ _hb_ot_font_create (hb_font_t *font)
static void static void
_hb_ot_font_destroy (hb_ot_font_t *ot_font) _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->h_metrics.fini ();
ot_font->v_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; const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
return ot_font->cmap.get_glyph (unicode, variation_selector, glyph);
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);
} }
static hb_position_t static hb_position_t