[subset] Prune unused user name IDs even with --name-IDs='*'

This option should affect only pre-defined name IDs, user name IDs
should be pruned when nit used, as usual.

Fixes https://github.com/fonttools/fonttools/issues/3508
This commit is contained in:
Khaled Hosny 2024-05-17 18:06:34 +03:00 committed by خالد حسني (Khaled Hosny)
parent b2b771076c
commit dbe1264b34
2 changed files with 57 additions and 6 deletions

View File

@ -2913,8 +2913,9 @@ def prune_post_subset(self, font, options):
visitor = NameRecordVisitor()
visitor.visit(font)
nameIDs = set(options.name_IDs) | visitor.seen
if "*" not in options.name_IDs:
self.names = [n for n in self.names if n.nameID in nameIDs]
if "*" in options.name_IDs:
nameIDs |= {n.nameID for n in self.names if n.nameID < 256}
self.names = [n for n in self.names if n.nameID in nameIDs]
if not options.name_legacy:
# TODO(behdad) Sometimes (eg Apple Color Emoji) there's only a macroman
# entry for Latin and no Unicode names.

View File

@ -1915,10 +1915,6 @@ def test_subset_recalc_xAvgCharWidth(ttf_path):
assert xAvgCharWidth_after == subset_font["OS/2"].xAvgCharWidth
if __name__ == "__main__":
sys.exit(unittest.main())
def test_subset_prune_gdef_markglyphsetsdef():
# GDEF_MarkGlyphSetsDef
fb = FontBuilder(unitsPerEm=1000, isTTF=True)
@ -2023,3 +2019,57 @@ def test_subset_prune_gdef_markglyphsetsdef():
assert lookups[1].MarkFilteringSet == None
marksets = font["GDEF"].table.MarkGlyphSetsDef.Coverage
assert marksets[0].glyphs == ["acutecomb"]
def test_prune_user_name_IDs_with_keep_all(ttf_path):
font = TTFont(ttf_path)
keepNameIDs = {n.nameID for n in font["name"].names}
for i in range(10):
font["name"].addName(f"Test{i}")
options = subset.Options()
options.name_IDs = ["*"]
options.name_legacy = True
options.name_languages = ["*"]
subsetter = subset.Subsetter(options)
subsetter.populate(unicodes=font.getBestCmap().keys())
subsetter.subset(font)
nameIDs = {n.nameID for n in font["name"].names}
assert not any(n > 255 for n in nameIDs)
assert nameIDs == keepNameIDs
def test_prune_unused_user_name_IDs_with_keep_all(ttf_path):
font = TTFont(ttf_path)
keepNameIDs = {n.nameID for n in font["name"].names}
for i in range(10):
font["name"].addName(f"Test{i}")
nameID = font["name"].addName("Test STAT")
keepNameIDs.add(nameID)
font["STAT"] = newTable("STAT")
font["STAT"].table = ot.STAT()
font["STAT"].table.ElidedFallbackNameID = nameID
options = subset.Options()
options.name_IDs = ["*"]
options.name_legacy = True
options.name_languages = ["*"]
subsetter = subset.Subsetter(options)
subsetter.populate(unicodes=font.getBestCmap().keys())
subsetter.subset(font)
nameIDs = {n.nameID for n in font["name"].names}
assert nameIDs == keepNameIDs
if __name__ == "__main__":
sys.exit(unittest.main())