Implement hmtx/vmtx metrics read from hvar/vvar
diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh
index 6b2cc86..cf1f3b4 100644
--- a/src/hb-ot-hmtx-table.hh
+++ b/src/hb-ot-hmtx-table.hh
@@ -53,6 +53,18 @@
   DEFINE_SIZE_STATIC (4);
 };
 
+struct hmtxvmtx_accelerator_base_t
+{
+  static int get_side_bearing_var_tt (hb_font_t *font HB_UNUSED,
+				      hb_codepoint_t glyph HB_UNUSED,
+				      bool is_vertical HB_UNUSED)
+  { return 0; } /* Not implemented yet */
+  static unsigned int get_advance_var_tt (hb_font_t *font HB_UNUSED,
+					  hb_codepoint_t glyph HB_UNUSED,
+					  bool is_vertical HB_UNUSED)
+  { return 0; } /* Not implemented yet */
+};
+
 template <typename T, typename H>
 struct hmtxvmtx
 {
@@ -133,7 +145,7 @@
 	  if (c->plan->old_gid_for_new_gid (_, &old_gid))
 	    return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
 	  else
-	    return hb_pair (0u, 0u);
+	    return hb_pair (0u, 0);
 	})
     ;
 
@@ -153,13 +165,14 @@
     return_trace (true);
   }
 
-  struct accelerator_t
+  struct accelerator_t : hmtxvmtx_accelerator_base_t
   {
     friend struct hmtxvmtx;
 
     void init (hb_face_t *face,
 	       unsigned int default_advance_ = 0)
     {
+      memset (this, 0, sizeof (*this));
       default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
 
       num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics;
@@ -190,8 +203,9 @@
       var_table.destroy ();
     }
 
-    /* TODO Add variations version. */
-    unsigned int get_side_bearing (hb_codepoint_t glyph) const
+    bool has_data () const { return table.get () != nullptr; }
+
+    int get_side_bearing (hb_codepoint_t glyph) const
     {
       if (glyph < num_advances)
 	return table->longMetricZ[glyph].sb;
@@ -203,6 +217,22 @@
       return bearings[glyph - num_advances];
     }
 
+    int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
+    {
+      int side_bearing = get_side_bearing (glyph);
+      if (likely (glyph < num_metrics))
+      {
+	if (font->num_coords)
+	{
+	  if (var_table.get_blob () != hb_blob_get_empty ())
+	    side_bearing += var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+	  else
+	    side_bearing = get_side_bearing_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx);
+	}
+      }
+      return side_bearing;
+    }
+
     unsigned int get_advance (hb_codepoint_t glyph) const
     {
       if (unlikely (glyph >= num_metrics))
@@ -225,7 +255,13 @@
       unsigned int advance = get_advance (glyph);
       if (likely (glyph < num_metrics))
       {
-	advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
+	if (font->num_coords)
+	{
+	  if (var_table.get_blob () != hb_blob_get_empty ())
+	    advance += roundf (var_table->get_advance_var (glyph, font->coords, font->num_coords)); // TODO Optimize?!
+	  else
+	    advance = get_advance_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx);
+	}
       }
       return advance;
     }
diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh
index a8d9fe3..628a600 100644
--- a/src/hb-ot-var-hvar-table.hh
+++ b/src/hb-ot-var-hvar-table.hh
@@ -63,7 +63,7 @@
     }
 
     { /* Repack it. */
-      unsigned int n = get_inner_bitcount ();
+      unsigned int n = get_inner_bit_count ();
       unsigned int outer = u >> n;
       unsigned int inner = u & ((1 << n) - 1);
       u = (outer<<16) | inner;
@@ -72,10 +72,9 @@
     return u;
   }
 
-  protected:
-  unsigned int get_width () const          { return ((format >> 4) & 3) + 1; }
-
-  unsigned int get_inner_bitcount () const { return (format & 0xF) + 1; }
+  unsigned int get_map_count () const	    { return mapCount; }
+  unsigned int get_width () const           { return ((format >> 4) & 3) + 1; }
+  unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; }
 
   protected:
   HBUINT16	format;		/* A packed field that describes the compressed
@@ -121,7 +120,15 @@
     return (this+varStore).get_delta (varidx, coords, coord_count);
   }
 
-  bool has_sidebearing_deltas () const { return lsbMap && rsbMap; }
+  float get_side_bearing_var (hb_codepoint_t glyph,
+			      const int *coords, unsigned int coord_count) const
+  {
+    if (!has_side_bearing_deltas ()) return 0.f;
+    unsigned int varidx = (this+lsbMap).map (glyph);
+    return (this+varStore).get_delta (varidx, coords, coord_count);
+  }
+
+  bool has_side_bearing_deltas () const { return lsbMap && rsbMap; }
 
   protected:
   FixedVersion<>version;	/* Version of the metrics variation table