instancer: prune unused name records after instancing
This commit is contained in:
parent
0010a3cd9a
commit
5a530880c0
@ -21,6 +21,7 @@ from fontTools import varLib
|
|||||||
from fontTools.varLib import builder
|
from fontTools.varLib import builder
|
||||||
from fontTools.varLib.mvar import MVAR_ENTRIES
|
from fontTools.varLib.mvar import MVAR_ENTRIES
|
||||||
from fontTools.varLib.merger import MutatorMerger
|
from fontTools.varLib.merger import MutatorMerger
|
||||||
|
from contextlib import contextmanager
|
||||||
import collections
|
import collections
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
import logging
|
import logging
|
||||||
@ -540,6 +541,50 @@ def instantiateSTAT(varfont, location):
|
|||||||
stat.DesignAxisCount = len(stat.DesignAxisRecord.Axis)
|
stat.DesignAxisCount = len(stat.DesignAxisRecord.Axis)
|
||||||
|
|
||||||
|
|
||||||
|
def getVariationNameIDs(varfont):
|
||||||
|
used = []
|
||||||
|
if "fvar" in varfont:
|
||||||
|
fvar = varfont["fvar"]
|
||||||
|
for axis in fvar.axes:
|
||||||
|
used.append(axis.axisNameID)
|
||||||
|
for instance in fvar.instances:
|
||||||
|
used.append(instance.subfamilyNameID)
|
||||||
|
if instance.postscriptNameID != 0xFFFF:
|
||||||
|
used.append(instance.postscriptNameID)
|
||||||
|
if "STAT" in varfont:
|
||||||
|
stat = varfont["STAT"].table
|
||||||
|
for axis in stat.DesignAxisRecord.Axis if stat.DesignAxisRecord else ():
|
||||||
|
used.append(axis.AxisNameID)
|
||||||
|
for value in stat.AxisValueArray.AxisValue if stat.AxisValueArray else ():
|
||||||
|
used.append(value.ValueNameID)
|
||||||
|
# nameIDs <= 255 are reserved by OT spec so we don't touch them
|
||||||
|
return {nameID for nameID in used if nameID > 255}
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def pruningUnusedNames(varfont):
|
||||||
|
origNameIDs = getVariationNameIDs(varfont)
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
log.info("Pruning name table")
|
||||||
|
exclude = origNameIDs - getVariationNameIDs(varfont)
|
||||||
|
varfont["name"].names[:] = [
|
||||||
|
record for record in varfont["name"].names if record.nameID not in exclude
|
||||||
|
]
|
||||||
|
if "ltag" in varfont:
|
||||||
|
# Drop the whole 'ltag' table if all the language-dependent Unicode name
|
||||||
|
# records that reference it have been dropped.
|
||||||
|
# TODO: Only prune unused ltag tags, renumerating langIDs accordingly.
|
||||||
|
# Note ltag can also be used by feat or morx tables, so check those too.
|
||||||
|
if not any(
|
||||||
|
record
|
||||||
|
for record in varfont["name"].names
|
||||||
|
if record.platformID == 0 and record.langID != 0xFFFF
|
||||||
|
):
|
||||||
|
del varfont["ltag"]
|
||||||
|
|
||||||
|
|
||||||
def normalize(value, triple, avar_mapping):
|
def normalize(value, triple, avar_mapping):
|
||||||
value = normalizeValue(value, triple)
|
value = normalizeValue(value, triple)
|
||||||
if avar_mapping:
|
if avar_mapping:
|
||||||
@ -622,10 +667,11 @@ def instantiateVariableFont(varfont, axis_limits, inplace=False, optimize=True):
|
|||||||
if "avar" in varfont:
|
if "avar" in varfont:
|
||||||
instantiateAvar(varfont, normalized_limits)
|
instantiateAvar(varfont, normalized_limits)
|
||||||
|
|
||||||
if "STAT" in varfont:
|
with pruningUnusedNames(varfont):
|
||||||
instantiateSTAT(varfont, axis_limits)
|
if "STAT" in varfont:
|
||||||
|
instantiateSTAT(varfont, axis_limits)
|
||||||
|
|
||||||
instantiateFvar(varfont, axis_limits)
|
instantiateFvar(varfont, axis_limits)
|
||||||
|
|
||||||
return varfont
|
return varfont
|
||||||
|
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
<!-- Most of this table will be recalculated by the compiler -->
|
<!-- Most of this table will be recalculated by the compiler -->
|
||||||
<tableVersion value="1.0"/>
|
<tableVersion value="1.0"/>
|
||||||
<fontRevision value="2.001"/>
|
<fontRevision value="2.001"/>
|
||||||
<checkSumAdjustment value="0x710b1826"/>
|
<checkSumAdjustment value="0x7815682b"/>
|
||||||
<magicNumber value="0x5f0f3cf5"/>
|
<magicNumber value="0x5f0f3cf5"/>
|
||||||
<flags value="00000000 00000011"/>
|
<flags value="00000000 00000011"/>
|
||||||
<unitsPerEm value="1000"/>
|
<unitsPerEm value="1000"/>
|
||||||
<created value="Tue Mar 5 00:05:14 2019"/>
|
<created value="Tue Mar 5 00:05:14 2019"/>
|
||||||
<modified value="Fri May 3 10:34:01 2019"/>
|
<modified value="Wed May 8 10:35:06 2019"/>
|
||||||
<xMin value="40"/>
|
<xMin value="40"/>
|
||||||
<yMin value="-200"/>
|
<yMin value="-200"/>
|
||||||
<xMax value="450"/>
|
<xMax value="450"/>
|
||||||
@ -186,6 +186,9 @@
|
|||||||
</glyf>
|
</glyf>
|
||||||
|
|
||||||
<name>
|
<name>
|
||||||
|
<namerecord nameID="257" platformID="0" platEncID="4" langID="0x0">
|
||||||
|
Bräiti
|
||||||
|
</namerecord>
|
||||||
<namerecord nameID="256" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
<namerecord nameID="256" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||||
Weight
|
Weight
|
||||||
</namerecord>
|
</namerecord>
|
||||||
@ -306,6 +309,9 @@
|
|||||||
<namerecord nameID="295" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
<namerecord nameID="295" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||||
Upright
|
Upright
|
||||||
</namerecord>
|
</namerecord>
|
||||||
|
<namerecord nameID="296" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||||
|
TestVariableFont-XCdBd
|
||||||
|
</namerecord>
|
||||||
<namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
|
<namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
|
||||||
Copyright 2015 Google Inc. All Rights Reserved.
|
Copyright 2015 Google Inc. All Rights Reserved.
|
||||||
</namerecord>
|
</namerecord>
|
||||||
@ -462,6 +468,9 @@
|
|||||||
<namerecord nameID="295" platformID="3" platEncID="1" langID="0x409">
|
<namerecord nameID="295" platformID="3" platEncID="1" langID="0x409">
|
||||||
Upright
|
Upright
|
||||||
</namerecord>
|
</namerecord>
|
||||||
|
<namerecord nameID="296" platformID="3" platEncID="1" langID="0x409">
|
||||||
|
TestVariableFont-XCdBd
|
||||||
|
</namerecord>
|
||||||
</name>
|
</name>
|
||||||
|
|
||||||
<post>
|
<post>
|
||||||
@ -1008,7 +1017,8 @@
|
|||||||
</NamedInstance>
|
</NamedInstance>
|
||||||
|
|
||||||
<!-- ExtraCondensed ExtraBold -->
|
<!-- ExtraCondensed ExtraBold -->
|
||||||
<NamedInstance flags="0x0" subfamilyNameID="292">
|
<!-- PostScript: TestVariableFont-XCdBd -->
|
||||||
|
<NamedInstance flags="0x0" postscriptNameID="296" subfamilyNameID="292">
|
||||||
<coord axis="wght" value="800.0"/>
|
<coord axis="wght" value="800.0"/>
|
||||||
<coord axis="wdth" value="70.0"/>
|
<coord axis="wdth" value="70.0"/>
|
||||||
</NamedInstance>
|
</NamedInstance>
|
||||||
@ -1076,6 +1086,12 @@
|
|||||||
</glyphVariations>
|
</glyphVariations>
|
||||||
</gvar>
|
</gvar>
|
||||||
|
|
||||||
|
<ltag>
|
||||||
|
<version value="1"/>
|
||||||
|
<flags value="0"/>
|
||||||
|
<LanguageTag tag="gsw-LI"/>
|
||||||
|
</ltag>
|
||||||
|
|
||||||
<vmtx>
|
<vmtx>
|
||||||
<mtx name=".notdef" height="1000" tsb="100"/>
|
<mtx name=".notdef" height="1000" tsb="100"/>
|
||||||
<mtx name="hyphen" height="536" tsb="229"/>
|
<mtx name="hyphen" height="536" tsb="229"/>
|
||||||
|
@ -966,3 +966,27 @@ class InstantiateSTATTest(object):
|
|||||||
instancer.instantiateSTAT(varfont, {"wght": 100})
|
instancer.instantiateSTAT(varfont, {"wght": 100})
|
||||||
|
|
||||||
assert "STAT" not in varfont
|
assert "STAT" not in varfont
|
||||||
|
|
||||||
|
|
||||||
|
def test_pruningUnusedNames(varfont):
|
||||||
|
varNameIDs = instancer.getVariationNameIDs(varfont)
|
||||||
|
|
||||||
|
assert varNameIDs == set(range(256, 296 + 1))
|
||||||
|
|
||||||
|
fvar = varfont["fvar"]
|
||||||
|
stat = varfont["STAT"].table
|
||||||
|
|
||||||
|
with instancer.pruningUnusedNames(varfont):
|
||||||
|
del fvar.axes[0] # Weight (nameID=256)
|
||||||
|
del fvar.instances[0] # Thin (nameID=258)
|
||||||
|
del stat.DesignAxisRecord.Axis[0] # Weight (nameID=256)
|
||||||
|
del stat.AxisValueArray.AxisValue[0] # Thin (nameID=258)
|
||||||
|
|
||||||
|
assert not any(n for n in varfont["name"].names if n.nameID in {256, 258})
|
||||||
|
|
||||||
|
with instancer.pruningUnusedNames(varfont):
|
||||||
|
del varfont["fvar"]
|
||||||
|
del varfont["STAT"]
|
||||||
|
|
||||||
|
assert not any(n for n in varfont["name"].names if n.nameID in varNameIDs)
|
||||||
|
assert "ltag" not in varfont
|
||||||
|
Loading…
x
Reference in New Issue
Block a user