[subset] update COLRv1 table struct definitions
diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh
index 73909c2..bc8b322 100644
--- a/src/hb-ot-color-colr-table.hh
+++ b/src/hb-ot-color-colr-table.hh
@@ -163,15 +163,25 @@
 template <typename T>
 struct Variable
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { value.closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    if (!value.subset (c)) return_trace (false);
+    return_trace (c->serializer->embed (varIndexBase));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (c->check_struct (this) && value.sanitize (c));
   }
 
   protected:
   T      value;
-  VarIdx varIdx;
+  VarIdx varIndexBase;
   public:
   DEFINE_SIZE_STATIC (4 + T::static_size);
 };
@@ -179,10 +189,19 @@
 template <typename T>
 struct NoVariable
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { value.closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    return_trace (value.subset (c));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (c->check_struct (this) && value.sanitize (c));
   }
 
   T      value;
@@ -192,9 +211,11 @@
 
 // Color structures
 
-template <template<typename> class Var>
-struct ColorIndex
+struct ColorStop
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { c->add_palette_index (paletteIndex); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -210,32 +231,11 @@
     return_trace (c->check_struct (this));
   }
 
+  F2DOT14	stopOffset;
   HBUINT16	paletteIndex;
-  Var<F2DOT14>	alpha;
+  F2DOT14	alpha;
   public:
-  DEFINE_SIZE_STATIC (2 + Var<F2DOT14>::static_size);
-};
-
-template <template<typename> class Var>
-struct ColorStop
-{
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    if (unlikely (!c->serializer->embed (stopOffset))) return_trace (false);
-    return_trace (color.subset (c));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  Var<F2DOT14>		stopOffset;
-  ColorIndex<Var>		color;
-  public:
-  DEFINE_SIZE_STATIC (Var<F2DOT14>::static_size + ColorIndex<Var>::static_size);
+  DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size);
 };
 
 struct Extend : HBUINT8
@@ -252,6 +252,12 @@
 template <template<typename> class Var>
 struct ColorLine
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    for (const auto &stop : stops.iter ())
+      stop.closurev1 (c);
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -276,8 +282,8 @@
                   stops.sanitize (c));
   }
 
-  Extend			extend;
-  Array16Of<ColorStop<Var>>	stops;
+  Extend	extend;
+  Array16Of<Var<ColorStop>>	stops;
   public:
   DEFINE_SIZE_ARRAY_SIZED (3, stops);
 };
@@ -331,7 +337,6 @@
   DEFINE_SIZE_STATIC (1);
 };
 
-template <template<typename> class Var>
 struct Affine2x3
 {
   bool sanitize (hb_sanitize_context_t *c) const
@@ -340,14 +345,14 @@
     return_trace (c->check_struct (this));
   }
 
-  Var<HBFixed> xx;
-  Var<HBFixed> yx;
-  Var<HBFixed> xy;
-  Var<HBFixed> yy;
-  Var<HBFixed> dx;
-  Var<HBFixed> dy;
+  HBFixed xx;
+  HBFixed yx;
+  HBFixed xy;
+  HBFixed yy;
+  HBFixed dx;
+  HBFixed dy;
   public:
-  DEFINE_SIZE_STATIC (6 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (6 * HBFixed::static_size);
 };
 
 struct PaintColrLayers
@@ -373,22 +378,23 @@
 
   HBUINT8	format; /* format = 1 */
   HBUINT8	numLayers;
-  HBUINT32	firstLayerIndex;  /* index into COLRv1::layersV1 */
+  HBUINT32	firstLayerIndex;  /* index into COLRv1::layerList */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
-template <template<typename> class Var>
 struct PaintSolid
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const
-  { c->add_palette_index (color.paletteIndex); }
+  { c->add_palette_index (paletteIndex); }
 
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    if (unlikely (!c->serializer->embed (format))) return_trace (false);
-    return_trace (color.subset (c));
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -397,20 +403,18 @@
     return_trace (c->check_struct (this));
   }
 
-  HBUINT8		format; /* format = 2(noVar) or 3(Var)*/
-  ColorIndex<Var>	color;
+  HBUINT8	format; /* format = 2(noVar) or 3(Var)*/
+  HBUINT16	paletteIndex;
+  F2DOT14	alpha;
   public:
-  DEFINE_SIZE_STATIC (1 + ColorIndex<Var>::static_size);
+  DEFINE_SIZE_STATIC (3 + F2DOT14::static_size);
 };
 
 template <template<typename> class Var>
 struct PaintLinearGradient
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const
-  {
-    for (const auto &stop : (this+colorLine).stops.iter ())
-      c->add_palette_index (stop.color.paletteIndex);
-  }
+  { (this+colorLine).closurev1 (c); }
 
   bool subset (hb_subset_context_t *c) const
   {
@@ -430,19 +434,22 @@
   HBUINT8			format; /* format = 4(noVar) or 5 (Var) */
   Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintLinearGradient
                                             * table) to ColorLine subtable. */
-  Var<FWORD>			x0;
-  Var<FWORD>			y0;
-  Var<FWORD>			x1;
-  Var<FWORD>			y1;
-  Var<FWORD>			x2;
-  Var<FWORD>			y2;
+  FWORD			x0;
+  FWORD			y0;
+  FWORD			x1;
+  FWORD			y1;
+  FWORD			x2;
+  FWORD			y2;
   public:
-  DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size);
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
 };
 
 template <template<typename> class Var>
 struct PaintRadialGradient
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { (this+colorLine).closurev1 (c); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -452,12 +459,6 @@
     return_trace (out->colorLine.serialize_subset (c, colorLine, this));
   }
 
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  {
-    for (const auto &stop : (this+colorLine).stops.iter ())
-      c->add_palette_index (stop.color.paletteIndex);
-  }
-
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -467,19 +468,22 @@
   HBUINT8			format; /* format = 6(noVar) or 7 (Var) */
   Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintRadialGradient
                                             * table) to ColorLine subtable. */
-  Var<FWORD>			x0;
-  Var<FWORD>			y0;
-  Var<UFWORD>			radius0;
-  Var<FWORD>			x1;
-  Var<FWORD>			y1;
-  Var<UFWORD>			radius1;
+  FWORD			x0;
+  FWORD			y0;
+  UFWORD		radius0;
+  FWORD			x1;
+  FWORD			y1;
+  UFWORD		radius1;
   public:
-  DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size);
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
 };
 
 template <template<typename> class Var>
 struct PaintSweepGradient
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { (this+colorLine).closurev1 (c); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -489,12 +493,6 @@
     return_trace (out->colorLine.serialize_subset (c, colorLine, this));
   }
 
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  {
-    for (const auto &stop : (this+colorLine).stops.iter ())
-      c->add_palette_index (stop.color.paletteIndex);
-  }
-
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -504,12 +502,12 @@
   HBUINT8			format; /* format = 8(noVar) or 9 (Var) */
   Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintSweepGradient
                                             * table) to ColorLine subtable. */
-  Var<FWORD>			centerX;
-  Var<FWORD>			centerY;
-  Var<HBFixed>			startAngle;
-  Var<HBFixed>			endAngle;
+  FWORD			centerX;
+  FWORD			centerY;
+  F2DOT14		startAngle;
+  F2DOT14		endAngle;
   public:
-  DEFINE_SIZE_STATIC (2 * Var<FWORD>::static_size + 2 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size);
 };
 
 struct Paint;
@@ -592,12 +590,11 @@
 
   HBUINT8		format; /* format = 12(noVar) or 13 (Var) */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */
-  Affine2x3<Var>	transform;
+  Var<Affine2x3>	transform;
   public:
-  DEFINE_SIZE_STATIC (4 + Affine2x3<Var>::static_size);
+  DEFINE_SIZE_STATIC (4 + Var<Affine2x3>::static_size);
 };
 
-template <template<typename> class Var>
 struct PaintTranslate
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
@@ -619,14 +616,13 @@
 
   HBUINT8		format; /* format = 14(noVar) or 15 (Var) */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
-  Var<HBFixed>		dx;
-  Var<HBFixed>		dy;
+  FWORD		dx;
+  FWORD		dy;
   public:
-  DEFINE_SIZE_STATIC (4 + Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size);
 };
 
-template <template<typename> class Var>
-struct PaintRotate
+struct PaintScale
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
@@ -646,15 +642,150 @@
   }
 
   HBUINT8		format; /* format = 16 (noVar) or 17(Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
-  Var<HBFixed>		angle;
-  Var<HBFixed>		centerX;
-  Var<HBFixed>		centerY;
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
+  F2DOT14		scaleX;
+  F2DOT14		scaleY;
   public:
-  DEFINE_SIZE_STATIC (4 + 3 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
 };
 
-template <template<typename> class Var>
+struct PaintScaleAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 18 (noVar) or 19(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
+  F2DOT14	scaleX;
+  F2DOT14	scaleY;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintScaleUniform
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 20 (noVar) or 21(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
+  F2DOT14		scale;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
+};
+
+struct PaintScaleUniformAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 22 (noVar) or 23(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
+  F2DOT14	scale;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintRotate
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 24 (noVar) or 25(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
+  F2DOT14		angle;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
+};
+
+struct PaintRotateAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 26 (noVar) or 27(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
+  F2DOT14	angle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
 struct PaintSkew
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
@@ -674,14 +805,41 @@
     return_trace (c->check_struct (this) && src.sanitize (c, this));
   }
 
-  HBUINT8		format; /* format = 18(noVar) or 19 (Var) */
+  HBUINT8		format; /* format = 28(noVar) or 29 (Var) */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
-  Var<HBFixed>		xSkewAngle;
-  Var<HBFixed>		ySkewAngle;
-  Var<HBFixed>		centerX;
-  Var<HBFixed>		centerY;
+  F2DOT14		xSkewAngle;
+  F2DOT14		ySkewAngle;
   public:
-  DEFINE_SIZE_STATIC (4 + 4 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
+};
+
+struct PaintSkewAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 30(noVar) or 31 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
+  F2DOT14	xSkewAngle;
+  F2DOT14	ySkewAngle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
 };
 
 struct PaintComposite
@@ -706,7 +864,7 @@
                   backdrop.sanitize (c, this));
   }
 
-  HBUINT8		format; /* format = 20 */
+  HBUINT8		format; /* format = 32 */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
   CompositeMode		mode;   /* If mode is unrecognized use COMPOSITE_CLEAR */
   Offset24To<Paint>	backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */
@@ -742,37 +900,61 @@
     case 18: return_trace (c->dispatch (u.paintformat18, hb_forward<Ts> (ds)...));
     case 19: return_trace (c->dispatch (u.paintformat19, hb_forward<Ts> (ds)...));
     case 20: return_trace (c->dispatch (u.paintformat20, hb_forward<Ts> (ds)...));
+    case 21: return_trace (c->dispatch (u.paintformat21, hb_forward<Ts> (ds)...));
+    case 22: return_trace (c->dispatch (u.paintformat22, hb_forward<Ts> (ds)...));
+    case 23: return_trace (c->dispatch (u.paintformat23, hb_forward<Ts> (ds)...));
+    case 24: return_trace (c->dispatch (u.paintformat24, hb_forward<Ts> (ds)...));
+    case 25: return_trace (c->dispatch (u.paintformat25, hb_forward<Ts> (ds)...));
+    case 26: return_trace (c->dispatch (u.paintformat26, hb_forward<Ts> (ds)...));
+    case 27: return_trace (c->dispatch (u.paintformat27, hb_forward<Ts> (ds)...));
+    case 28: return_trace (c->dispatch (u.paintformat28, hb_forward<Ts> (ds)...));
+    case 29: return_trace (c->dispatch (u.paintformat29, hb_forward<Ts> (ds)...));
+    case 30: return_trace (c->dispatch (u.paintformat30, hb_forward<Ts> (ds)...));
+    case 31: return_trace (c->dispatch (u.paintformat31, hb_forward<Ts> (ds)...));
+    case 32: return_trace (c->dispatch (u.paintformat32, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
 
   protected:
   union {
-  HBUINT8				format;
-  PaintColrLayers			paintformat1;
-  PaintSolid<NoVariable>		paintformat2;
-  PaintSolid<Variable>			paintformat3;
-  PaintLinearGradient<NoVariable>	paintformat4;
-  PaintLinearGradient<Variable>		paintformat5;
-  PaintRadialGradient<NoVariable>	paintformat6;
-  PaintRadialGradient<Variable>		paintformat7;
-  PaintSweepGradient<NoVariable>	paintformat8;
-  PaintSweepGradient<Variable>		paintformat9;
-  PaintGlyph				paintformat10;
-  PaintColrGlyph			paintformat11;
-  PaintTransform<NoVariable>		paintformat12;
-  PaintTransform<Variable>		paintformat13;
-  PaintTranslate<NoVariable>		paintformat14;
-  PaintTranslate<Variable>		paintformat15;
-  PaintRotate<NoVariable>		paintformat16;
-  PaintRotate<Variable>			paintformat17;
-  PaintSkew<NoVariable>			paintformat18;
-  PaintSkew<Variable>			paintformat19;
-  PaintComposite			paintformat20;
+  HBUINT8					format;
+  PaintColrLayers				paintformat1;
+  PaintSolid					paintformat2;
+  Variable<PaintSolid>				paintformat3;
+  PaintLinearGradient<NoVariable>		paintformat4;
+  Variable<PaintLinearGradient<Variable>>	paintformat5;
+  PaintRadialGradient<NoVariable>		paintformat6;
+  Variable<PaintRadialGradient<Variable>>	paintformat7;
+  PaintSweepGradient<NoVariable>		paintformat8;
+  Variable<PaintSweepGradient<Variable>>	paintformat9;
+  PaintGlyph					paintformat10;
+  PaintColrGlyph				paintformat11;
+  PaintTransform<NoVariable>			paintformat12;
+  PaintTransform<Variable>			paintformat13;
+  PaintTranslate				paintformat14;
+  Variable<PaintTranslate>			paintformat15;
+  PaintScale					paintformat16;
+  Variable<PaintScale>				paintformat17;
+  PaintScaleAroundCenter			paintformat18;
+  Variable<PaintScaleAroundCenter>		paintformat19;
+  PaintScaleUniform				paintformat20;
+  Variable<PaintScaleUniform>			paintformat21;
+  PaintScaleUniformAroundCenter			paintformat22;
+  Variable<PaintScaleUniformAroundCenter>	paintformat23;
+  PaintRotate					paintformat24;
+  Variable<PaintRotate>				paintformat25;
+  PaintRotateAroundCenter			paintformat26;
+  Variable<PaintRotateAroundCenter>		paintformat27;
+  PaintSkew					paintformat28;
+  Variable<PaintSkew>				paintformat29;
+  PaintSkewAroundCenter				paintformat30;
+  Variable<PaintSkewAroundCenter>		paintformat31;
+  PaintComposite				paintformat32;
   } u;
 };
 
-struct BaseGlyphV1Record
+struct BaseGlyphPaintRecord
 {
   int cmp (hb_codepoint_t g) const
   { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
@@ -798,13 +980,13 @@
 
   public:
   HBGlyphID16		glyphId;    /* Glyph ID of reference glyph */
-  Offset32To<Paint>	paint;      /* Offset (from beginning of BaseGlyphV1Record array) to Paint,
+  Offset32To<Paint>	paint;      /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint,
                                      * Typically PaintColrLayers */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
-struct BaseGlyphV1List : SortedArray32Of<BaseGlyphV1Record>
+struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
 {
   bool subset (hb_subset_context_t *c) const
   {
@@ -828,11 +1010,11 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (SortedArray32Of<BaseGlyphV1Record>::sanitize (c, this));
+    return_trace (SortedArray32Of<BaseGlyphPaintRecord>::sanitize (c, this));
   }
 };
 
-struct LayerV1List : Array32OfOffset32To<Paint>
+struct LayerList : Array32OfOffset32To<Paint>
 {
   const Paint& get_paint (unsigned i) const
   { return this+(*this)[i]; }
@@ -952,24 +1134,24 @@
     hb_set_t visited_glyphs;
 
     hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices);
-    const BaseGlyphV1List &baseglyphV1_records = this+baseGlyphsV1List;
+    const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
 
-    for (const BaseGlyphV1Record &baseglyphV1record: baseglyphV1_records.iter ())
+    for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ())
     {
-      unsigned gid = baseglyphV1record.glyphId;
+      unsigned gid = baseglyph_paintrecord.glyphId;
       if (!glyphset->has (gid)) continue;
 
-      const Paint &paint = &baseglyphV1_records+baseglyphV1record.paint;
+      const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint;
       paint.dispatch (&c);
     }
     hb_set_union (glyphset, &visited_glyphs);
   }
 
-  const LayerV1List& get_layerV1List () const
-  { return (this+layersV1); }
+  const LayerList& get_layerList () const
+  { return (this+layerList); }
 
-  const BaseGlyphV1List& get_baseglyphV1List () const
-  { return (this+baseGlyphsV1List); }
+  const BaseGlyphList& get_baseglyphList () const
+  { return (this+baseGlyphList); }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -979,8 +1161,8 @@
                   (this+layersZ).sanitize (c, numLayers) &&
                   (version == 0 ||
 		   (COLRV1_ENABLE_SUBSETTING && version == 1 &&
-		    baseGlyphsV1List.sanitize (c, this) &&
-		    layersV1.sanitize (c, this) &&
+		    baseGlyphList.sanitize (c, this) &&
+		    layerList.sanitize (c, this) &&
 		    varStore.sanitize (c, this))));
   }
 
@@ -1033,9 +1215,9 @@
     return record;
   }
 
-  const BaseGlyphV1Record* get_base_glyphV1_record (hb_codepoint_t gid) const
+  const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const
   {
-    const BaseGlyphV1Record* record = &(this+baseGlyphsV1List).bsearch ((unsigned) gid);
+    const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid);
     if ((record && (hb_codepoint_t) record->glyphId != gid))
       record = nullptr;
     return record;
@@ -1106,7 +1288,7 @@
     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 (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
     {
       if (c->serializer->in_error ()) return_trace (false);
       //no more COLRv1 glyphs: downgrade to version 0
@@ -1115,7 +1297,7 @@
       return_trace (true);
     }
 
-    if (!colr_prime->layersV1.serialize_subset (c, layersV1, this)) return_trace (false);
+    if (!colr_prime->layerList.serialize_subset (c, layerList, this)) return_trace (false);
 
     colr_prime->varStore = 0;
     //TODO: subset varStore once it's implemented in fonttools
@@ -1131,8 +1313,9 @@
 		layersZ;	/* Offset to Layer Records. */
   HBUINT16	numLayers;	/* Number of Layer Records. */
   // Version-1 additions
-  Offset32To<BaseGlyphV1List>		baseGlyphsV1List;
-  Offset32To<LayerV1List>		layersV1;
+  Offset32To<BaseGlyphList>		baseGlyphList;
+  Offset32To<LayerList>			layerList;
+  //Offset32<DeltaSetIndexMap>		varIdxMap;  // Offset to DeltaSetIndexMap table (may be NULL)
   Offset32To<VariationStore>		varStore;
   public:
   DEFINE_SIZE_MIN (14);
diff --git a/src/hb-ot-color-colrv1-closure.hh b/src/hb-ot-color-colrv1-closure.hh
index 4124efe..ca85ba6 100644
--- a/src/hb-ot-color-colrv1-closure.hh
+++ b/src/hb-ot-color-colrv1-closure.hh
@@ -40,7 +40,7 @@
 HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
 {
   c->add_layer_indices (firstLayerIndex, numLayers);
-  const LayerV1List &paint_offset_lists = c->get_colr_table ()->get_layerV1List ();
+  const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
   for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
   {
     const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i];
@@ -57,37 +57,44 @@
 HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
 {
   const COLR *colr_table = c->get_colr_table ();
-  const BaseGlyphV1Record* baseglyphV1_record = colr_table->get_base_glyphV1_record (gid);
-  if (!baseglyphV1_record) return;
+  const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
+  if (!baseglyph_paintrecord) return;
   c->add_glyph (gid);
 
-  const BaseGlyphV1List &baseglyphV1_list = colr_table->get_baseglyphV1List ();
-  (&baseglyphV1_list+baseglyphV1_record->paint).dispatch (c);
+  const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
+  (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
 }
 
 template <template<typename> class Var>
 HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+{ (this+src).dispatch (c); }
 
-template <template<typename> class Var>
-HB_INTERNAL void PaintTranslate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
 
-template <template<typename> class Var>
-HB_INTERNAL void PaintRotate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
 
-template <template<typename> class Var>
-HB_INTERNAL void PaintSkew<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
 
 HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
 {