[subset] Fix hdmx subsetting when retain gids is enabled.
diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh
index 95229c5..b1ad3eb 100644
--- a/src/hb-ot-hdmx-table.hh
+++ b/src/hb-ot-hdmx-table.hh
@@ -57,16 +57,19 @@
     }
 
     unsigned int len () const
-    { return this->subset_plan->glyphs.length; }
+    { return this->subset_plan->num_glyphs; }
 
-    const HBUINT8* operator [] (unsigned int i) const
+    const HBUINT8* operator [] (unsigned int new_gid) const
     {
-      if (unlikely (i >= len ())) return nullptr;
-      hb_codepoint_t gid = this->subset_plan->glyphs [i];
+      if (unlikely (new_gid >= len ())) return nullptr;
 
-      if (gid >= sizeDeviceRecord - DeviceRecord::min_size)
+      hb_codepoint_t old_gid;
+      if (!this->subset_plan->old_gid_for_new_gid (new_gid, &old_gid))
+        return &Null(HBUINT8);
+
+      if (old_gid >= sizeDeviceRecord - DeviceRecord::min_size)
         return nullptr;
-      return &(this->source_device_record->widthsZ[gid]);
+      return &(this->source_device_record->widthsZ[old_gid]);
     }
   };
 
@@ -140,7 +143,7 @@
 
     this->version.set (source_hdmx->version);
     this->numRecords.set (source_hdmx->numRecords);
-    this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->glyphs.length));
+    this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->num_glyphs));
 
     for (unsigned int i = 0; i < source_hdmx->numRecords; i++)
     {
@@ -156,7 +159,7 @@
 
   static size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan)
   {
-    return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->glyphs.length);
+    return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->num_glyphs);
   }
 
   bool subset (hb_subset_plan_t *plan) const
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 63498b7..dd00f4d 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -159,13 +159,20 @@
 _create_old_gid_to_new_gid_map (bool                               retain_gids,
 				const hb_vector_t<hb_codepoint_t> &glyphs,
                                 hb_map_t                          *glyph_map, /* OUT */
+                                hb_map_t                          *reverse_glyph_map, /* OUT */
                                 unsigned int                      *num_glyphs /* OUT */)
 {
   for (unsigned int i = 0; i < glyphs.length; i++) {
     if (!retain_gids)
+    {
       glyph_map->set (glyphs[i], i);
+      reverse_glyph_map->set (i, glyphs[i]);
+    }
     else
+    {
       glyph_map->set (glyphs[i], glyphs[i]);
+      reverse_glyph_map->set (glyphs[i], glyphs[i]);
+    }
   }
   if (!retain_gids || glyphs.length == 0)
   {
@@ -202,6 +209,7 @@
   plan->dest = hb_face_builder_create ();
   plan->codepoint_to_glyph = hb_map_create();
   plan->glyph_map = hb_map_create();
+  plan->reverse_glyph_map = hb_map_create();
   plan->glyphset = _populate_gids_to_retain (face,
 					     input->unicodes,
 					     !plan->drop_layout,
@@ -212,6 +220,7 @@
   _create_old_gid_to_new_gid_map (input->retain_gids,
 				  plan->glyphs,
 				  plan->glyph_map,
+                                  plan->reverse_glyph_map,
                                   &plan->num_glyphs);
 
   return plan;
@@ -233,6 +242,7 @@
   hb_face_destroy (plan->dest);
   hb_map_destroy (plan->codepoint_to_glyph);
   hb_map_destroy (plan->glyph_map);
+  hb_map_destroy (plan->reverse_glyph_map);
   hb_set_destroy (plan->glyphset);
 
   free (plan);
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index b8b2c5d..5a90b7c 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -45,11 +45,14 @@
   // For each cp that we'd like to retain maps to the corresponding gid.
   hb_set_t *unicodes;
 
+  // The glyph subset
   hb_vector_t<hb_codepoint_t> glyphs;
   hb_set_t *glyphset;
-
   hb_map_t *codepoint_to_glyph;
+
+  // Old -> New glyph id mapping
   hb_map_t *glyph_map;
+  hb_map_t *reverse_glyph_map;
   unsigned int num_glyphs;
 
   // Plan is only good for a specific source/dest so keep them with it
@@ -77,6 +80,17 @@
     return true;
   }
 
+  bool old_gid_for_new_gid (hb_codepoint_t  new_gid,
+			    hb_codepoint_t *old_gid) const
+  {
+    hb_codepoint_t gid = reverse_glyph_map->get (new_gid);
+    if (gid == HB_MAP_VALUE_INVALID)
+      return false;
+
+    *old_gid = gid;
+    return true;
+  }
+
   bool
   add_table (hb_tag_t tag,
 	     hb_blob_t *contents)