Merge pull request #1447 from anthrotype/retain-gids-cff

[subset] set emptied CFF charstrings to 'endchar' with --retain-gids
This commit is contained in:
Cosimo Lupo 2019-01-16 16:51:57 +00:00 committed by GitHub
commit a3dd59d6ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 127 additions and 44 deletions

View File

@ -66,16 +66,13 @@ def closure_glyphs(self, s):
s.glyphs.update(components)
decompose = components
@_add_method(ttLib.getTableClass('CFF '))
def prune_pre_subset(self, font, options):
cff = self.cff
# CFF table must have one font only
cff.fontNames = cff.fontNames[:1]
if options.notdef_glyph and not options.notdef_outline:
for fontname in cff.keys():
font = cff[fontname]
c, fdSelectIndex = font.CharStrings.getItemAndSelector('.notdef')
def _empty_charstring(font, glyphName, isCFF2, ignoreWidth=False):
c, fdSelectIndex = font.CharStrings.getItemAndSelector(glyphName)
if isCFF2 or ignoreWidth:
# CFF2 charstrings have no widths nor 'endchar' operators
c.decompile()
c.program = [] if isCFF2 else ['endchar']
else:
if hasattr(font, 'FDArray') and font.FDArray is not None:
private = font.FDArray[fdSelectIndex].Private
else:
@ -89,6 +86,18 @@ def prune_pre_subset(self, font, options):
else:
c.program = ['endchar']
@_add_method(ttLib.getTableClass('CFF '))
def prune_pre_subset(self, font, options):
cff = self.cff
# CFF table must have one font only
cff.fontNames = cff.fontNames[:1]
if options.notdef_glyph and not options.notdef_outline:
isCFF2 = cff.major > 1
for fontname in cff.keys():
font = cff[fontname]
_empty_charstring(font, ".notdef", isCFF2=isCFF2)
# Clear useless Encoding
for fontname in cff.keys():
font = cff[fontname]
@ -104,6 +113,11 @@ def subset_glyphs(self, s):
font = cff[fontname]
cs = font.CharStrings
if s.options.retain_gids:
isCFF2 = cff.major > 1
for g in s.glyphs_emptied:
_empty_charstring(font, g, isCFF2=isCFF2, ignoreWidth=True)
else:
# Load all glyphs
for g in font.charset:
if g not in s.glyphs: continue

View File

@ -475,7 +475,7 @@ class SubsetTest(unittest.TestCase):
subset.main([fontpath, "--recalc-timestamp", "--output-file=%s" % subsetpath, "*"])
self.assertLess(modified, TTFont(subsetpath)['head'].modified)
def test_retain_gids(self):
def test_retain_gids_ttf(self):
_, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
font = TTFont(fontpath)
@ -507,6 +507,75 @@ class SubsetTest(unittest.TestCase):
self.assertGreater(glyf["A"].numberOfContours, 0)
self.assertEqual(glyf["B"].numberOfContours, 0)
def test_retain_gids_cff(self):
_, fontpath = self.compile_font(self.getpath("TestOTF-Regular.ttx"), ".otf")
font = TTFont(fontpath)
self.assertEqual(font["hmtx"]["A"], (500, 132))
self.assertEqual(font["hmtx"]["B"], (400, 132))
font["CFF "].cff[0].decompileAllCharStrings()
cs = font["CFF "].cff[0].CharStrings
self.assertGreater(len(cs["A"].program), 0)
self.assertGreater(len(cs["B"].program), 0)
subsetpath = self.temp_path(".otf")
subset.main(
[
fontpath,
"--retain-gids",
"--output-file=%s" % subsetpath,
"--glyph-names",
"A",
]
)
subsetfont = TTFont(subsetpath)
self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder())
hmtx = subsetfont["hmtx"]
self.assertEqual(hmtx["A"], (500, 132))
self.assertEqual(hmtx["B"], (0, 0))
subsetfont["CFF "].cff[0].decompileAllCharStrings()
cs = subsetfont["CFF "].cff[0].CharStrings
self.assertGreater(len(cs["A"].program), 0)
self.assertEqual(cs["B"].program, ["endchar"])
def test_retain_gids_cff2(self):
fontpath = self.getpath("../../varLib/data/TestCFF2VF.otf")
font = TTFont(fontpath)
self.assertEqual(font["hmtx"]["A"], (600, 31))
self.assertEqual(font["hmtx"]["T"], (600, 41))
font["CFF2"].cff[0].decompileAllCharStrings()
cs = font["CFF2"].cff[0].CharStrings
self.assertGreater(len(cs["A"].program), 0)
self.assertGreater(len(cs["T"].program), 0)
subsetpath = self.temp_path(".otf")
subset.main(
[
fontpath,
"--retain-gids",
"--output-file=%s" % subsetpath,
"A",
]
)
subsetfont = TTFont(subsetpath)
self.assertEqual(len(subsetfont.getGlyphOrder()), len(font.getGlyphOrder()))
hmtx = subsetfont["hmtx"]
self.assertEqual(hmtx["A"], (600, 31))
self.assertEqual(hmtx["glyph00002"], (0, 0))
subsetfont["CFF2"].cff[0].decompileAllCharStrings()
cs = subsetfont["CFF2"].cff[0].CharStrings
self.assertGreater(len(cs["A"].program), 0)
self.assertEqual(cs["glyph00002"].program, [])
if __name__ == "__main__":
sys.exit(unittest.main())