[repacker] use mutable copies of Coverage/ClassDef in MarkBasePos shrink operation.

Also make mutable copies (when needed) of the top level subtables during a split operation.
diff --git a/src/graph/graph.hh b/src/graph/graph.hh
index e4a5d40..79c7e69 100644
--- a/src/graph/graph.hh
+++ b/src/graph/graph.hh
@@ -496,6 +496,12 @@
   }
 
   template <typename T, typename ...Ts>
+  vertex_and_table_t<T> as_mutable_table (unsigned parent, const void* offset, Ts... ds)
+  {
+    return as_table_from_index<T> (mutable_index_for_offset (parent, offset), std::forward<Ts>(ds)...);
+  }
+
+  template <typename T, typename ...Ts>
   vertex_and_table_t<T> as_table_from_index (unsigned index, Ts... ds)
   {
     if (index >= vertices_.length)
@@ -833,7 +839,20 @@
    * parent to the clone. The copy is a shallow copy, objects
    * linked from child are not duplicated.
    */
-  bool duplicate (unsigned parent_idx, unsigned child_idx)
+  unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx)
+  {
+    unsigned new_idx = duplicate (parent_idx, child_idx);
+    if (new_idx == (unsigned) -1) return child_idx;
+    return new_idx;
+  }
+
+
+  /*
+   * Creates a copy of child and re-assigns the link from
+   * parent to the clone. The copy is a shallow copy, objects
+   * linked from child are not duplicated.
+   */
+  unsigned duplicate (unsigned parent_idx, unsigned child_idx)
   {
     update_parents ();
 
@@ -849,7 +868,7 @@
       // to child are from parent.
       DEBUG_MSG (SUBSET_REPACK, nullptr, "  Not duplicating %d => %d",
                  parent_idx, child_idx);
-      return false;
+      return -1;
     }
 
     DEBUG_MSG (SUBSET_REPACK, nullptr, "  Duplicating %d => %d",
@@ -869,7 +888,7 @@
       reassign_link (l, parent_idx, clone_idx);
     }
 
-    return true;
+    return clone_idx;
   }
 
 
diff --git a/src/graph/gsubgpos-graph.hh b/src/graph/gsubgpos-graph.hh
index a93e7d1..e8d5bef 100644
--- a/src/graph/gsubgpos-graph.hh
+++ b/src/graph/gsubgpos-graph.hh
@@ -131,8 +131,10 @@
     for (unsigned i = 0; i < subTable.len; i++)
     {
       unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]);
+      unsigned parent_index = this_index;
       if (is_ext) {
         unsigned ext_subtable_index = subtable_index;
+        parent_index = ext_subtable_index;
         ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension =
             (ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*)
             c.graph.object (ext_subtable_index).head;
@@ -150,9 +152,9 @@
       switch (type)
       {
       case 2:
-        new_sub_tables = split_subtable<PairPos> (c, subtable_index); break;
+        new_sub_tables = split_subtable<PairPos> (c, parent_index, subtable_index); break;
       case 4:
-        new_sub_tables = split_subtable<MarkBasePos> (c, subtable_index); break;
+        new_sub_tables = split_subtable<MarkBasePos> (c, parent_index, subtable_index); break;
       default:
         break;
       }
@@ -172,13 +174,14 @@
 
   template<typename T>
   hb_vector_t<unsigned> split_subtable (gsubgpos_graph_context_t& c,
+                                        unsigned parent_idx,
                                         unsigned objidx)
   {
     T* sub_table = (T*) c.graph.object (objidx).head;
     if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx]))
       return hb_vector_t<unsigned> ();
 
-    return sub_table->split_subtables (c, objidx);
+    return sub_table->split_subtables (c, parent_idx, objidx);
   }
 
   void add_sub_tables (gsubgpos_graph_context_t& c,
diff --git a/src/graph/markbasepos-graph.hh b/src/graph/markbasepos-graph.hh
index 56fa812..e42a604 100644
--- a/src/graph/markbasepos-graph.hh
+++ b/src/graph/markbasepos-graph.hh
@@ -209,7 +209,9 @@
     return vertex_len >= MarkBasePosFormat1::static_size;
   }
 
-  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
+  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
+                                         unsigned parent_index,
+                                         unsigned this_index)
   {
     hb_set_t visited;
 
@@ -261,7 +263,7 @@
     split_context_t split_context {
       c,
       this,
-      this_index,
+      c.graph.duplicate_if_shared (parent_index, this_index),
       std::move (class_to_info),
       c.graph.vertices_[mark_array_id].position_to_index_map (),
     };
@@ -365,8 +367,8 @@
 
     classCount = count;
 
-    auto mark_coverage = sc.c.graph.as_table<Coverage> (this_index,
-                                                        &markCoverage);
+    auto mark_coverage = sc.c.graph.as_mutable_table<Coverage> (this_index,
+                                                                &markCoverage);
     if (!mark_coverage) return false;
     hb_set_t marks = sc.marks_for (0, count);
     auto new_coverage =
@@ -380,17 +382,17 @@
       return false;
 
 
-    auto base_array = sc.c.graph.as_table<AnchorMatrix> (this_index,
-                                                         &baseArray,
-                                                         old_count);
+    auto base_array = sc.c.graph.as_mutable_table<AnchorMatrix> (this_index,
+                                                                 &baseArray,
+                                                                 old_count);
     if (!base_array || !base_array.table->shrink (sc.c,
                                                   base_array.index,
                                                   old_count,
                                                   count))
       return false;
 
-    auto mark_array = sc.c.graph.as_table<MarkArray> (this_index,
-                                                      &markArray);
+    auto mark_array = sc.c.graph.as_mutable_table<MarkArray> (this_index,
+                                                              &markArray);
     if (!mark_array || !mark_array.table->shrink (sc.c,
                                                   sc.mark_array_links,
                                                   mark_array.index,
@@ -469,11 +471,12 @@
 struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos
 {
   hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
+                                         unsigned parent_index,
                                          unsigned this_index)
   {
     switch (u.format) {
     case 1:
-      return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, this_index);
+      return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
 #ifndef HB_NO_BORING_EXPANSION
     case 2: HB_FALLTHROUGH;
       // Don't split 24bit PairPos's.
diff --git a/src/graph/pairpos-graph.hh b/src/graph/pairpos-graph.hh
index 976b872..c3aa471 100644
--- a/src/graph/pairpos-graph.hh
+++ b/src/graph/pairpos-graph.hh
@@ -47,7 +47,9 @@
         min_size + pairSet.get_size () - pairSet.len.get_size();
   }
 
-  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
+  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
+                                         unsigned parent_index,
+                                         unsigned this_index)
   {
     hb_set_t visited;
 
@@ -81,7 +83,7 @@
     split_context_t split_context {
       c,
       this,
-      this_index,
+      c.graph.duplicate_if_shared (parent_index, this_index),
     };
 
     return actuate_subtable_split<split_context_t> (split_context, split_points);
@@ -125,23 +127,19 @@
     pairSet.len = count;
     c.graph.vertices_[this_index].obj.tail -= (old_count - count) * SmallTypes::size;
 
-    unsigned coverage_id = c.graph.mutable_index_for_offset (this_index, &coverage);
-    unsigned coverage_size = c.graph.vertices_[coverage_id].table_size ();
-    auto& coverage_v = c.graph.vertices_[coverage_id];
+    auto coverage = c.graph.as_mutable_table<Coverage> (this_index, &this->coverage);
+    if (!coverage) return false;
 
-    Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
-    if (!coverage_table || !coverage_table->sanitize (coverage_v))
-      return false;
-
+    unsigned coverage_size = coverage.vertex->table_size ();
     auto new_coverage =
-        + hb_zip (coverage_table->iter (), hb_range ())
+        + hb_zip (coverage.table->iter (), hb_range ())
         | hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) {
           return p.second < count;
         })
         | hb_map_retains_sorting (hb_first)
         ;
 
-    return Coverage::make_coverage (c, new_coverage, coverage_id, coverage_size);
+    return Coverage::make_coverage (c, new_coverage, coverage.index, coverage_size);
   }
 
   // Create a new PairPos including PairSet's from start (inclusive) to end (exclusive).
@@ -206,7 +204,9 @@
         min_size + class1_count * get_class1_record_size ();
   }
 
-  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
+  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
+                                         unsigned parent_index,
+                                         unsigned this_index)
   {
     const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>::min_size;
     const unsigned class_def_2_size = size_of (c, this_index, &classDef2);
@@ -287,7 +287,7 @@
     split_context_t split_context {
       c,
       this,
-      this_index,
+      c.graph.duplicate_if_shared (parent_index, this_index),
       class1_record_size,
       total_value_len,
       value_1_len,
@@ -508,24 +508,18 @@
     graph.vertices_[split_context.this_index].obj.tail -=
         (old_count - count) * split_context.class1_record_size;
 
-    unsigned coverage_id =
-        graph.mutable_index_for_offset (split_context.this_index, &coverage);
-    unsigned class_def_1_id =
-        graph.mutable_index_for_offset (split_context.this_index, &classDef1);
-    auto& coverage_v = graph.vertices_[coverage_id];
-    auto& class_def_1_v = graph.vertices_[class_def_1_id];
-    Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
-    ClassDef* class_def_1_table = (ClassDef*) class_def_1_v.obj.head;
-    if (!coverage_table
-        || !coverage_table->sanitize (coverage_v)
-        || !class_def_1_table
-        || !class_def_1_table->sanitize (class_def_1_v))
-      return false;
+    auto coverage =
+        graph.as_mutable_table<Coverage> (split_context.this_index, &this->coverage);
+    if (!coverage) return false;
+
+    auto class_def_1 =
+        graph.as_mutable_table<ClassDef> (split_context.this_index, &classDef1);
+    if (!class_def_1) return false;
 
     auto klass_map =
-    + coverage_table->iter ()
+    + coverage.table->iter ()
     | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
-      return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1_table->get_class (gid));
+      return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1.table->get_class (gid));
     })
     | hb_filter ([&] (hb_codepoint_t klass) {
       return klass < count;
@@ -534,14 +528,14 @@
 
     if (!Coverage::make_coverage (split_context.c,
                                   + klass_map | hb_map_retains_sorting (hb_first),
-                                  coverage_id,
-                                  coverage_v.table_size ()))
+                                  coverage.index,
+                                  coverage.vertex->table_size ()))
       return false;
 
     return ClassDef::make_class_def (split_context.c,
                                      + klass_map,
-                                     class_def_1_id,
-                                     class_def_1_v.table_size ());
+                                     class_def_1.index,
+                                     class_def_1.vertex->table_size ());
   }
 
   hb_hashmap_t<unsigned, unsigned>
@@ -605,13 +599,15 @@
 
 struct PairPos : public OT::Layout::GPOS_impl::PairPos
 {
-  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
+  hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
+                                         unsigned parent_index,
+                                         unsigned this_index)
   {
     switch (u.format) {
     case 1:
-      return ((PairPosFormat1*)(&u.format1))->split_subtables (c, this_index);
+      return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
     case 2:
-      return ((PairPosFormat2*)(&u.format2))->split_subtables (c, this_index);
+      return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index);
 #ifndef HB_NO_BORING_EXPANSION
     case 3: HB_FALLTHROUGH;
     case 4: HB_FALLTHROUGH;
diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh
index 40a5326..c97ce6c 100644
--- a/src/hb-repacker.hh
+++ b/src/hb-repacker.hh
@@ -244,7 +244,7 @@
     {
       // The child object is shared, we may be able to eliminate the overflow
       // by duplicating it.
-      if (!sorted_graph.duplicate (r.parent, r.child)) continue;
+      if (sorted_graph.duplicate (r.parent, r.child) == (unsigned) -1) continue;
       return true;
     }