[ot-font] Start adding vertical support
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 3514fcc..25fe511 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -39,10 +39,15 @@
struct hb_ot_font_t
{
unsigned int num_glyphs;
+
unsigned int num_hmetrics;
const OT::hmtx *hmtx;
hb_blob_t *hmtx_blob;
+ unsigned int num_vmetrics;
+ const OT::vmtx *vmtx;
+ hb_blob_t *vmtx_blob;
+
const OT::CmapSubtable *cmap;
const OT::CmapSubtable *cmap_uvs;
hb_blob_t *cmap_blob;
@@ -59,21 +64,41 @@
ot_font->num_glyphs = font->face->get_num_glyphs ();
+ /* Setup horizontal metrics. */
{
hb_blob_t *hhea_blob = OT::Sanitizer<OT::hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea));
const OT::hhea *hhea = OT::Sanitizer<OT::hhea>::lock_instance (hhea_blob);
- ot_font->num_hmetrics = hhea->numberOfHMetrics;
+ ot_font->num_hmetrics = hhea->numberOfMetrics;
hb_blob_destroy (hhea_blob);
+
+ ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::sanitize (font->face->reference_table (HB_OT_TAG_hmtx));
+ if (unlikely (!ot_font->num_hmetrics ||
+ 2 * (ot_font->num_hmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->hmtx_blob)))
+ {
+ hb_blob_destroy (ot_font->hmtx_blob);
+ free (ot_font);
+ return NULL;
+ }
+ ot_font->hmtx = OT::Sanitizer<OT::hmtx>::lock_instance (ot_font->hmtx_blob);
}
- ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::sanitize (font->face->reference_table (HB_OT_TAG_hmtx));
- if (unlikely (!ot_font->num_hmetrics ||
- 2 * (ot_font->num_hmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->hmtx_blob)))
+
+ /* Setup vertical metrics. */
{
- hb_blob_destroy (ot_font->hmtx_blob);
- free (ot_font);
- return NULL;
+ hb_blob_t *vhea_blob = OT::Sanitizer<OT::vhea>::sanitize (font->face->reference_table (HB_OT_TAG_vhea));
+ const OT::vhea *vhea = OT::Sanitizer<OT::vhea>::lock_instance (vhea_blob);
+ ot_font->num_vmetrics = vhea->numberOfMetrics;
+ hb_blob_destroy (vhea_blob);
+
+ ot_font->vmtx_blob = OT::Sanitizer<OT::vmtx>::sanitize (font->face->reference_table (HB_TAG('v','m','t','x')));
+ if (unlikely (!ot_font->num_vmetrics ||
+ 2 * (ot_font->num_vmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->vmtx_blob)))
+ {
+ hb_blob_destroy (ot_font->vmtx_blob);
+ free (ot_font);
+ return NULL;
+ }
+ ot_font->vmtx = OT::Sanitizer<OT::vmtx>::lock_instance (ot_font->vmtx_blob);
}
- ot_font->hmtx = OT::Sanitizer<OT::hmtx>::lock_instance (ot_font->hmtx_blob);
ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
@@ -109,6 +134,7 @@
{
hb_blob_destroy (ot_font->cmap_blob);
hb_blob_destroy (ot_font->hmtx_blob);
+ hb_blob_destroy (ot_font->vmtx_blob);
free (ot_font);
}
@@ -149,12 +175,12 @@
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
if (unlikely (glyph >= ot_font->num_glyphs))
- return 0; /* Maybe better to return notdef's advance instead? */
+ return 0;
if (glyph >= ot_font->num_hmetrics)
glyph = ot_font->num_hmetrics - 1;
- return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advanceWidth);
+ return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advance);
}
static hb_position_t
@@ -163,8 +189,15 @@
hb_codepoint_t glyph,
void *user_data HB_UNUSED)
{
- /* TODO */
- return 0;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+
+ if (unlikely (glyph >= ot_font->num_glyphs))
+ return 0;
+
+ if (glyph >= ot_font->num_vmetrics)
+ glyph = ot_font->num_vmetrics - 1;
+
+ return font->em_scale_y (-ot_font->vmtx->longHorMetric[glyph].advance);
}
static hb_bool_t