diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh index 623775a77..42b332658 100644 --- a/src/OT/Color/COLR/COLR.hh +++ b/src/OT/Color/COLR/COLR.hh @@ -159,23 +159,32 @@ struct hb_colrv1_closure_context_t : void add_palette_index (unsigned palette_index) { palette_indices->add (palette_index); } + void add_var_idxes (unsigned first_var_idx, unsigned num_idxes) + { variation_indices->add_range (first_var_idx, first_var_idx + num_idxes - 1); } + public: const void *base; hb_set_t visited_paint; hb_set_t *glyphs; hb_set_t *layer_indices; hb_set_t *palette_indices; + hb_set_t *variation_indices; + unsigned num_var_idxes; unsigned nesting_level_left; hb_colrv1_closure_context_t (const void *base_, hb_set_t *glyphs_, hb_set_t *layer_indices_, hb_set_t *palette_indices_, + hb_set_t *variation_indices_, + unsigned num_var_idxes_ = 1, unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) : base (base_), glyphs (glyphs_), layer_indices (layer_indices_), palette_indices (palette_indices_), + variation_indices (variation_indices_), + num_var_idxes (num_var_idxes_), nesting_level_left (nesting_level_left_) {} }; @@ -242,7 +251,11 @@ struct Variable } void closurev1 (hb_colrv1_closure_context_t* c) const - { value.closurev1 (c); } + { + // update c->num_var_idxes during value closure + value.closurev1 (c); + c->add_var_idxes (varIdxBase, c->num_var_idxes); + } bool subset (hb_subset_context_t *c, const ItemVarStoreInstancer &instancer) const @@ -345,7 +358,10 @@ struct NoVariable struct ColorStop { void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } + { + c->add_palette_index (paletteIndex); + c->num_var_idxes = 2; + } bool subset (hb_subset_context_t *c, const ItemVarStoreInstancer &instancer, @@ -542,6 +558,9 @@ struct Affine2x3 return_trace (c->check_struct (this)); } + void closurev1 (hb_colrv1_closure_context_t* c) const + { c->num_var_idxes = 6; } + bool subset (hb_subset_context_t *c, const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const @@ -617,7 +636,10 @@ struct PaintColrLayers struct PaintSolid { void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } + { + c->add_palette_index (paletteIndex); + c->num_var_idxes = 1; + } bool subset (hb_subset_context_t *c, const ItemVarStoreInstancer &instancer, @@ -666,7 +688,10 @@ template class Var> struct PaintLinearGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 6; + } bool subset (hb_subset_context_t *c, const ItemVarStoreInstancer &instancer, @@ -733,7 +758,10 @@ template class Var> struct PaintRadialGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 6; + } bool subset (hb_subset_context_t *c, const ItemVarStoreInstancer &instancer, @@ -800,7 +828,10 @@ template class Var> struct PaintSweepGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 4; + } bool subset (hb_subset_context_t *c, const ItemVarStoreInstancer &instancer, @@ -1544,6 +1575,9 @@ struct ClipBoxFormat2 : Variable clip_box.yMax += roundf (instancer (varIdxBase, 3)); } } + + void closurev1 (hb_colrv1_closure_context_t* c) const + { c->variation_indices->add_range (varIdxBase, varIdxBase + 3); } }; struct ClipBox @@ -1559,6 +1593,14 @@ struct ClipBox } } + void closurev1 (hb_colrv1_closure_context_t* c) const + { + switch (u.format) { + case 2: u.format2.closurev1 (c); + default:return; + } + } + template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { @@ -1606,6 +1648,12 @@ struct ClipRecord int cmp (hb_codepoint_t g) const { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; } + void closurev1 (hb_colrv1_closure_context_t* c, const void *base) const + { + if (!c->glyphs->intersects (startGlyphID, endGlyphID)) return; + (base+clipBox).closurev1 (c); + } + bool subset (hb_subset_context_t *c, const void *base, const ItemVarStoreInstancer &instancer) const @@ -1992,8 +2040,9 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, - hb_set_t *palette_indices) const - { colr->closure_forV1 (glyphset, layer_indices, palette_indices); } + hb_set_t *palette_indices, + hb_set_t *variation_indices) const + { colr->closure_forV1 (glyphset, layer_indices, palette_indices, variation_indices); } private: hb_blob_ptr_t colr; @@ -2030,14 +2079,15 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, - hb_set_t *palette_indices) const + hb_set_t *palette_indices, + hb_set_t *variation_indices) const { if (version != 1) return; hb_barrier (); hb_set_t visited_glyphs; - hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); + hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices, variation_indices); const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ()) @@ -2049,6 +2099,11 @@ struct COLR paint.dispatch (&c); } hb_set_union (glyphset, &visited_glyphs); + + const ClipList &cliplist = this+clipList; + c.glyphs = glyphset; + for (const ClipRecord &clip_record : cliplist.clips.iter()) + clip_record.closurev1 (&c, &cliplist); } const LayerList& get_layerList () const diff --git a/src/OT/Color/COLR/colrv1-closure.hh b/src/OT/Color/COLR/colrv1-closure.hh index 705863d4a..9ed0aa563 100644 --- a/src/OT/Color/COLR/colrv1-closure.hh +++ b/src/OT/Color/COLR/colrv1-closure.hh @@ -66,34 +66,64 @@ HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) cons template class Var> HB_INTERNAL void PaintTransform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + (this+transform).closurev1 (c); +} HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 4; +} HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 1; +} HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 3; +} HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 1; +} HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 3; +} HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 4; +} HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const { diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 068fddaed..865041a3e 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -506,7 +506,8 @@ static void _colr_closure (hb_face_t *face, glyphs_colred->union_ (glyphset_colrv0); //closure for COLRv1 - colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); + hb_set_t variation_indices; + colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); _remap_indexes (&layer_indices, layers_map);