[subset] optimize glyf subsetting w/ retain gids.
When retain gids is enabled the subset plan may require the output of many empty glyphs. This change optimizes the glyf subsetting code when the number of retained glyphs << number of output glyphs. Unnessecary lookups to the glyph map are reduced by iterating through the glyph map instead of the output glyph set.
This commit is contained in:
parent
e94fe2adf3
commit
8f1bf23cc9
|
@ -346,10 +346,16 @@ struct Glyph
|
||||||
|
|
||||||
hb_bytes_t get_bytes () const { return bytes; }
|
hb_bytes_t get_bytes () const { return bytes; }
|
||||||
|
|
||||||
Glyph (hb_bytes_t bytes_ = hb_bytes_t (),
|
Glyph () : bytes (),
|
||||||
hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_),
|
header (bytes.as<GlyphHeader> ()),
|
||||||
header (bytes.as<GlyphHeader> ()),
|
gid (-1),
|
||||||
gid (gid_)
|
type(EMPTY)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Glyph (hb_bytes_t bytes_,
|
||||||
|
hb_codepoint_t gid_ = (unsigned) -1) : bytes (bytes_),
|
||||||
|
header (bytes.as<GlyphHeader> ()),
|
||||||
|
gid (gid_)
|
||||||
{
|
{
|
||||||
int num_contours = header->numberOfContours;
|
int num_contours = header->numberOfContours;
|
||||||
if (unlikely (num_contours == 0)) type = EMPTY;
|
if (unlikely (num_contours == 0)) type = EMPTY;
|
||||||
|
|
|
@ -14,7 +14,6 @@ namespace glyf_impl {
|
||||||
|
|
||||||
struct SubsetGlyph
|
struct SubsetGlyph
|
||||||
{
|
{
|
||||||
hb_codepoint_t new_gid;
|
|
||||||
hb_codepoint_t old_gid;
|
hb_codepoint_t old_gid;
|
||||||
Glyph source_glyph;
|
Glyph source_glyph;
|
||||||
hb_bytes_t dest_start; /* region of source_glyph to copy first */
|
hb_bytes_t dest_start; /* region of source_glyph to copy first */
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct glyf
|
||||||
if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
|
if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
|
||||||
|
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
|
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
|
||||||
_populate_subset_glyphs (c->plan, &glyphs);
|
_populate_subset_glyphs (c->plan, glyphs);
|
||||||
|
|
||||||
if (!c->plan->pinned_at_default)
|
if (!c->plan->pinned_at_default)
|
||||||
{
|
{
|
||||||
|
@ -108,7 +108,7 @@ struct glyf
|
||||||
|
|
||||||
void
|
void
|
||||||
_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
|
hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
|
_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
|
||||||
|
@ -377,34 +377,30 @@ struct glyf_accelerator_t
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
|
hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
|
||||||
{
|
{
|
||||||
OT::glyf_accelerator_t glyf (plan->source);
|
OT::glyf_accelerator_t glyf (plan->source);
|
||||||
|
unsigned num_glyphs = plan->num_output_glyphs ();
|
||||||
|
if (!glyphs.resize (num_glyphs)) return;
|
||||||
|
|
||||||
+ hb_range (plan->num_output_glyphs ())
|
for (auto p : plan->glyph_map->iter ())
|
||||||
| hb_map ([&] (hb_codepoint_t new_gid)
|
{
|
||||||
{
|
unsigned new_gid = p.second;
|
||||||
glyf_impl::SubsetGlyph subset_glyph = {0};
|
glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid];
|
||||||
subset_glyph.new_gid = new_gid;
|
subset_glyph.old_gid = p.first;
|
||||||
|
|
||||||
/* should never fail: all old gids should be mapped */
|
if (unlikely (new_gid == 0 &&
|
||||||
if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
|
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
|
||||||
return subset_glyph;
|
plan->pinned_at_default)
|
||||||
|
subset_glyph.source_glyph = glyf_impl::Glyph ();
|
||||||
|
else
|
||||||
|
subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
|
||||||
|
|
||||||
if (new_gid == 0 &&
|
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
||||||
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) &&
|
subset_glyph.drop_hints_bytes ();
|
||||||
plan->pinned_at_default)
|
else
|
||||||
subset_glyph.source_glyph = glyf_impl::Glyph ();
|
subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
|
||||||
else
|
}
|
||||||
subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
|
|
||||||
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
|
||||||
subset_glyph.drop_hints_bytes ();
|
|
||||||
else
|
|
||||||
subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
|
|
||||||
return subset_glyph;
|
|
||||||
})
|
|
||||||
| hb_sink (glyphs)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
|
Loading…
Reference in New Issue