[subset] subset both CPAL and COLRv1
diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh
index 93e473d..3e375c4 100644
--- a/src/hb-ot-color-colr-table.hh
+++ b/src/hb-ot-color-colr-table.hh
@@ -185,7 +185,7 @@
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
-    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colrv1_palettes->get (paletteIndex),
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
                                                HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
@@ -807,7 +807,7 @@
       else return_trace (false);
     }
 
-    return_trace (true);
+    return_trace (out->len != 0);
   }
 };
 
@@ -822,9 +822,12 @@
     auto *out = c->serializer->start_embed (this);
     if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
 
-    for (const auto& offset : as_array ()) {
+    for (const auto& _ : + hb_enumerate (*this)
+                         | hb_filter (c->plan->colrv1_layers, hb_first))
+
+    {
       auto *o = out->serialize_append (c->serializer);
-      if (unlikely (!o) || !o->serialize_subset (c, offset, this))
+      if (unlikely (!o) || !o->serialize_subset (c, _.second, this))
         return_trace (false);
     }
     return_trace (true);
@@ -878,6 +881,10 @@
 			 hb_set_t *related_ids /* OUT */) const
     { colr->closure_glyphs (glyph, related_ids); }
 
+    void closure_V0palette_indices (const hb_set_t *glyphs,
+				    hb_set_t *palettes /* OUT */) const
+    { colr->closure_V0palette_indices (glyphs, palettes); }
+
     void closure_forV1 (hb_set_t *glyphset,
                         hb_set_t *layer_indices,
                         hb_set_t *palette_indices) const
@@ -899,6 +906,23 @@
     related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size);
   }
 
+  void closure_V0palette_indices (const hb_set_t *glyphs,
+				  hb_set_t *palettes /* OUT */) const
+  {
+    if (!numBaseGlyphs || !numLayers) return;
+    hb_array_t<const BaseGlyphRecord> baseGlyphs = (this+baseGlyphsZ).as_array (numBaseGlyphs);
+    hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
+    
+    for (const BaseGlyphRecord record : baseGlyphs)
+    {
+      if (!glyphs->has (record.glyphId)) continue;
+      hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
+                                                                   record.numLayers);
+      for (const LayerRecord layer : glyph_layers)
+        palettes->add (layer.colorIdx);
+    }
+  }
+
   void closure_forV1 (hb_set_t *glyphset,
                       hb_set_t *layer_indices,
                       hb_set_t *palette_indices) const
@@ -941,10 +965,10 @@
   template<typename BaseIterator, typename LayerIterator,
 	   hb_requires (hb_is_iterator (BaseIterator)),
 	   hb_requires (hb_is_iterator (LayerIterator))>
-  bool serialize (hb_serialize_context_t *c,
-		  unsigned version,
-		  BaseIterator base_it,
-		  LayerIterator layer_it)
+  bool serialize_V0 (hb_serialize_context_t *c,
+		     unsigned version,
+		     BaseIterator base_it,
+		     LayerIterator layer_it)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (base_it.len () != layer_it.len ()))
@@ -954,6 +978,12 @@
     this->version = version;
     numLayers = 0;
     numBaseGlyphs = base_it.len ();
+    if (base_it.len () == 0)
+    {
+      baseGlyphsZ = 0;
+      layersZ = 0;
+      return_trace (true);
+    }
     baseGlyphsZ = COLR::min_size;
     layersZ = COLR::min_size + numBaseGlyphs * BaseGlyphRecord::min_size;
 
@@ -1036,6 +1066,7 @@
 				  if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid)))
 				    return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
 				  out_layers[i].glyphId = new_gid;
+				  out_layers[i].colorIdx = c->plan->colr_palettes->get (layers[i].colorIdx);
 				}
 
 				return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers);
@@ -1044,11 +1075,29 @@
     | hb_map_retains_sorting (hb_second)
     ;
 
-    if (unlikely (!base_it || !layer_it || base_it.len () != layer_it.len ()))
+    if (version == 0 && (!base_it || !layer_it))
       return_trace (false);
 
     COLR *colr_prime = c->serializer->start_embed<COLR> ();
-    return_trace (colr_prime->serialize (c->serializer, version, base_it, layer_it));
+    bool ret = colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it);
+
+    if (version == 0) return_trace (ret);
+    auto snap = c->serializer->snapshot ();
+    if (!c->serializer->allocate_size<void> (3 * HBUINT32::static_size)) return_trace (false);
+    if (!colr_prime->baseGlyphsV1List.serialize_subset (c, baseGlyphsV1List, this))
+    {
+      if (c->serializer->in_error ()) return_trace (false);
+      //no more COLRv1 glyphs: downgrade to version 0
+      c->serializer->revert (snap);
+      colr_prime->version = 0;
+      return_trace (true);
+    }
+
+    if (!colr_prime->layersV1.serialize_subset (c, layersV1, this)) return_trace (false);
+
+    colr_prime->varStore = 0;
+    //TODO: subset varStore once it's implemented in fonttools
+    return_trace (true);
   }
 
   protected:
diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh
index 2fa99de..a59b46b 100644
--- a/src/hb-ot-color-cpal-table.hh
+++ b/src/hb-ot-color-cpal-table.hh
@@ -39,7 +39,6 @@
  */
 #define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
 
-
 namespace OT {
 
 
@@ -74,6 +73,58 @@
   }
 
   public:
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned palette_count,
+                  unsigned color_count,
+                  const void *base,
+                  const hb_map_t *color_index_map) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->allocate_size<CPALV1Tail> (static_size);
+    if (unlikely (!out)) return_trace (false);
+
+    const hb_array_t<const HBUINT32> paletteFlags = (base+paletteFlagsZ).as_array (palette_count);
+    const hb_array_t<const NameID> paletteLabels = (base+paletteLabelsZ).as_array (palette_count);
+    const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
+
+    c->push ();
+    for (const auto _ : paletteFlags)
+    {
+      if (!c->copy<HBUINT32> (_))
+      {
+        c->pop_discard ();
+        return_trace (false);
+      }
+    }
+    c->add_link (out->paletteFlagsZ, c->pop_pack ());
+
+    c->push ();
+    for (const auto _ : paletteLabels)
+    {
+      if (!c->copy<NameID> (_))
+      {
+        c->pop_discard ();
+        return_trace (false);
+      }
+    }
+    c->add_link (out->paletteLabelsZ, c->pop_pack ());
+
+    c->push ();
+    for (const auto _ : colorLabels)
+    {
+      if (!color_index_map->has (_)) continue;
+      NameID new_color_idx;
+      new_color_idx = color_index_map->get (_);
+      if (!c->copy<NameID> (new_color_idx))
+      {
+        c->pop_discard ();
+        return_trace (false);
+      }
+    }
+    c->add_link (out->colorLabelsZ, c->pop_pack ());
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c,
 		 const void *base,
 		 unsigned int palette_count,
@@ -157,6 +208,84 @@
   }
 
   public:
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_array_t<const BGRAColor> &color_records,
+                  const hb_array_t<const HBUINT16> &color_record_indices,
+                  const hb_map_t &color_record_index_map,
+                  const hb_set_t &retained_color_record_indices) const
+  {
+    TRACE_SERIALIZE (this);
+
+    for (const auto idx : color_record_indices)
+    {
+      HBUINT16 new_idx;
+      if (idx == 0) new_idx = 0;
+      else new_idx = color_record_index_map.get (idx);
+      if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
+    }
+
+    c->push ();
+    for (const auto _ : retained_color_record_indices.iter ())
+    {
+      if (!c->copy<BGRAColor> (color_records[_]))
+      {
+        c->pop_discard ();
+        return_trace (false);
+      }
+    }
+    c->add_link (colorRecordsZ, c->pop_pack ());
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_map_t *color_index_map = c->plan->colr_palettes;
+    if (color_index_map->is_empty ()) return_trace (false);
+
+    hb_set_t retained_color_indices;
+    for (const auto _ : color_index_map->keys ())
+    {
+      if (_ == 0xFFFF) continue;
+      retained_color_indices.add (_);
+    }
+    if (retained_color_indices.is_empty ()) return_trace (false);
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    
+    out->version = version;
+    out->numColors = retained_color_indices.get_population ();
+    out->numPalettes = numPalettes;
+
+    const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
+    hb_map_t color_record_index_map;
+    hb_set_t retained_color_record_indices;
+
+    unsigned record_count = 0;
+    for (const auto first_color_record_idx : colorRecordIndices)
+    {
+      for (unsigned retained_color_idx : retained_color_indices.iter ())
+      {
+        unsigned color_record_idx = first_color_record_idx + retained_color_idx;
+        if (color_record_index_map.has (color_record_idx)) continue;
+        color_record_index_map.set (color_record_idx, record_count);
+        retained_color_record_indices.add (color_record_idx);
+        record_count++;
+      }
+    }
+
+    out->numColorRecords = record_count;
+    const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
+    if (!out->serialize (c->serializer, color_records, colorRecordIndices, color_record_index_map, retained_color_record_indices))
+      return_trace (false);
+
+    if (version == 1)
+      return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
+
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 04505cb..b620322 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -57,6 +57,23 @@
 #endif
 
 static void
+_remap_palette_indexes (const hb_set_t *palette_indexes,
+                        hb_map_t       *mapping /* OUT */)
+{
+  unsigned new_idx = 0;
+  for (unsigned palette_index : palette_indexes->iter ())
+  {
+    if (palette_index == 0xFFFF)
+    {
+      mapping->set (palette_index, palette_index);
+      continue;
+    }
+    mapping->set (palette_index, new_idx);
+    new_idx++;
+  }
+}
+
+static void
 _remap_indexes (const hb_set_t *indexes,
 		hb_map_t       *mapping /* OUT */)
 {
@@ -278,11 +295,14 @@
   }
 
   _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
+
+  hb_set_t palette_indices;
+  colr.closure_V0palette_indices (plan->_glyphset, &palette_indices);
   
-  hb_set_t layer_indices, palette_indices;
+  hb_set_t layer_indices;
   colr.closure_forV1 (plan->_glyphset, &layer_indices, &palette_indices);
   _remap_indexes (&layer_indices, plan->colrv1_layers);
-  _remap_indexes (&palette_indices, plan->colrv1_palettes);
+  _remap_palette_indexes (&palette_indices, plan->colr_palettes);
   colr.fini ();
   _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
 
@@ -397,7 +417,7 @@
   plan->gsub_features = hb_map_create ();
   plan->gpos_features = hb_map_create ();
   plan->colrv1_layers = hb_map_create ();
-  plan->colrv1_palettes = hb_map_create ();
+  plan->colr_palettes = hb_map_create ();
   plan->layout_variation_indices = hb_set_create ();
   plan->layout_variation_idx_map = hb_map_create ();
 
@@ -449,7 +469,7 @@
   hb_map_destroy (plan->gsub_features);
   hb_map_destroy (plan->gpos_features);
   hb_map_destroy (plan->colrv1_layers);
-  hb_map_destroy (plan->colrv1_palettes);
+  hb_map_destroy (plan->colr_palettes);
   hb_set_destroy (plan->layout_variation_indices);
   hb_map_destroy (plan->layout_variation_idx_map);
 
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index 615f12e..79c34a7 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -89,7 +89,7 @@
 
   //active layers/palettes we'd like to retain
   hb_map_t *colrv1_layers;
-  hb_map_t *colrv1_palettes;
+  hb_map_t *colr_palettes;
 
   //The set of layout item variation store delta set indices to be retained
   hb_set_t *layout_variation_indices;
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index d443d24..6a5ce52 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -39,6 +39,7 @@
 #include "hb-ot-maxp-table.hh"
 #include "hb-ot-color-sbix-table.hh"
 #include "hb-ot-color-colr-table.hh"
+#include "hb-ot-color-cpal-table.hh"
 #include "hb-ot-os2-table.hh"
 #include "hb-ot-post-table.hh"
 #include "hb-ot-cff1-table.hh"
@@ -266,6 +267,7 @@
   case HB_OT_TAG_OS2 : return _subset<const OT::OS2 > (plan);
   case HB_OT_TAG_post: return _subset<const OT::post> (plan);
   case HB_OT_TAG_COLR: return _subset<const OT::COLR> (plan);
+  case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan);
   case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan);
   case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */
 
diff --git a/test/api/fonts/TwemojiMozilla.subset.default.32,3299.ttf b/test/api/fonts/TwemojiMozilla.subset.default.32,3299.ttf
index be3a53d..2f1a11a 100644
--- a/test/api/fonts/TwemojiMozilla.subset.default.32,3299.ttf
+++ b/test/api/fonts/TwemojiMozilla.subset.default.32,3299.ttf
Binary files differ
diff --git a/test/api/fonts/TwemojiMozilla.subset.default.32.ttf b/test/api/fonts/TwemojiMozilla.subset.default.32.ttf
index b7d70ad..d77db78 100644
--- a/test/api/fonts/TwemojiMozilla.subset.default.32.ttf
+++ b/test/api/fonts/TwemojiMozilla.subset.default.32.ttf
Binary files differ
diff --git a/test/api/fonts/TwemojiMozilla.subset.default.3297.ttf b/test/api/fonts/TwemojiMozilla.subset.default.3297.ttf
index 09e5056..5028110 100644
--- a/test/api/fonts/TwemojiMozilla.subset.default.3297.ttf
+++ b/test/api/fonts/TwemojiMozilla.subset.default.3297.ttf
Binary files differ
diff --git a/test/api/fonts/TwemojiMozilla.subset.ttf b/test/api/fonts/TwemojiMozilla.subset.ttf
index 357dda3..7d09649 100644
--- a/test/api/fonts/TwemojiMozilla.subset.ttf
+++ b/test/api/fonts/TwemojiMozilla.subset.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297,3299.ttf
index 357dda3..42c2a8a 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297.ttf
index adedf7a..8c3191a 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3299.ttf
index 1fbce41..743ca0c 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32.ttf
index 34ea336..f21fab0 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.32.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297,3299.ttf
index 3d021a2..c2081b3 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297.ttf
index b8c6e6b..5ea2026 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3299.ttf
index d2abf38..8acea94 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.default.3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297,3299.ttf
index 3644ec0..d0d5187 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297.ttf
index 81c92b4..91207c0 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3299.ttf
index 37ab302..41f381b 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32.ttf
index c84776d..0273ead 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.32.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297,3299.ttf
index 4f7f8ef..ccc2504 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297.ttf
index 271c6b4..0af003a 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3299.ttf
index 88b4ec9..1900ddf 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints-retain-gids.3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297,3299.ttf
index 3644ec0..d0d5187 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297.ttf
index 12040a1..175b42d 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3299.ttf
index ab4b9e2..1593f16 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32.ttf
index c84776d..0273ead 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.32.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297,3299.ttf
index 7707dcc..10dde89 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297.ttf
index dd0e1a9..fb7dc77 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3299.ttf
index e59928b..0725ade 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.drop-hints.3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297,3299.ttf
index 357dda3..42c2a8a 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297.ttf
index d04142d..32628c4 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3299.ttf
index 983eb75..25ba6b3 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32.ttf
index 34ea336..f21fab0 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.32.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297,3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297,3299.ttf
index ed60276..80df9b2 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297,3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297,3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297.ttf
index 60a5a3a..97faf4b 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3297.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3299.ttf b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3299.ttf
index 803af3f..ff8cabb 100644
--- a/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3299.ttf
+++ b/test/subset/data/expected/colr/TwemojiMozilla.subset.retain-gids.3299.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr_with_components/colr-table.default.6B.ttf b/test/subset/data/expected/colr_with_components/colr-table.default.6B.ttf
index a73bffb..28f0057 100644
--- a/test/subset/data/expected/colr_with_components/colr-table.default.6B.ttf
+++ b/test/subset/data/expected/colr_with_components/colr-table.default.6B.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr_with_components/colr-table.drop-hints-retain-gids.6B.ttf b/test/subset/data/expected/colr_with_components/colr-table.drop-hints-retain-gids.6B.ttf
index 4a4784c..5ab44e9 100644
--- a/test/subset/data/expected/colr_with_components/colr-table.drop-hints-retain-gids.6B.ttf
+++ b/test/subset/data/expected/colr_with_components/colr-table.drop-hints-retain-gids.6B.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr_with_components/colr-table.drop-hints.6B.ttf b/test/subset/data/expected/colr_with_components/colr-table.drop-hints.6B.ttf
index a73bffb..28f0057 100644
--- a/test/subset/data/expected/colr_with_components/colr-table.drop-hints.6B.ttf
+++ b/test/subset/data/expected/colr_with_components/colr-table.drop-hints.6B.ttf
Binary files differ
diff --git a/test/subset/data/expected/colr_with_components/colr-table.retain-gids.6B.ttf b/test/subset/data/expected/colr_with_components/colr-table.retain-gids.6B.ttf
index 4a4784c..5ab44e9 100644
--- a/test/subset/data/expected/colr_with_components/colr-table.retain-gids.6B.ttf
+++ b/test/subset/data/expected/colr_with_components/colr-table.retain-gids.6B.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.default.E000,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.default.E000,E004.ttf
new file mode 100644
index 0000000..424c6ba
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.default.E000,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.default.E003,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.default.E003,E004.ttf
new file mode 100644
index 0000000..d2778a2
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.default.E003,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.default.E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.default.E004.ttf
new file mode 100644
index 0000000..ef769c7
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.default.E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.default.retain-all-codepoint.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.default.retain-all-codepoint.ttf
new file mode 100644
index 0000000..7cd14c4
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.default.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E000,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E000,E004.ttf
new file mode 100644
index 0000000..819335b
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E000,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E003,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E003,E004.ttf
new file mode 100644
index 0000000..7d1f333
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E003,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E004.ttf
new file mode 100644
index 0000000..451d665
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..9bb3da5
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints-retain-gids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E000,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E000,E004.ttf
new file mode 100644
index 0000000..eef68d7
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E000,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E003,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E003,E004.ttf
new file mode 100644
index 0000000..e3cd398
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E003,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E004.ttf
new file mode 100644
index 0000000..e8dfae6
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.retain-all-codepoint.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.retain-all-codepoint.ttf
new file mode 100644
index 0000000..9bb3da5
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.drop-hints.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E000,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E000,E004.ttf
new file mode 100644
index 0000000..6e3f5fb
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E000,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E003,E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E003,E004.ttf
new file mode 100644
index 0000000..ee80313
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E003,E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E004.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E004.ttf
new file mode 100644
index 0000000..32d69dc
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.E004.ttf
Binary files differ
diff --git a/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..7cd14c4
--- /dev/null
+++ b/test/subset/data/expected/colrv1/TestCOLRv1.retain-gids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/fonts/TestCOLRv1.ttf b/test/subset/data/fonts/TestCOLRv1.ttf
new file mode 100644
index 0000000..262f266
--- /dev/null
+++ b/test/subset/data/fonts/TestCOLRv1.ttf
Binary files differ
diff --git a/test/subset/data/tests/colrv1.tests b/test/subset/data/tests/colrv1.tests
new file mode 100644
index 0000000..f579737
--- /dev/null
+++ b/test/subset/data/tests/colrv1.tests
@@ -0,0 +1,21 @@
+FONTS:
+TestCOLRv1.ttf
+
+PROFILES:
+default.txt
+drop-hints.txt
+drop-hints-retain-gids.txt
+retain-gids.txt
+
+SUBSETS:
+#U+E000
+#U+E001
+#U+E003
+U+E004
+#U+E000,U+E001
+#U+E002,U+E003
+U+E000,U+E004
+U+E003,U+E004
+#U+E000,U+E001,U+E002
+#U+E000,U+E001,U+E002,U+E003
+*
diff --git a/test/subset/subset_test_suite.py b/test/subset/subset_test_suite.py
index b7fd105..a58d017 100644
--- a/test/subset/subset_test_suite.py
+++ b/test/subset/subset_test_suite.py
@@ -11,8 +11,12 @@
 		self.subset = subset
 
 	def unicodes(self):
+		import re
 		if self.subset == '*':
 			return self.subset[0]
+		elif re.match("^U\+", self.subset):
+			s = re.sub (r"U\+", "", self.subset)
+			return s
 		else:
 			return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))