[subset] GPOS6 MarkToMark subsetting support
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index e0459c2..3e02931 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1961,8 +1961,70 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping);
+    
+    if (!klass_mapping.get_population ()) return_trace (false);
+    out->classCount = klass_mapping.get_population ();
+
+    auto mark1_iter =
+    + hb_zip (this+mark1Coverage, this+mark1Array)
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + mark1_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->mark1Coverage.serialize (c->serializer, out)
+			   .serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    out->mark1Array.serialize (c->serializer, out)
+		   .serialize (c->serializer, &klass_mapping, &(this+mark1Array), + mark1_iter
+										  | hb_map (hb_second));
+//////
+    unsigned mark2count = (this+mark2Array).rows;
+    auto mark2_iter =
+    + hb_zip (this+mark2Coverage, hb_range (mark2count))
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    new_coverage.reset ();
+    + mark2_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->mark2Coverage.serialize (c->serializer, out)
+			   .serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    hb_sorted_vector_t<unsigned> mark2_indexes;
+    for (const unsigned row : + mark2_iter
+			      | hb_map (hb_second))
+    {
+      + hb_range ((unsigned) classCount)
+      | hb_filter (klass_mapping)
+      | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+      | hb_sink (mark2_indexes)
+      ;
+    }
+    out->mark2Array.serialize (c->serializer, out)
+		   .serialize (c->serializer, mark2_iter.len (), &(this+mark2Array), mark2_indexes.iter ());
+
+    return_trace (true);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
diff --git a/test/subset/data/Makefile.am b/test/subset/data/Makefile.am
index 81aee95..2070582 100644
--- a/test/subset/data/Makefile.am
+++ b/test/subset/data/Makefile.am
@@ -17,6 +17,7 @@
 	expected/layout.gpos2 \
 	expected/layout.gpos3 \
 	expected/layout.gpos4 \
+	expected/layout.gpos6 \
 	expected/layout.gsub6 \
 	expected/cmap \
 	expected/cmap14 \
diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources
index b5b4a1f..2b57ef0 100644
--- a/test/subset/data/Makefile.sources
+++ b/test/subset/data/Makefile.sources
@@ -9,6 +9,7 @@
 	tests/layout.gpos2.tests \
 	tests/layout.gpos3.tests \
 	tests/layout.gpos4.tests \
+	tests/layout.gpos6.tests \
 	tests/layout.gsub6.tests \
 	tests/cmap.tests \
 	tests/cmap14.tests \
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43,44.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43,44.otf
new file mode 100644
index 0000000..92d1e28
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43,44.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43,45.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43,45.otf
new file mode 100644
index 0000000..28d5cb4
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43,45.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43.otf
new file mode 100644
index 0000000..7d58a98
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42.otf
new file mode 100644
index 0000000..4261081
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,42.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,44,45,46.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,44,45,46.otf
new file mode 100644
index 0000000..d944ebf
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,44,45,46.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,44.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,44.otf
new file mode 100644
index 0000000..7dc3d62
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,44.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,45.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,45.otf
new file mode 100644
index 0000000..f7727d4
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43,45.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43.otf
new file mode 100644
index 0000000..7e564d5
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41.otf
new file mode 100644
index 0000000..c9ae1c7
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.41.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644
index 0000000..f636342
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout-retain-gids.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43,44.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43,44.otf
new file mode 100644
index 0000000..106c55a
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43,44.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43,45.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43,45.otf
new file mode 100644
index 0000000..ba37625
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43,45.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43.otf
new file mode 100644
index 0000000..8a6aa87
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42.otf
new file mode 100644
index 0000000..1b8a1ca
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,42.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,44,45,46.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,44,45,46.otf
new file mode 100644
index 0000000..09e27e6
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,44,45,46.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,44.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,44.otf
new file mode 100644
index 0000000..48e8928
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,44.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,45.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,45.otf
new file mode 100644
index 0000000..e4656fe
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43,45.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43.otf
new file mode 100644
index 0000000..5527d9f
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41.otf
new file mode 100644
index 0000000..c151b9d
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.41.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.retain-all-codepoint.otf
new file mode 100644
index 0000000..f636342
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos6/gpos6_font1.keep-layout.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/fonts/gpos6_font1.otf b/test/subset/data/fonts/gpos6_font1.otf
new file mode 100644
index 0000000..fd640ac
--- /dev/null
+++ b/test/subset/data/fonts/gpos6_font1.otf
Binary files differ
diff --git a/test/subset/data/tests/layout.gpos6.tests b/test/subset/data/tests/layout.gpos6.tests
new file mode 100644
index 0000000..d31e0d4
--- /dev/null
+++ b/test/subset/data/tests/layout.gpos6.tests
@@ -0,0 +1,18 @@
+FONTS:
+gpos6_font1.otf
+
+PROFILES:
+keep-layout.txt
+keep-layout-retain-gids.txt
+
+SUBSETS:
+A
+AB
+AC
+ABC
+ACE
+ABCE
+ACD
+ACDEF
+ABCD
+*