aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/subset/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/subset/__init__.py')
-rw-r--r--Lib/fontTools/subset/__init__.py58
1 files changed, 40 insertions, 18 deletions
diff --git a/Lib/fontTools/subset/__init__.py b/Lib/fontTools/subset/__init__.py
index 2ed17cc9..9403fc15 100644
--- a/Lib/fontTools/subset/__init__.py
+++ b/Lib/fontTools/subset/__init__.py
@@ -123,6 +123,8 @@ Output options:
Glyph set expansion:
These options control how additional glyphs are added to the subset.
+ --retain-gids
+ Retain glyph indices; just empty glyphs not needed in-place.
--notdef-glyph
Add the '.notdef' glyph to the subset (ie, keep it). [default]
--no-notdef-glyph
@@ -1714,16 +1716,23 @@ def subset_glyphs(self, s):
@_add_method(ttLib.getTableClass('vmtx'))
def subset_glyphs(self, s):
self.metrics = _dict_subset(self.metrics, s.glyphs)
+ for g in s.glyphs_emptied:
+ self.metrics[g] = (0,0)
return bool(self.metrics)
@_add_method(ttLib.getTableClass('hmtx'))
def subset_glyphs(self, s):
self.metrics = _dict_subset(self.metrics, s.glyphs)
+ for g in s.glyphs_emptied:
+ self.metrics[g] = (0,0)
return True # Required table
@_add_method(ttLib.getTableClass('hdmx'))
def subset_glyphs(self, s):
self.hdmx = {sz:_dict_subset(l, s.glyphs) for sz,l in self.hdmx.items()}
+ for sz in self.hdmx:
+ for g in s.glyphs_emptied:
+ self.hdmx[sz][g] = 0
return bool(self.hdmx)
@_add_method(ttLib.getTableClass('ankr'))
@@ -1784,6 +1793,8 @@ def subset_glyphs(self, s):
def subset_glyphs(self, s):
table = self.table
+ # TODO Update for retain_gids
+
used = set()
if table.AdvWidthMap:
@@ -2010,7 +2021,7 @@ def subset_glyphs(self, s):
return True
@_add_method(ttLib.getTableModule('glyf').Glyph)
-def remapComponentsFast(self, indices):
+def remapComponentsFast(self, glyphidmap):
if not self.data or struct.unpack(">h", self.data[:2])[0] >= 0:
return # Not composite
data = array.array("B", self.data)
@@ -2020,7 +2031,7 @@ def remapComponentsFast(self, indices):
flags =(data[i] << 8) | data[i+1]
glyphID =(data[i+2] << 8) | data[i+3]
# Remap
- glyphID = indices.index(glyphID)
+ glyphID = glyphidmap[glyphID]
data[i+2] = glyphID >> 8
data[i+3] = glyphID & 0xFF
i += 4
@@ -2063,13 +2074,17 @@ def prune_pre_subset(self, font, options):
@_add_method(ttLib.getTableClass('glyf'))
def subset_glyphs(self, s):
self.glyphs = _dict_subset(self.glyphs, s.glyphs)
- indices = [i for i,g in enumerate(self.glyphOrder) if g in s.glyphs]
- for v in self.glyphs.values():
- if hasattr(v, "data"):
- v.remapComponentsFast(indices)
- else:
- pass # No need
- self.glyphOrder = [g for g in self.glyphOrder if g in s.glyphs]
+ if not s.options.retain_gids:
+ indices = [i for i,g in enumerate(self.glyphOrder) if g in s.glyphs]
+ glyphmap = {o:n for n,o in enumerate(indices)}
+ for v in self.glyphs.values():
+ if hasattr(v, "data"):
+ v.remapComponentsFast(glyphmap)
+ Glyph = ttLib.getTableModule('glyf').Glyph
+ for g in s.glyphs_emptied:
+ self.glyphs[g] = Glyph()
+ self.glyphs[g].data = ''
+ self.glyphOrder = [g for g in self.glyphOrder if g in s.glyphs or g in s.glyphs_emptied]
# Don't drop empty 'glyf' tables, otherwise 'loca' doesn't get subset.
return True
@@ -2275,6 +2290,7 @@ class Options(object):
self.name_legacy = False
self.name_languages = [0x0409] # English
self.obfuscate_names = False # to make webfont unusable as a system font
+ self.retain_gids = False
self.notdef_glyph = True # gid0 for TrueType / .notdef for CFF
self.notdef_outline = False # No need for notdef to have an outline really
self.recommended_glyphs = False # gid1, gid2, gid3 for TrueType
@@ -2533,12 +2549,17 @@ class Subsetter(object):
log.glyphs(self.glyphs, font=font)
self.glyphs_cffed = frozenset(self.glyphs)
- self.glyphs_all = frozenset(self.glyphs)
+ self.glyphs_retained = frozenset(self.glyphs)
+
+ self.glyphs_emptied = frozenset()
+ if self.options.retain_gids:
+ self.glyphs_emptied = realGlyphs - self.glyphs_retained
+ # TODO Drop empty glyphs at the end of GlyphOrder vector.
order = font.getReverseGlyphMap()
- self.reverseOrigGlyphMap = {g:order[g] for g in self.glyphs_all}
+ self.reverseOrigGlyphMap = {g:order[g] for g in self.glyphs_retained}
- log.info("Retaining %d glyphs", len(self.glyphs_all))
+ log.info("Retaining %d glyphs", len(self.glyphs_retained))
del self.glyphs
@@ -2551,7 +2572,7 @@ class Subsetter(object):
elif hasattr(clazz, 'subset_glyphs'):
with timer("subset '%s'" % tag):
table = font[tag]
- self.glyphs = self.glyphs_all
+ self.glyphs = self.glyphs_retained
retain = table.subset_glyphs(self)
del self.glyphs
if not retain:
@@ -2565,11 +2586,12 @@ class Subsetter(object):
log.warning("%s NOT subset; don't know how to subset; dropped", tag)
del font[tag]
- with timer("subset GlyphOrder"):
- glyphOrder = font.getGlyphOrder()
- glyphOrder = [g for g in glyphOrder if g in self.glyphs_all]
- font.setGlyphOrder(glyphOrder)
- font._buildReverseGlyphOrderDict()
+ if not self.options.retain_gids:
+ with timer("subset GlyphOrder"):
+ glyphOrder = font.getGlyphOrder()
+ glyphOrder = [g for g in glyphOrder if g in self.glyphs_retained]
+ font.setGlyphOrder(glyphOrder)
+ font._buildReverseGlyphOrderDict()
def _prune_post_subset(self, font):
for tag in font.keys():