[instancer] add subset() for MVAR
diff --git a/src/hb-ot-var-mvar-table.hh b/src/hb-ot-var-mvar-table.hh
index d27ebb3..a41e578 100644
--- a/src/hb-ot-var-mvar-table.hh
+++ b/src/hb-ot-var-mvar-table.hh
@@ -27,7 +27,7 @@
 #ifndef HB_OT_VAR_MVAR_TABLE_HH
 #define HB_OT_VAR_MVAR_TABLE_HH
 
-#include "hb-ot-layout-common.hh"
+#include "hb-ot-var-common.hh"
 
 
 namespace OT {
@@ -41,6 +41,19 @@
     return_trace (c->check_struct (this));
   }
 
+  bool subset (hb_subset_context_t *c,
+               const hb_map_t& varidx_map) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    hb_codepoint_t *new_idx;
+    return_trace (c->serializer->check_assign (out->varIdx,
+                                               (varidx_map.has (varIdx, &new_idx)) ? *new_idx : HB_OT_LAYOUT_NO_VARIATIONS_INDEX,
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   public:
   Tag		valueTag;	/* Four-byte tag identifying a font-wide measure. */
   VarIdx	varIdx;		/* Outer/inner index into VariationStore item. */
@@ -73,6 +86,52 @@
 				  valueRecordSize));
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+#ifdef HB_NO_VAR
+    return_trace (false);
+#endif
+
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    MVAR *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->version = version;
+    out->reserved = reserved;
+    out->valueRecordSize = valueRecordSize;
+    out->valueRecordCount = valueRecordCount;
+
+    item_variations_t item_vars;
+    const VariationStore& src_var_store = this+varStore;
+    if (!item_vars.create_from_item_varstore (src_var_store, c->plan->axes_old_index_tag_map))
+      return_trace (false);
+
+    if (!item_vars.instantiate (c->plan->axes_location, c->plan->axes_triple_distances))
+      return_trace (false);
+
+    if (!item_vars.optimize ())
+      return_trace (false);
+
+    /* serialize varstore */
+    if (!out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (),
+                                            c->plan->axis_tags,
+                                            item_vars.get_region_list (),
+                                            item_vars.get_vardata_encodings ()))
+      return_trace (false);
+
+    /* serialize value records array */
+    unsigned value_rec_count = valueRecordCount;
+    const VariationValueRecord *record = reinterpret_cast<const VariationValueRecord*> (valuesZ.arrayZ);
+    for (unsigned i = 0; i < value_rec_count; i++)
+    {
+      if (!record->subset (c, item_vars.get_varidx_map ())) return_trace (false);
+      record++;
+    }
+    return_trace (true);
+  }
+
   float get_var (hb_tag_t tag,
 		 const int *coords, unsigned int coord_count) const
   {
diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc
index aade558..0277d3d 100644
--- a/src/hb-subset-input.cc
+++ b/src/hb-subset-input.cc
@@ -74,7 +74,6 @@
     HB_TAG ('p', 'r', 'e', 'p'),
     HB_TAG ('V', 'D', 'M', 'X'),
     HB_TAG ('D', 'S', 'I', 'G'),
-    HB_TAG ('M', 'V', 'A', 'R'),
   };
   sets.no_subset_tables->add_array (default_no_subset_tables,
 					 ARRAY_LENGTH (default_no_subset_tables));
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 100ce87..de3e876 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -55,6 +55,7 @@
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-var-gvar-table.hh"
 #include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-var-mvar-table.hh"
 #include "hb-ot-math-table.hh"
 #include "hb-ot-stat-table.hh"
 #include "hb-repacker.hh"
@@ -523,6 +524,9 @@
   case HB_OT_TAG_cvar:
     if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
     return _subset<const OT::cvar> (plan, buf);
+  case HB_OT_TAG_MVAR:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset<const OT::MVAR> (plan, buf);
   case HB_OT_TAG_STAT:
     if (!plan->user_axes_location.is_empty ()) return _subset<const OT::STAT> (plan, buf);
     else return _passthrough (plan, tag);