[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);
}
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 == 0)) return 0;
glyph--;
for (unsigned int i = 0;; i++)
hb_codepoint_t start_glyph = 1;
unsigned i = 0;
if (cache && likely (cache->glyph <= glyph))
{
if (glyph <= ranges[i].nLeft)
return (hb_codepoint_t) ranges[i].first + glyph;
glyph -= (ranges[i].nLeft + 1);
i = cache->code;
start_glyph = cache->glyph;
}
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;
@ -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)
{
case 0: return u.format0.get_sid (glyph, num_glyphs);
case 1: return u.format1.get_sid (glyph, num_glyphs);
case 2: return u.format2.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, cache);
default:return 0;
}
}
@ -1211,13 +1227,14 @@ struct cff1
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))
return encoding->get_code (glyph);
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;
hb_codepoint_t code = 0;
switch (topDict.EncodingOffset)
@ -1250,10 +1267,11 @@ struct cff1
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))
return charset->get_sid (glyph, num_glyphs);
return charset->get_sid (glyph, num_glyphs, cache);
else
{
hb_codepoint_t sid = 0;
@ -1396,9 +1414,10 @@ struct cff1
/* TODO */
/* fill glyph names */
code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
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.sid = sid;
if (sid < cff1_std_strings_length)

@ -413,6 +413,7 @@ struct cff_subset_plan {
supp_codes.init ();
code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
subset_enc_num_codes = plan->num_output_glyphs () - 1;
unsigned int glyph;
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 */
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)
{
subset_enc_num_codes = glyph - 1;
@ -447,7 +448,7 @@ struct cff_subset_plan {
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);
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)
{
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)))
{
@ -486,13 +487,14 @@ struct cff_subset_plan {
nullptr;
bool created_map = false;
if (!glyph_to_sid_map &&
((plan->accelerator && plan->accelerator->cff_accelerator) ||
plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.))
((plan->accelerator && plan->accelerator->cff_accelerator)))
{
created_map = true;
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 num_glyphs = plan->num_output_glyphs ();
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 */
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)
sid = sidmap.add (sid);

Loading…
Cancel
Save