[subset] Close glyphs over CFF

Fixes https://github.com/fonttools/fonttools/issues/1162
This commit is contained in:
Behdad Esfahbod 2018-01-26 17:36:09 -08:00
parent 4fec016862
commit d723b695e7

View File

@ -1918,13 +1918,14 @@ def remapComponentsFast(self, indices):
@_add_method(ttLib.getTableClass('glyf'))
def closure_glyphs(self, s):
glyphSet = self.glyphs
decompose = s.glyphs
while decompose:
components = set()
for g in decompose:
if g not in self.glyphs:
if g not in glyphSet:
continue
gl = self.glyphs[g]
gl = glyphSet[g]
for c in gl.getComponentNames(self):
components.add(c)
components -= s.glyphs
@ -1960,6 +1961,49 @@ def prune_post_subset(self, options):
v.trim(remove_hinting=remove_hinting)
return True
class _ClosureGlyphsT2Decompiler(psCharStrings.SimpleT2Decompiler):
def __init__(self, components, localSubrs, globalSubrs):
psCharStrings.SimpleT2Decompiler.__init__(self,
localSubrs,
globalSubrs)
self.components = components
def op_endchar(self, index):
args = self.popall()
if len(args) >= 4:
from fontTools.encodings.StandardEncoding import StandardEncoding
# endchar can do seac accent bulding; The T2 spec says it's deprecated,
# but recent software that shall remain nameless does output it.
adx, ady, bchar, achar = args[-4:]
baseGlyph = StandardEncoding[bchar]
accentGlyph = StandardEncoding[achar]
self.components.add(baseGlyph)
self.components.add(accentGlyph)
@_add_method(ttLib.getTableClass('CFF '))
def closure_glyphs(self, s):
cff = self.cff
assert len(cff) == 1
font = cff[cff.keys()[0]]
glyphSet = font.CharStrings
decompose = s.glyphs
while decompose:
components = set()
for g in decompose:
if g not in glyphSet:
continue
gl = glyphSet[g]
subrs = getattr(gl.private, "Subrs", [])
decompiler = _ClosureGlyphsT2Decompiler(components, subrs, gl.globalSubrs)
decompiler.execute(gl)
components -= s.glyphs
s.glyphs.update(components)
decompose = components
@_add_method(ttLib.getTableClass('CFF '))
def prune_pre_subset(self, font, options):
cff = self.cff
@ -2860,6 +2904,18 @@ class Subsetter(object):
log.glyphs(self.glyphs, font=font)
self.glyphs_glyfed = frozenset(self.glyphs)
if 'CFF ' in font:
with timer("close glyph list over 'CFF '"):
log.info("Closing glyph list over 'CFF ': %d glyphs before",
len(self.glyphs))
log.glyphs(self.glyphs, font=font)
font['CFF '].closure_glyphs(self)
self.glyphs.intersection_update(realGlyphs)
log.info("Closed glyph list over 'CFF ': %d glyphs after",
len(self.glyphs))
log.glyphs(self.glyphs, font=font)
self.glyphs_cffed = frozenset(self.glyphs)
self.glyphs_all = frozenset(self.glyphs)
log.info("Retaining %d glyphs", len(self.glyphs_all))