[subset/cff1] Collect glyph-to-sid map to avoid an O(n^2) algorithm
Saves 13 for largest benchmark: BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/10000 -0.1313 -0.1308 75 65 75 65 BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/4096 -0.1009 -0.1004 54 48 54 48 BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/10000 -0.1067 -0.1066 70 62 69 62
This commit is contained in:
parent
b87f48e948
commit
a4d98b63ea
|
@ -327,6 +327,12 @@ struct Charset0 {
|
|||
return sids[glyph - 1];
|
||||
}
|
||||
|
||||
void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
|
||||
{
|
||||
for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++)
|
||||
mapping->set (gid, sids[gid - 1]);
|
||||
}
|
||||
|
||||
hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
|
||||
{
|
||||
if (sid == 0)
|
||||
|
@ -390,13 +396,28 @@ struct Charset1_2 {
|
|||
for (unsigned int i = 0;; i++)
|
||||
{
|
||||
if (glyph <= ranges[i].nLeft)
|
||||
return (hb_codepoint_t)ranges[i].first + glyph;
|
||||
return (hb_codepoint_t) ranges[i].first + glyph;
|
||||
glyph -= (ranges[i].nLeft + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
|
||||
{
|
||||
hb_codepoint_t gid = 1;
|
||||
for (unsigned i = 0;; i++)
|
||||
{
|
||||
hb_codepoint_t sid = ranges[i].first;
|
||||
unsigned count = ranges[i].nLeft + 1;
|
||||
for (unsigned j = 0; j < count; j++)
|
||||
mapping->set (gid++, sid++);
|
||||
|
||||
if (gid >= num_glyphs)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
|
||||
{
|
||||
if (sid == 0) return 0;
|
||||
|
@ -532,6 +553,17 @@ struct Charset
|
|||
}
|
||||
}
|
||||
|
||||
void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case 0: u.format0.collect_glyph_to_sid_map (mapping, num_glyphs); return;
|
||||
case 1: u.format1.collect_glyph_to_sid_map (mapping, num_glyphs); return;
|
||||
case 2: u.format2.collect_glyph_to_sid_map (mapping, num_glyphs); return;
|
||||
default:return;
|
||||
}
|
||||
}
|
||||
|
||||
hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
|
||||
{
|
||||
switch (format)
|
||||
|
@ -1196,6 +1228,19 @@ struct cff1
|
|||
}
|
||||
}
|
||||
|
||||
hb_map_t *create_glyph_to_sid_map () const
|
||||
{
|
||||
if (charset != &Null (Charset))
|
||||
{
|
||||
hb_map_t *mapping = hb_map_create ();
|
||||
mapping->set (0, 0);
|
||||
charset->collect_glyph_to_sid_map (mapping, num_glyphs);
|
||||
return mapping;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (charset != &Null (Charset))
|
||||
|
|
|
@ -442,6 +442,9 @@ struct cff_subset_plan {
|
|||
return;
|
||||
}
|
||||
|
||||
bool use_glyph_to_sid_map = plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.;
|
||||
hb_map_t *glyph_to_sid_map = use_glyph_to_sid_map ? acc.create_glyph_to_sid_map () : nullptr;
|
||||
|
||||
unsigned int glyph;
|
||||
for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
|
||||
{
|
||||
|
@ -451,7 +454,7 @@ struct cff_subset_plan {
|
|||
/* Retain the SID for the old missing glyph ID */
|
||||
old_glyph = glyph;
|
||||
}
|
||||
sid = acc.glyph_to_sid (old_glyph);
|
||||
sid = glyph_to_sid_map ? glyph_to_sid_map->get (old_glyph) : acc.glyph_to_sid (old_glyph);
|
||||
|
||||
if (!acc.is_CID ())
|
||||
sid = sidmap.add (sid);
|
||||
|
@ -464,6 +467,9 @@ struct cff_subset_plan {
|
|||
last_sid = sid;
|
||||
}
|
||||
|
||||
if (glyph_to_sid_map)
|
||||
hb_map_destroy (glyph_to_sid_map);
|
||||
|
||||
bool two_byte = subset_charset_ranges.complete (glyph);
|
||||
|
||||
size0 = Charset0::min_size + HBUINT16::static_size * (plan->num_output_glyphs () - 1);
|
||||
|
|
Loading…
Reference in New Issue