[subset] prune redundant cmap12 subtables.

If the post subset cmap12 table is equivalent to another cmap subtable don't include the 12 table in the final subset. Matches change https://github.com/fonttools/fonttools/pull/2146 from fontTools.
This commit is contained in:
Garret Rieger 2021-08-04 11:38:38 -07:00 committed by Behdad Esfahbod
parent 84946e4d2c
commit 2c024dc3cb
681 changed files with 162 additions and 44 deletions

View File

@ -49,6 +49,12 @@ struct CmapSubtableFormat0
*glyph = gid; *glyph = gid;
return true; return true;
} }
unsigned get_language () const
{
return language;
}
void collect_unicodes (hb_set_t *out) const void collect_unicodes (hb_set_t *out) const
{ {
for (unsigned int i = 0; i < 256; i++) for (unsigned int i = 0; i < 256; i++)
@ -287,6 +293,11 @@ struct CmapSubtableFormat4
: 0; : 0;
} }
unsigned get_language () const
{
return language;
}
struct accelerator_t struct accelerator_t
{ {
accelerator_t () {} accelerator_t () {}
@ -549,6 +560,12 @@ struct CmapSubtableTrimmed
*glyph = gid; *glyph = gid;
return true; return true;
} }
unsigned get_language () const
{
return language;
}
void collect_unicodes (hb_set_t *out) const void collect_unicodes (hb_set_t *out) const
{ {
hb_codepoint_t start = startCharCode; hb_codepoint_t start = startCharCode;
@ -608,6 +625,11 @@ struct CmapSubtableLongSegmented
return true; return true;
} }
unsigned get_language () const
{
return language;
}
void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const
{ {
for (unsigned int i = 0; i < this->groups.len; i++) for (unsigned int i = 0; i < this->groups.len; i++)
@ -1238,6 +1260,20 @@ struct CmapSubtable
} }
} }
unsigned get_language () const
{
switch (u.format) {
case 0: return u.format0 .get_language ();
case 4: return u.format4 .get_language ();
case 6: return u.format6 .get_language ();
case 10: return u.format10.get_language ();
case 12: return u.format12.get_language ();
case 13: return u.format13.get_language ();
case 14:
default: return 0;
}
}
template<typename Iterator, template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))> hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c, void serialize (hb_serialize_context_t *c,
@ -1373,7 +1409,11 @@ struct cmap
(base+_.subtable).collect_unicodes (&unicodes_set); (base+_.subtable).collect_unicodes (&unicodes_set);
if (format == 4) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 4u, base, plan, &format4objidx); if (format == 4) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 4u, base, plan, &format4objidx);
else if (format == 12) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 12u, base, plan, &format12objidx); else if (format == 12)
{
if (_can_drop (_, unicodes_set, base, + it | hb_map (hb_first), encodingrec_iter)) continue;
c->copy (_, + it | hb_filter (unicodes_set, hb_first), 12u, base, plan, &format12objidx);
}
else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx); else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx);
} }
@ -1382,6 +1422,60 @@ struct cmap
HB_SERIALIZE_ERROR_INT_OVERFLOW); HB_SERIALIZE_ERROR_INT_OVERFLOW);
} }
template<typename Iterator, typename EncodingRecordIterator,
hb_requires (hb_is_iterator (Iterator)),
hb_requires (hb_is_iterator (EncodingRecordIterator))>
bool _can_drop (const EncodingRecord& cmap12,
const hb_set_t& cmap12_unicodes,
const void* base,
Iterator subset_unicodes,
EncodingRecordIterator encoding_records)
{
for (auto cp : + subset_unicodes | hb_filter (cmap12_unicodes))
{
if (cp >= 0x10000) return false;
}
unsigned target_platform;
unsigned target_encoding;
unsigned target_language = (base+cmap12.subtable).get_language ();
if (cmap12.platformID == 0 && cmap12.encodingID == 4)
{
target_platform = 0;
target_encoding = 3;
} else if (cmap12.platformID == 3 && cmap12.encodingID == 10) {
target_platform = 3;
target_encoding = 1;
} else {
return false;
}
for (const auto& _ : encoding_records)
{
if (_.platformID != target_platform
|| _.encodingID != target_encoding
|| (base+_.subtable).get_language() != target_language)
continue;
hb_set_t sibling_unicodes;
(base+_.subtable).collect_unicodes (&sibling_unicodes);
auto cmap12 = + subset_unicodes | hb_filter (cmap12_unicodes);
auto sibling = + subset_unicodes | hb_filter (sibling_unicodes);
for (; cmap12 && sibling; cmap12++, sibling++)
{
unsigned a = *cmap12;
unsigned b = *sibling;
if (a != b) return false;
}
return !cmap12 && !sibling;
}
return false;
}
void closure_glyphs (const hb_set_t *unicodes, void closure_glyphs (const hb_set_t *unicodes,
hb_set_t *glyphset) const hb_set_t *glyphset) const
{ {

Binary file not shown.

View File

@ -38,14 +38,16 @@ EXTRA_DIST += \
expected/sbix \ expected/sbix \
expected/colr \ expected/colr \
expected/colr_with_components \ expected/colr_with_components \
expected/colrv1.notoemoji \
expected/colrv1 \
expected/cbdt \ expected/cbdt \
expected/variable \ expected/variable \
fonts \ fonts \
profiles \ profiles \
$(NULL) $(NULL)
# TODO: re-able once colrv1 subsetting is stabilized.
# expected/colrv1
# expected/colrv1.notoemoji
# Convenience targets: # Convenience targets:
lib: lib:
@$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src lib @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src lib

Some files were not shown because too many files have changed in this diff Show More