Make closure_glyphs() inplace
This commit is contained in:
parent
aeacc15839
commit
033dfcdf26
92
pyotlss.py
92
pyotlss.py
@ -100,7 +100,7 @@ def remap (self, class_map):
|
|||||||
def closure_glyphs (self, s, cur_glyphs=None):
|
def closure_glyphs (self, s, cur_glyphs=None):
|
||||||
if cur_glyphs == None: cur_glyphs = s.glyphs
|
if cur_glyphs == None: cur_glyphs = s.glyphs
|
||||||
if self.Format in [1, 2]:
|
if self.Format in [1, 2]:
|
||||||
return [v for g,v in self.mapping.items() if g in cur_glyphs]
|
s.glyphs.update (v for g,v in self.mapping.items() if g in cur_glyphs)
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ def closure_glyphs (self, s, cur_glyphs=None):
|
|||||||
if cur_glyphs == None: cur_glyphs = s.glyphs
|
if cur_glyphs == None: cur_glyphs = s.glyphs
|
||||||
if self.Format == 1:
|
if self.Format == 1:
|
||||||
indices = self.Coverage.intersect (cur_glyphs)
|
indices = self.Coverage.intersect (cur_glyphs)
|
||||||
return sum ((self.Sequence[i].Substitute for i in indices), [])
|
s.glyphs.update (*(self.Sequence[i].Substitute for i in indices))
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ def subset_glyphs (self, s):
|
|||||||
def closure_glyphs (self, s, cur_glyphs=None):
|
def closure_glyphs (self, s, cur_glyphs=None):
|
||||||
if cur_glyphs == None: cur_glyphs = s.glyphs
|
if cur_glyphs == None: cur_glyphs = s.glyphs
|
||||||
if self.Format == 1:
|
if self.Format == 1:
|
||||||
return sum ((vlist for g,vlist in self.alternates.items() if g in cur_glyphs), [])
|
s.glyphs.update (*(vlist for g,vlist in self.alternates.items() if g in cur_glyphs))
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
|
|
||||||
@ -157,8 +157,8 @@ def subset_glyphs (self, s):
|
|||||||
def closure_glyphs (self, s, cur_glyphs=None):
|
def closure_glyphs (self, s, cur_glyphs=None):
|
||||||
if cur_glyphs == None: cur_glyphs = s.glyphs
|
if cur_glyphs == None: cur_glyphs = s.glyphs
|
||||||
if self.Format == 1:
|
if self.Format == 1:
|
||||||
return sum (([seq.LigGlyph for seq in seqs if all(c in s.glyphs for c in seq.Component)]
|
s.glyphs.update (*([seq.LigGlyph for seq in seqs if all(c in s.glyphs for c in seq.Component)]
|
||||||
for g,seqs in self.ligatures.items() if g in cur_glyphs), [])
|
for g,seqs in self.ligatures.items() if g in cur_glyphs))
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
|
|
||||||
@ -182,8 +182,8 @@ def closure_glyphs (self, s, cur_glyphs=None):
|
|||||||
indices = self.Coverage.intersect (cur_glyphs)
|
indices = self.Coverage.intersect (cur_glyphs)
|
||||||
if not indices or \
|
if not indices or \
|
||||||
not all (c.intersect (s.glyphs) for c in self.LookAheadCoverage + self.BacktrackCoverage):
|
not all (c.intersect (s.glyphs) for c in self.LookAheadCoverage + self.BacktrackCoverage):
|
||||||
return []
|
return
|
||||||
return [self.Substitute[i] for i in indices]
|
s.glyphs.update (self.Substitute[i] for i in indices)
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
|
|
||||||
@ -451,7 +451,6 @@ def closure_glyphs (self, s, cur_glyphs=None):
|
|||||||
if self.Format == 1:
|
if self.Format == 1:
|
||||||
ContextData = c.ContextData (self)
|
ContextData = c.ContextData (self)
|
||||||
rss = getattr (self, c.RuleSet)
|
rss = getattr (self, c.RuleSet)
|
||||||
add = []
|
|
||||||
for i in indices:
|
for i in indices:
|
||||||
if not rss[i]: continue
|
if not rss[i]: continue
|
||||||
for r in getattr (rss[i], c.Rule):
|
for r in getattr (rss[i], c.Rule):
|
||||||
@ -471,14 +470,12 @@ def closure_glyphs (self, s, cur_glyphs=None):
|
|||||||
pos_glyphs = set (r.Input[seqi - 1])
|
pos_glyphs = set (r.Input[seqi - 1])
|
||||||
lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
|
lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
|
||||||
chaos = chaos or lookup.may_have_non_1to1 ()
|
chaos = chaos or lookup.may_have_non_1to1 ()
|
||||||
add.extend (lookup.closure_glyphs (s, cur_glyphs=pos_glyphs))
|
lookup.closure_glyphs (s, cur_glyphs=pos_glyphs)
|
||||||
return add
|
|
||||||
elif self.Format == 2:
|
elif self.Format == 2:
|
||||||
ClassDef = getattr (self, c.ClassDef)
|
ClassDef = getattr (self, c.ClassDef)
|
||||||
indices = ClassDef.intersect (cur_glyphs)
|
indices = ClassDef.intersect (cur_glyphs)
|
||||||
ContextData = c.ContextData (self)
|
ContextData = c.ContextData (self)
|
||||||
rss = getattr (self, c.RuleSet)
|
rss = getattr (self, c.RuleSet)
|
||||||
add = []
|
|
||||||
for i in indices:
|
for i in indices:
|
||||||
if not rss[i]: continue
|
if not rss[i]: continue
|
||||||
for r in getattr (rss[i], c.Rule):
|
for r in getattr (rss[i], c.Rule):
|
||||||
@ -498,13 +495,11 @@ def closure_glyphs (self, s, cur_glyphs=None):
|
|||||||
pos_glyphs = ClassDef.intersect_class (s.glyphs, r.Input[seqi - 1])
|
pos_glyphs = ClassDef.intersect_class (s.glyphs, r.Input[seqi - 1])
|
||||||
lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
|
lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
|
||||||
chaos = chaos or lookup.may_have_non_1to1 ()
|
chaos = chaos or lookup.may_have_non_1to1 ()
|
||||||
add.extend (lookup.closure_glyphs (s, cur_glyphs=pos_glyphs))
|
lookup.closure_glyphs (s, cur_glyphs=pos_glyphs)
|
||||||
return add
|
|
||||||
elif self.Format == 3:
|
elif self.Format == 3:
|
||||||
if not all (x.intersect (s.glyphs) for x in c.RuleData (self)):
|
if not all (x.intersect (s.glyphs) for x in c.RuleData (self)):
|
||||||
return []
|
return []
|
||||||
r = self
|
r = self
|
||||||
add = []
|
|
||||||
chaos = False
|
chaos = False
|
||||||
for ll in getattr (r, c.LookupRecord):
|
for ll in getattr (r, c.LookupRecord):
|
||||||
if not ll: continue
|
if not ll: continue
|
||||||
@ -518,8 +513,7 @@ def closure_glyphs (self, s, cur_glyphs=None):
|
|||||||
pos_glyphs = r.InputCoverage[seqi].intersect_glyphs (s.glyphs)
|
pos_glyphs = r.InputCoverage[seqi].intersect_glyphs (s.glyphs)
|
||||||
lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
|
lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
|
||||||
chaos = chaos or lookup.may_have_non_1to1 ()
|
chaos = chaos or lookup.may_have_non_1to1 ()
|
||||||
add.extend (lookup.closure_glyphs (s, cur_glyphs=pos_glyphs))
|
lookup.closure_glyphs (s, cur_glyphs=pos_glyphs)
|
||||||
return add
|
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
|
|
||||||
@ -619,7 +613,7 @@ def collect_lookups (self):
|
|||||||
@add_method(fontTools.ttLib.tables.otTables.ExtensionSubst)
|
@add_method(fontTools.ttLib.tables.otTables.ExtensionSubst)
|
||||||
def closure_glyphs (self, s, cur_glyphs=None):
|
def closure_glyphs (self, s, cur_glyphs=None):
|
||||||
if self.Format == 1:
|
if self.Format == 1:
|
||||||
return self.ExtSubTable.closure_glyphs (s, cur_glyphs)
|
self.ExtSubTable.closure_glyphs (s, cur_glyphs)
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
|
|
||||||
@ -653,7 +647,9 @@ def collect_lookups (self):
|
|||||||
|
|
||||||
@add_method(fontTools.ttLib.tables.otTables.Lookup)
|
@add_method(fontTools.ttLib.tables.otTables.Lookup)
|
||||||
def closure_glyphs (self, s, cur_glyphs=None):
|
def closure_glyphs (self, s, cur_glyphs=None):
|
||||||
return sum ((st.closure_glyphs (s, cur_glyphs) for st in self.SubTable if st), [])
|
for st in self.SubTable:
|
||||||
|
if not st: continue
|
||||||
|
st.closure_glyphs (s, cur_glyphs)
|
||||||
|
|
||||||
@add_method(fontTools.ttLib.tables.otTables.Lookup)
|
@add_method(fontTools.ttLib.tables.otTables.Lookup)
|
||||||
def subset_glyphs (self, s):
|
def subset_glyphs (self, s):
|
||||||
@ -778,17 +774,14 @@ def closure_glyphs (self, s):
|
|||||||
s.table = self.table
|
s.table = self.table
|
||||||
feature_indices = self.table.ScriptList.collect_features ()
|
feature_indices = self.table.ScriptList.collect_features ()
|
||||||
lookup_indices = self.table.FeatureList.collect_lookups (feature_indices)
|
lookup_indices = self.table.FeatureList.collect_lookups (feature_indices)
|
||||||
orig_glyphs = s.glyphs
|
|
||||||
glyphs = unique_sorted (s.glyphs)
|
|
||||||
while True:
|
while True:
|
||||||
s.glyphs = glyphs
|
orig_glyphs = s.glyphs.copy ()
|
||||||
additions = (sum ((self.table.LookupList.Lookup[i].closure_glyphs (s) \
|
for i in lookup_indices:
|
||||||
for i in lookup_indices if i < self.table.LookupList.LookupCount), []))
|
if i >= self.table.LookupList.LookupCount: continue
|
||||||
additions = unique_sorted (g for g in additions if g not in glyphs)
|
if not self.table.LookupList.Lookup[i]: continue
|
||||||
if not additions:
|
self.table.LookupList.Lookup[i].closure_glyphs (s)
|
||||||
s.glyphs = orig_glyphs
|
if orig_glyphs == s.glyphs:
|
||||||
return glyphs
|
break
|
||||||
glyphs.extend (additions)
|
|
||||||
del s.table
|
del s.table
|
||||||
|
|
||||||
@add_method(fontTools.ttLib.getTableClass('GSUB'), fontTools.ttLib.getTableClass('GPOS'))
|
@add_method(fontTools.ttLib.getTableClass('GSUB'), fontTools.ttLib.getTableClass('GPOS'))
|
||||||
@ -998,31 +991,30 @@ def dropInstructionsFast (self):
|
|||||||
|
|
||||||
@add_method(fontTools.ttLib.getTableClass('glyf'))
|
@add_method(fontTools.ttLib.getTableClass('glyf'))
|
||||||
def closure_glyphs (self, s):
|
def closure_glyphs (self, s):
|
||||||
glyphs = unique_sorted (s.glyphs)
|
decompose = s.glyphs
|
||||||
decompose = glyphs
|
|
||||||
# I don't know if component glyphs can be composite themselves.
|
# I don't know if component glyphs can be composite themselves.
|
||||||
# We handle them anyway.
|
# We handle them anyway.
|
||||||
while True:
|
while True:
|
||||||
components = []
|
components = set ()
|
||||||
for g in decompose:
|
for g in decompose:
|
||||||
if g not in self.glyphs:
|
if g not in self.glyphs:
|
||||||
continue
|
continue
|
||||||
gl = self.glyphs[g]
|
gl = self.glyphs[g]
|
||||||
if hasattr (gl, "data"):
|
if hasattr (gl, "data"):
|
||||||
for c in gl.getComponentNamesFast (self):
|
for c in gl.getComponentNamesFast (self):
|
||||||
if c not in glyphs:
|
if c not in s.glyphs:
|
||||||
components.append (c)
|
components.add (c)
|
||||||
else:
|
else:
|
||||||
# TTX seems to expand gid0..3 always
|
# TTX seems to expand gid0..3 always
|
||||||
if gl.isComposite ():
|
if gl.isComposite ():
|
||||||
for c in gl.components:
|
for c in gl.components:
|
||||||
if c.glyphName not in glyphs:
|
if c.glyphName not in s.glyphs:
|
||||||
components.append (c.glyphName)
|
components.add (c.glyphName)
|
||||||
components = [c for c in components if c not in glyphs]
|
components = set (c for c in components if c not in s.glyphs)
|
||||||
if not components:
|
if not components:
|
||||||
return glyphs
|
break
|
||||||
decompose = unique_sorted (components)
|
decompose = components
|
||||||
glyphs.extend (components)
|
s.glyphs.update (components)
|
||||||
|
|
||||||
@add_method(fontTools.ttLib.getTableClass('glyf'))
|
@add_method(fontTools.ttLib.getTableClass('glyf'))
|
||||||
def subset_glyphs (self, s):
|
def subset_glyphs (self, s):
|
||||||
@ -1054,17 +1046,15 @@ def subset_glyphs (self, s):
|
|||||||
@add_method(fontTools.ttLib.getTableClass('cmap'))
|
@add_method(fontTools.ttLib.getTableClass('cmap'))
|
||||||
def closure_glyphs (self, s):
|
def closure_glyphs (self, s):
|
||||||
tables = [t for t in self.tables if t.platformID == 3 and t.platEncID in [1, 10]]
|
tables = [t for t in self.tables if t.platformID == 3 and t.platEncID in [1, 10]]
|
||||||
extra = []
|
|
||||||
for u in s.unicodes_requested:
|
for u in s.unicodes_requested:
|
||||||
found = False
|
found = False
|
||||||
for table in tables:
|
for table in tables:
|
||||||
if u in table.cmap:
|
if u in table.cmap:
|
||||||
extra.append (table.cmap[u])
|
s.glyphs.add (table.cmap[u])
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
if not found:
|
if not found:
|
||||||
s.log ("No glyph for Unicode value %s; skipping." % u)
|
s.log ("No glyph for Unicode value %s; skipping." % u)
|
||||||
return extra
|
|
||||||
|
|
||||||
@add_method(fontTools.ttLib.getTableClass('cmap'))
|
@add_method(fontTools.ttLib.getTableClass('cmap'))
|
||||||
def prune_pre_subset (self, options):
|
def prune_pre_subset (self, options):
|
||||||
@ -1262,16 +1252,13 @@ class Subsetter:
|
|||||||
|
|
||||||
def closure_glyphs (self):
|
def closure_glyphs (self):
|
||||||
|
|
||||||
self.glyphs = self.glyphs_requested
|
self.glyphs = self.glyphs_requested.copy ()
|
||||||
|
|
||||||
if 'cmap' in self.font:
|
if 'cmap' in self.font:
|
||||||
extra_glyphs = self.font['cmap'].closure_glyphs (self)
|
self.font['cmap'].closure_glyphs (self)
|
||||||
self.glyph = self.glyphs.copy ()
|
|
||||||
self.glyphs.update (extra_glyphs)
|
|
||||||
self.glyphs_cmaped = self.glyphs
|
self.glyphs_cmaped = self.glyphs
|
||||||
|
|
||||||
if self.options.mandatory_glyphs:
|
if self.options.mandatory_glyphs:
|
||||||
self.glyphs = self.glyphs.copy ()
|
|
||||||
if 'glyf' in self.font:
|
if 'glyf' in self.font:
|
||||||
for i in range (4):
|
for i in range (4):
|
||||||
self.glyphs.add (self.font.getGlyphName (i))
|
self.glyphs.add (self.font.getGlyphName (i))
|
||||||
@ -1283,22 +1270,22 @@ class Subsetter:
|
|||||||
if 'GSUB' in self.font:
|
if 'GSUB' in self.font:
|
||||||
self.log ("Closing glyph list over 'GSUB': %d glyphs before" % len (self.glyphs))
|
self.log ("Closing glyph list over 'GSUB': %d glyphs before" % len (self.glyphs))
|
||||||
self.log.glyphs (self.glyphs, font=self.font)
|
self.log.glyphs (self.glyphs, font=self.font)
|
||||||
self.glyphs = set (self.font['GSUB'].closure_glyphs (self))
|
self.font['GSUB'].closure_glyphs (self)
|
||||||
self.log ("Closed glyph list over 'GSUB': %d glyphs after" % len (self.glyphs))
|
self.log ("Closed glyph list over 'GSUB': %d glyphs after" % len (self.glyphs))
|
||||||
self.log.glyphs (self.glyphs, font=self.font)
|
self.log.glyphs (self.glyphs, font=self.font)
|
||||||
self.log.lapse ("close glyph list over 'GSUB'")
|
self.log.lapse ("close glyph list over 'GSUB'")
|
||||||
self.glyphs_gsubed = self.glyphs
|
self.glyphs_gsubed = self.glyphs.copy ()
|
||||||
|
|
||||||
if 'glyf' in self.font:
|
if 'glyf' in self.font:
|
||||||
self.log ("Closing glyph list over 'glyf': %d glyphs before" % len (self.glyphs))
|
self.log ("Closing glyph list over 'glyf': %d glyphs before" % len (self.glyphs))
|
||||||
self.log.glyphs (self.glyphs, font=self.font)
|
self.log.glyphs (self.glyphs, font=self.font)
|
||||||
self.glyphs = set (self.font['glyf'].closure_glyphs (self))
|
self.font['glyf'].closure_glyphs (self)
|
||||||
self.log ("Closed glyph list over 'glyf': %d glyphs after" % len (self.glyphs))
|
self.log ("Closed glyph list over 'glyf': %d glyphs after" % len (self.glyphs))
|
||||||
self.log.glyphs (self.glyphs, font=self.font)
|
self.log.glyphs (self.glyphs, font=self.font)
|
||||||
self.log.lapse ("close glyph list over 'glyf'")
|
self.log.lapse ("close glyph list over 'glyf'")
|
||||||
self.glyphs_glyfed = self.glyphs
|
self.glyphs_glyfed = self.glyphs.copy ()
|
||||||
|
|
||||||
self.glyphs_all = self.glyphs
|
self.glyphs_all = self.glyphs.copy ()
|
||||||
|
|
||||||
self.log ("Retaining %d glyphs: " % len (self.glyphs_all))
|
self.log ("Retaining %d glyphs: " % len (self.glyphs_all))
|
||||||
|
|
||||||
@ -1313,6 +1300,7 @@ class Subsetter:
|
|||||||
table = self.font[tag]
|
table = self.font[tag]
|
||||||
self.glyphs = self.glyphs_all
|
self.glyphs = self.glyphs_all
|
||||||
retain = table.subset_glyphs (self)
|
retain = table.subset_glyphs (self)
|
||||||
|
self.glyphs = self.glyphs_all
|
||||||
self.log.lapse ("subset '%s'" % tag)
|
self.log.lapse ("subset '%s'" % tag)
|
||||||
if not retain:
|
if not retain:
|
||||||
self.log (tag, "subsetted to empty; dropped")
|
self.log (tag, "subsetted to empty; dropped")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user