[subset/cff] Speed up sid mapping

pull/4269/head
Behdad Esfahbod 1 year ago
parent ffc6899b0c
commit 59387dbe43
  1. 47
      src/hb-ot-cff1-table.hh
  2. 14
      src/hb-subset-cff1.cc

@ -391,16 +391,31 @@ struct Charset1_2 {
return_trace (true); return_trace (true);
} }
hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs,
code_pair_t *cache = nullptr) const
{ {
if (unlikely (glyph >= num_glyphs)) return 0; if (unlikely (glyph >= num_glyphs)) return 0;
if (unlikely (glyph == 0)) return 0; if (unlikely (glyph == 0)) return 0;
glyph--; hb_codepoint_t start_glyph = 1;
for (unsigned int i = 0;; i++) unsigned i = 0;
if (cache && likely (cache->glyph <= glyph))
{ {
if (glyph <= ranges[i].nLeft) i = cache->code;
return (hb_codepoint_t) ranges[i].first + glyph; start_glyph = cache->glyph;
glyph -= (ranges[i].nLeft + 1); }
glyph -= start_glyph;
for (;; i++)
{
unsigned count = ranges[i].nLeft;
if (glyph <= count)
{
if (cache)
*cache = {i, start_glyph};
return ranges[i].first + glyph;
}
count++;
start_glyph += count;
glyph -= count;
} }
return 0; return 0;
@ -553,13 +568,14 @@ struct Charset
} }
} }
hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs) const hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs,
code_pair_t *cache = nullptr) const
{ {
switch (format) switch (format)
{ {
case 0: return u.format0.get_sid (glyph, num_glyphs); case 0: return u.format0.get_sid (glyph, num_glyphs);
case 1: return u.format1.get_sid (glyph, num_glyphs); case 1: return u.format1.get_sid (glyph, num_glyphs, cache);
case 2: return u.format2.get_sid (glyph, num_glyphs); case 2: return u.format2.get_sid (glyph, num_glyphs, cache);
default:return 0; default:return 0;
} }
} }
@ -1211,13 +1227,14 @@ struct cff1
bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; } bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const hb_codepoint_t glyph_to_code (hb_codepoint_t glyph,
code_pair_t *glyph_to_sid_cache = nullptr) const
{ {
if (encoding != &Null (Encoding)) if (encoding != &Null (Encoding))
return encoding->get_code (glyph); return encoding->get_code (glyph);
else else
{ {
hb_codepoint_t sid = glyph_to_sid (glyph); hb_codepoint_t sid = glyph_to_sid (glyph, glyph_to_sid_cache);
if (sid == 0) return 0; if (sid == 0) return 0;
hb_codepoint_t code = 0; hb_codepoint_t code = 0;
switch (topDict.EncodingOffset) switch (topDict.EncodingOffset)
@ -1250,10 +1267,11 @@ struct cff1
return nullptr; return nullptr;
} }
hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph,
code_pair_t *cache = nullptr) const
{ {
if (charset != &Null (Charset)) if (charset != &Null (Charset))
return charset->get_sid (glyph, num_glyphs); return charset->get_sid (glyph, num_glyphs, cache);
else else
{ {
hb_codepoint_t sid = 0; hb_codepoint_t sid = 0;
@ -1396,9 +1414,10 @@ struct cff1
/* TODO */ /* TODO */
/* fill glyph names */ /* fill glyph names */
code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
{ {
hb_codepoint_t sid = glyph_to_sid (gid); hb_codepoint_t sid = glyph_to_sid (gid, &glyph_to_sid_cache);
gname_t gname; gname_t gname;
gname.sid = sid; gname.sid = sid;
if (sid < cff1_std_strings_length) if (sid < cff1_std_strings_length)

@ -413,6 +413,7 @@ struct cff_subset_plan {
supp_codes.init (); supp_codes.init ();
code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
subset_enc_num_codes = plan->num_output_glyphs () - 1; subset_enc_num_codes = plan->num_output_glyphs () - 1;
unsigned int glyph; unsigned int glyph;
auto it = hb_iter (plan->new_to_old_gid_list); auto it = hb_iter (plan->new_to_old_gid_list);
@ -431,7 +432,7 @@ struct cff_subset_plan {
/* Retain the SID for the old missing glyph ID */ /* Retain the SID for the old missing glyph ID */
old_glyph = glyph; old_glyph = glyph;
} }
code = acc.glyph_to_code (old_glyph); code = acc.glyph_to_code (old_glyph, &glyph_to_sid_cache);
if (code == CFF_UNDEF_CODE) if (code == CFF_UNDEF_CODE)
{ {
subset_enc_num_codes = glyph - 1; subset_enc_num_codes = glyph - 1;
@ -447,7 +448,7 @@ struct cff_subset_plan {
if (encoding != &Null (Encoding)) if (encoding != &Null (Encoding))
{ {
hb_codepoint_t sid = acc.glyph_to_sid (old_glyph); hb_codepoint_t sid = acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache);
encoding->get_supplement_codes (sid, supp_codes); encoding->get_supplement_codes (sid, supp_codes);
for (unsigned int i = 0; i < supp_codes.length; i++) for (unsigned int i = 0; i < supp_codes.length; i++)
{ {
@ -473,7 +474,7 @@ struct cff_subset_plan {
void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
{ {
unsigned int size0, size_ranges; unsigned int size0, size_ranges;
unsigned sid, last_sid = CFF_UNDEF_CODE - 1; unsigned last_sid = CFF_UNDEF_CODE - 1;
if (unlikely (!subset_charset_ranges.resize (0))) if (unlikely (!subset_charset_ranges.resize (0)))
{ {
@ -486,13 +487,14 @@ struct cff_subset_plan {
nullptr; nullptr;
bool created_map = false; bool created_map = false;
if (!glyph_to_sid_map && if (!glyph_to_sid_map &&
((plan->accelerator && plan->accelerator->cff_accelerator) || ((plan->accelerator && plan->accelerator->cff_accelerator)))
plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.))
{ {
created_map = true; created_map = true;
glyph_to_sid_map = acc.create_glyph_to_sid_map (); glyph_to_sid_map = acc.create_glyph_to_sid_map ();
} }
code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
unsigned int glyph; unsigned int glyph;
unsigned num_glyphs = plan->num_output_glyphs (); unsigned num_glyphs = plan->num_output_glyphs ();
auto it = hb_iter (plan->new_to_old_gid_list); auto it = hb_iter (plan->new_to_old_gid_list);
@ -512,7 +514,7 @@ struct cff_subset_plan {
/* Retain the SID for the old missing glyph ID */ /* Retain the SID for the old missing glyph ID */
old_glyph = glyph; old_glyph = glyph;
} }
sid = glyph_to_sid_map ? glyph_to_sid_map->arrayZ[old_glyph] : acc.glyph_to_sid (old_glyph); unsigned sid = glyph_to_sid_map ? glyph_to_sid_map->arrayZ[old_glyph] : acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache);
if (not_is_cid) if (not_is_cid)
sid = sidmap.add (sid); sid = sidmap.add (sid);

Loading…
Cancel
Save