[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