[subset] COLRv1 layer/palette indices closure
This commit is contained in:
parent
a08900b721
commit
e59ffe5482
@ -40,6 +40,63 @@
|
||||
|
||||
namespace OT {
|
||||
|
||||
struct COLR;
|
||||
struct hb_colrv1_closure_context_t :
|
||||
hb_dispatch_context_t<hb_colrv1_closure_context_t>
|
||||
{
|
||||
template <typename T>
|
||||
return_t dispatch (const T &obj)
|
||||
{
|
||||
if (paint_visited (&obj))
|
||||
return hb_empty_t ();
|
||||
|
||||
obj.closurev1 (this);
|
||||
return hb_empty_t ();
|
||||
}
|
||||
static return_t default_return_value () { return hb_empty_t (); }
|
||||
|
||||
bool paint_visited (const void *paint)
|
||||
{
|
||||
hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
|
||||
if (visited_paint->has (delta))
|
||||
return true;
|
||||
|
||||
visited_paint->add (delta);
|
||||
return false;
|
||||
}
|
||||
|
||||
const COLR* get_colr_table () const
|
||||
{ return reinterpret_cast<const COLR *> (base); }
|
||||
|
||||
void add_glyph (unsigned glyph_id)
|
||||
{ glyphs->add (glyph_id); }
|
||||
|
||||
void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers)
|
||||
{ layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); }
|
||||
|
||||
void add_palette_index (unsigned palette_index)
|
||||
{ palette_indices->add (palette_index); }
|
||||
|
||||
public:
|
||||
const void *base;
|
||||
hb_set_t visited_paint[1];
|
||||
hb_set_t *glyphs;
|
||||
hb_set_t *layer_indices;
|
||||
hb_set_t *palette_indices;
|
||||
|
||||
hb_colrv1_closure_context_t (const void *base_,
|
||||
hb_set_t *glyphs_,
|
||||
hb_set_t *layer_indices_,
|
||||
hb_set_t *palette_indices_) :
|
||||
base (base_),
|
||||
glyphs (glyphs_),
|
||||
layer_indices (layer_indices_),
|
||||
palette_indices (palette_indices_)
|
||||
{}
|
||||
|
||||
~hb_colrv1_closure_context_t () { hb_set_clear (visited_paint); }
|
||||
};
|
||||
|
||||
struct LayerRecord
|
||||
{
|
||||
operator hb_ot_color_layer_t () const { return {glyphId, colorIdx}; }
|
||||
@ -249,6 +306,8 @@ struct Affine2x3
|
||||
|
||||
struct PaintColrLayers
|
||||
{
|
||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -265,6 +324,9 @@ struct PaintColrLayers
|
||||
template <template<typename> class Var>
|
||||
struct PaintSolid
|
||||
{
|
||||
void closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ c->add_palette_index (color.paletteIndex); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -280,6 +342,12 @@ struct PaintSolid
|
||||
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);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -302,6 +370,12 @@ struct PaintLinearGradient
|
||||
template <template<typename> class Var>
|
||||
struct PaintRadialGradient
|
||||
{
|
||||
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);
|
||||
@ -324,6 +398,12 @@ struct PaintRadialGradient
|
||||
template <template<typename> class Var>
|
||||
struct PaintSweepGradient
|
||||
{
|
||||
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);
|
||||
@ -345,6 +425,8 @@ struct Paint;
|
||||
// Paint a non-COLR glyph, filled as indicated by paint.
|
||||
struct PaintGlyph
|
||||
{
|
||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -360,6 +442,8 @@ struct PaintGlyph
|
||||
|
||||
struct PaintColrGlyph
|
||||
{
|
||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -375,6 +459,8 @@ struct PaintColrGlyph
|
||||
template <template<typename> class Var>
|
||||
struct PaintTransform
|
||||
{
|
||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -391,6 +477,8 @@ struct PaintTransform
|
||||
template <template<typename> class Var>
|
||||
struct PaintTranslate
|
||||
{
|
||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -408,6 +496,8 @@ struct PaintTranslate
|
||||
template <template<typename> class Var>
|
||||
struct PaintRotate
|
||||
{
|
||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -426,6 +516,8 @@ struct PaintRotate
|
||||
template <template<typename> class Var>
|
||||
struct PaintSkew
|
||||
{
|
||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -444,6 +536,8 @@ struct PaintSkew
|
||||
|
||||
struct PaintComposite
|
||||
{
|
||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -592,6 +686,11 @@ struct COLR
|
||||
hb_set_t *related_ids /* OUT */) const
|
||||
{ colr->closure_glyphs (glyph, related_ids); }
|
||||
|
||||
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); }
|
||||
|
||||
private:
|
||||
hb_blob_ptr_t<COLR> colr;
|
||||
};
|
||||
@ -608,6 +707,33 @@ struct COLR
|
||||
related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size);
|
||||
}
|
||||
|
||||
void closure_forV1 (hb_set_t *glyphset,
|
||||
hb_set_t *layer_indices,
|
||||
hb_set_t *palette_indices) const
|
||||
{
|
||||
if (version != 1) return;
|
||||
hb_set_t visited_glyphs;
|
||||
|
||||
hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices);
|
||||
const BaseGlyphV1List &baseglyphV1_records = this+baseGlyphsV1List;
|
||||
|
||||
for (const BaseGlyphV1Record &baseglyphV1record: baseglyphV1_records.iter ())
|
||||
{
|
||||
unsigned gid = baseglyphV1record.glyphId;
|
||||
if (!glyphset->has (gid)) continue;
|
||||
|
||||
const Paint &paint = &baseglyphV1_records+baseglyphV1record.paint;
|
||||
paint.dispatch (&c);
|
||||
}
|
||||
hb_set_union (glyphset, &visited_glyphs);
|
||||
}
|
||||
|
||||
const LayerV1List& get_layerV1List () const
|
||||
{ return (this+layersV1); }
|
||||
|
||||
const BaseGlyphV1List& get_baseglyphV1List () const
|
||||
{ return (this+baseGlyphsV1List); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -663,6 +789,14 @@ struct COLR
|
||||
return record;
|
||||
}
|
||||
|
||||
const BaseGlyphV1Record* get_base_glyphV1_record (hb_codepoint_t gid) const
|
||||
{
|
||||
const BaseGlyphV1Record* record = &(this+baseGlyphsV1List).bsearch ((unsigned) gid);
|
||||
if ((record && (hb_codepoint_t) record->glyphId != gid))
|
||||
record = nullptr;
|
||||
return record;
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
|
101
src/hb-ot-color-colrv1-closure.hh
Normal file
101
src/hb-ot-color-colrv1-closure.hh
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
* Copyright © 2020 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_COLR_COLRV1_CLOSURE_HH
|
||||
#define HB_OT_COLR_COLRV1_CLOSURE_HH
|
||||
|
||||
#include "hb-open-type.hh"
|
||||
#include "hb-ot-layout-common.hh"
|
||||
#include "hb-ot-color-colr-table.hh"
|
||||
|
||||
/*
|
||||
* COLR -- Color
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/colr
|
||||
*/
|
||||
namespace OT {
|
||||
|
||||
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 ();
|
||||
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
|
||||
{
|
||||
const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i];
|
||||
paint.dispatch (c);
|
||||
}
|
||||
}
|
||||
|
||||
HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
c->add_glyph (gid);
|
||||
(this+paint).dispatch (c);
|
||||
}
|
||||
|
||||
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;
|
||||
c->add_glyph (gid);
|
||||
|
||||
const BaseGlyphV1List &baseglyphV1_list = colr_table->get_baseglyphV1List ();
|
||||
(&baseglyphV1_list+baseglyphV1_record->paint).dispatch (c);
|
||||
}
|
||||
|
||||
template <template<typename> typename Var>
|
||||
HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
(this+src).dispatch (c);
|
||||
}
|
||||
|
||||
template <template<typename> typename Var>
|
||||
HB_INTERNAL void PaintTranslate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
(this+src).dispatch (c);
|
||||
}
|
||||
|
||||
template <template<typename> typename Var>
|
||||
HB_INTERNAL void PaintRotate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
(this+src).dispatch (c);
|
||||
}
|
||||
|
||||
template <template<typename> typename Var>
|
||||
HB_INTERNAL void PaintSkew<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
(this+src).dispatch (c);
|
||||
}
|
||||
|
||||
HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
(this+src).dispatch (c);
|
||||
(this+backdrop).dispatch (c);
|
||||
}
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_COLR_COLRV1_CLOSURE_HH */
|
@ -35,6 +35,7 @@
|
||||
#include "hb-ot-layout-gsub-table.hh"
|
||||
#include "hb-ot-cff1-table.hh"
|
||||
#include "hb-ot-color-colr-table.hh"
|
||||
#include "hb-ot-color-colrv1-closure.hh"
|
||||
#include "hb-ot-var-fvar-table.hh"
|
||||
#include "hb-ot-stat-table.hh"
|
||||
|
||||
@ -277,6 +278,13 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
||||
}
|
||||
|
||||
_remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
|
||||
|
||||
hb_set_t layer_indices, palette_indices;
|
||||
colr.closure_forV1 (plan->_glyphset, &layer_indices, &palette_indices);
|
||||
_remap_indexes (&layer_indices, plan->colrv1_layers);
|
||||
_remap_indexes (&palette_indices, plan->colrv1_palettes);
|
||||
colr.fini ();
|
||||
_remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
if (close_over_gdef)
|
||||
@ -388,6 +396,8 @@ hb_subset_plan_create (hb_face_t *face,
|
||||
|
||||
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->layout_variation_indices = hb_set_create ();
|
||||
plan->layout_variation_idx_map = hb_map_create ();
|
||||
|
||||
@ -438,6 +448,8 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
||||
hb_map_destroy (plan->gpos_lookups);
|
||||
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_set_destroy (plan->layout_variation_indices);
|
||||
hb_map_destroy (plan->layout_variation_idx_map);
|
||||
|
||||
|
@ -87,6 +87,10 @@ struct hb_subset_plan_t
|
||||
hb_map_t *gsub_features;
|
||||
hb_map_t *gpos_features;
|
||||
|
||||
//active layers/palettes we'd like to retain
|
||||
hb_map_t *colrv1_layers;
|
||||
hb_map_t *colrv1_palettes;
|
||||
|
||||
//The set of layout item variation store delta set indices to be retained
|
||||
hb_set_t *layout_variation_indices;
|
||||
//Old -> New layout item variation store delta set index mapping
|
||||
|
Loading…
Reference in New Issue
Block a user