undo DesignSpaceDocument context manager changes, and explicitly (but opt-out) close master_fonts within varLib.build()
This commit is contained in:
parent
703c2272bd
commit
49507a9de8
@ -1322,14 +1322,3 @@ class DesignSpaceDocument(LogMixin, AsDictMixin):
|
||||
loaded[source.path] = source.font
|
||||
fonts.append(source.font)
|
||||
return fonts
|
||||
|
||||
def closeSourceFonts(self):
|
||||
for source in self.sources:
|
||||
if source.font is not None and hasattr(source.font, "close"):
|
||||
source.font.close()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.closeSourceFonts()
|
||||
|
@ -821,7 +821,7 @@ def set_default_weight_width_slant(font, location):
|
||||
font["post"].italicAngle = italicAngle
|
||||
|
||||
|
||||
def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
|
||||
def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True, close_source_fonts=True):
|
||||
"""
|
||||
Build variation font from a designspace file.
|
||||
|
||||
@ -840,59 +840,64 @@ def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
|
||||
log.info("Loading master fonts")
|
||||
master_fonts = load_masters(designspace, master_finder)
|
||||
|
||||
# TODO: 'master_ttfs' is unused except for return value, remove later
|
||||
master_ttfs = []
|
||||
for master in master_fonts:
|
||||
try:
|
||||
master_ttfs.append(master.reader.file.name)
|
||||
except AttributeError:
|
||||
master_ttfs.append(None) # in-memory fonts have no path
|
||||
try:
|
||||
# TODO: 'master_ttfs' is unused except for return value, remove later
|
||||
master_ttfs = []
|
||||
for master in master_fonts:
|
||||
try:
|
||||
master_ttfs.append(master.reader.file.name)
|
||||
except AttributeError:
|
||||
master_ttfs.append(None) # in-memory fonts have no path
|
||||
|
||||
# Copy the base master to work from it
|
||||
vf = deepcopy(master_fonts[ds.base_idx])
|
||||
# Copy the base master to work from it
|
||||
vf = deepcopy(master_fonts[ds.base_idx])
|
||||
|
||||
# TODO append masters as named-instances as well; needs .designspace change.
|
||||
fvar = _add_fvar(vf, ds.axes, ds.instances)
|
||||
if 'STAT' not in exclude:
|
||||
_add_stat(vf, ds.axes)
|
||||
if 'avar' not in exclude:
|
||||
_add_avar(vf, ds.axes)
|
||||
# TODO append masters as named-instances as well; needs .designspace change.
|
||||
fvar = _add_fvar(vf, ds.axes, ds.instances)
|
||||
if 'STAT' not in exclude:
|
||||
_add_stat(vf, ds.axes)
|
||||
if 'avar' not in exclude:
|
||||
_add_avar(vf, ds.axes)
|
||||
|
||||
# Map from axis names to axis tags...
|
||||
normalized_master_locs = [
|
||||
{ds.axes[k].tag: v for k,v in loc.items()} for loc in ds.normalized_master_locs
|
||||
]
|
||||
# From here on, we use fvar axes only
|
||||
axisTags = [axis.axisTag for axis in fvar.axes]
|
||||
# Map from axis names to axis tags...
|
||||
normalized_master_locs = [
|
||||
{ds.axes[k].tag: v for k,v in loc.items()} for loc in ds.normalized_master_locs
|
||||
]
|
||||
# From here on, we use fvar axes only
|
||||
axisTags = [axis.axisTag for axis in fvar.axes]
|
||||
|
||||
# Assume single-model for now.
|
||||
model = models.VariationModel(normalized_master_locs, axisOrder=axisTags)
|
||||
assert 0 == model.mapping[ds.base_idx]
|
||||
# Assume single-model for now.
|
||||
model = models.VariationModel(normalized_master_locs, axisOrder=axisTags)
|
||||
assert 0 == model.mapping[ds.base_idx]
|
||||
|
||||
log.info("Building variations tables")
|
||||
if 'MVAR' not in exclude:
|
||||
_add_MVAR(vf, model, master_fonts, axisTags)
|
||||
if 'HVAR' not in exclude:
|
||||
_add_HVAR(vf, model, master_fonts, axisTags)
|
||||
if 'VVAR' not in exclude and 'vmtx' in vf:
|
||||
_add_VVAR(vf, model, master_fonts, axisTags)
|
||||
if 'GDEF' not in exclude or 'GPOS' not in exclude:
|
||||
_merge_OTL(vf, model, master_fonts, axisTags)
|
||||
if 'gvar' not in exclude and 'glyf' in vf:
|
||||
_add_gvar(vf, model, master_fonts, optimize=optimize)
|
||||
if 'cvar' not in exclude and 'glyf' in vf:
|
||||
_merge_TTHinting(vf, model, master_fonts)
|
||||
if 'GSUB' not in exclude and ds.rules:
|
||||
_add_GSUB_feature_variations(vf, ds.axes, ds.internal_axis_supports, ds.rules, ds.rulesProcessingLast)
|
||||
if 'CFF2' not in exclude and 'CFF ' in vf:
|
||||
_add_CFF2(vf, model, master_fonts)
|
||||
if "post" in vf:
|
||||
# set 'post' to format 2 to keep the glyph names dropped from CFF2
|
||||
post = vf["post"]
|
||||
if post.formatType != 2.0:
|
||||
post.formatType = 2.0
|
||||
post.extraNames = []
|
||||
post.mapping = {}
|
||||
log.info("Building variations tables")
|
||||
if 'MVAR' not in exclude:
|
||||
_add_MVAR(vf, model, master_fonts, axisTags)
|
||||
if 'HVAR' not in exclude:
|
||||
_add_HVAR(vf, model, master_fonts, axisTags)
|
||||
if 'VVAR' not in exclude and 'vmtx' in vf:
|
||||
_add_VVAR(vf, model, master_fonts, axisTags)
|
||||
if 'GDEF' not in exclude or 'GPOS' not in exclude:
|
||||
_merge_OTL(vf, model, master_fonts, axisTags)
|
||||
if 'gvar' not in exclude and 'glyf' in vf:
|
||||
_add_gvar(vf, model, master_fonts, optimize=optimize)
|
||||
if 'cvar' not in exclude and 'glyf' in vf:
|
||||
_merge_TTHinting(vf, model, master_fonts)
|
||||
if 'GSUB' not in exclude and ds.rules:
|
||||
_add_GSUB_feature_variations(vf, ds.axes, ds.internal_axis_supports, ds.rules, ds.rulesProcessingLast)
|
||||
if 'CFF2' not in exclude and 'CFF ' in vf:
|
||||
_add_CFF2(vf, model, master_fonts)
|
||||
if "post" in vf:
|
||||
# set 'post' to format 2 to keep the glyph names dropped from CFF2
|
||||
post = vf["post"]
|
||||
if post.formatType != 2.0:
|
||||
post.formatType = 2.0
|
||||
post.extraNames = []
|
||||
post.mapping = {}
|
||||
finally:
|
||||
if close_source_fonts:
|
||||
for master in master_fonts:
|
||||
master.close()
|
||||
|
||||
set_default_weight_width_slant(
|
||||
vf, location={axis.axisTag: axis.defaultValue for axis in vf["fvar"].axes}
|
||||
|
@ -282,18 +282,18 @@ class BuildTest(unittest.TestCase):
|
||||
for path in self.get_file_list(ttx_dir, '.ttx', 'TestNonMarkingCFF2_'):
|
||||
self.compile_font(path, ".otf", self.tempdir)
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
|
||||
tables = ["CFF2"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
tables = ["CFF2"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
|
||||
def test_varlib_build_CFF2(self):
|
||||
ds_path = self.get_test_input('TestCFF2.designspace')
|
||||
@ -304,18 +304,18 @@ class BuildTest(unittest.TestCase):
|
||||
for path in self.get_file_list(ttx_dir, '.ttx', 'TestCFF2_'):
|
||||
self.compile_font(path, ".otf", self.tempdir)
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
|
||||
tables = ["fvar", "CFF2"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
tables = ["fvar", "CFF2"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
|
||||
def test_varlib_build_sparse_CFF2(self):
|
||||
ds_path = self.get_test_input('TestSparseCFF2VF.designspace')
|
||||
@ -326,18 +326,18 @@ class BuildTest(unittest.TestCase):
|
||||
for path in self.get_file_list(ttx_dir, '.ttx', 'MasterSet_Kanji-'):
|
||||
self.compile_font(path, ".otf", self.tempdir)
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
|
||||
tables = ["fvar", "CFF2"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
tables = ["fvar", "CFF2"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
|
||||
def test_varlib_build_vpal(self):
|
||||
ds_path = self.get_test_input('test_vpal.designspace')
|
||||
@ -348,18 +348,18 @@ class BuildTest(unittest.TestCase):
|
||||
for path in self.get_file_list(ttx_dir, '.ttx', 'master_vpal_test_'):
|
||||
self.compile_font(path, ".otf", self.tempdir)
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
|
||||
tables = ["GPOS"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
tables = ["GPOS"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
|
||||
def test_varlib_main_ttf(self):
|
||||
"""Mostly for testing varLib.main()
|
||||
@ -416,20 +416,20 @@ class BuildTest(unittest.TestCase):
|
||||
for path in self.get_file_list(ttx_dir, '.ttx', 'TestFamily-'):
|
||||
self.compile_font(path, ".ttf", self.tempdir)
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
filename = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
||||
)
|
||||
source.font = TTFont(
|
||||
filename, recalcBBoxes=False, recalcTimestamp=False, lazy=True
|
||||
)
|
||||
source.filename = None # Make sure no file path gets into build()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
filename = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
||||
)
|
||||
source.font = TTFont(
|
||||
filename, recalcBBoxes=False, recalcTimestamp=False, lazy=True
|
||||
)
|
||||
source.filename = None # Make sure no file path gets into build()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
|
||||
def test_varlib_build_from_ttf_paths(self):
|
||||
ds_path = self.get_test_input("Build.designspace")
|
||||
@ -440,34 +440,34 @@ class BuildTest(unittest.TestCase):
|
||||
for path in self.get_file_list(ttx_dir, '.ttx', 'TestFamily-'):
|
||||
self.compile_font(path, ".ttf", self.tempdir)
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
||||
)
|
||||
ds.updatePaths()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
|
||||
def test_varlib_build_from_ttx_paths(self):
|
||||
ds_path = self.get_test_input("Build.designspace")
|
||||
ttx_dir = self.get_test_input("master_ttx_interpolatable_ttf")
|
||||
expected_ttx_path = self.get_test_output("BuildMain.ttx")
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
ttx_dir, os.path.basename(source.filename).replace(".ufo", ".ttx")
|
||||
)
|
||||
ds.updatePaths()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
ttx_dir, os.path.basename(source.filename).replace(".ufo", ".ttx")
|
||||
)
|
||||
ds.updatePaths()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
|
||||
def test_varlib_build_sparse_masters(self):
|
||||
ds_path = self.get_test_input("SparseMasters.designspace")
|
||||
@ -482,9 +482,10 @@ class BuildTest(unittest.TestCase):
|
||||
import fontTools.varLib.mvar
|
||||
|
||||
ds_path = self.get_test_input("SparseMasters.designspace")
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
load_masters(ds)
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
master_fonts = load_masters(ds)
|
||||
|
||||
try:
|
||||
# Trigger MVAR generation so varLib is forced to create deltas with a
|
||||
# sparse master inbetween.
|
||||
font_0_os2 = ds.sources[0].font["OS/2"]
|
||||
@ -558,6 +559,9 @@ class BuildTest(unittest.TestCase):
|
||||
varfont, _, _ = build(ds)
|
||||
mvar_tags = [vr.ValueTag for vr in varfont["MVAR"].table.ValueRecord]
|
||||
assert all(tag in mvar_tags for tag in fontTools.varLib.mvar.MVAR_ENTRIES)
|
||||
finally:
|
||||
for master in master_fonts:
|
||||
master.close()
|
||||
|
||||
def test_varlib_build_VVAR_CFF2(self):
|
||||
ds_path = self.get_test_input('TestVVAR.designspace')
|
||||
@ -569,20 +573,20 @@ class BuildTest(unittest.TestCase):
|
||||
for path in self.get_file_list(ttx_dir, '.ttx', 'TestVVAR'):
|
||||
font, savepath = self.compile_font(path, suffix, self.tempdir)
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", suffix)
|
||||
)
|
||||
ds.updatePaths()
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
source.path = os.path.join(
|
||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", suffix)
|
||||
)
|
||||
ds.updatePaths()
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
|
||||
expected_ttx_path = self.get_test_output(expected_ttx_name + '.ttx')
|
||||
tables = ["VVAR"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
self.check_ttx_dump(varfont, expected_ttx_path, tables, suffix)
|
||||
expected_ttx_path = self.get_test_output(expected_ttx_name + '.ttx')
|
||||
tables = ["VVAR"]
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
self.check_ttx_dump(varfont, expected_ttx_path, tables, suffix)
|
||||
|
||||
def test_varlib_build_single_master(self):
|
||||
self._run_varlib_build_test(
|
||||
@ -603,87 +607,87 @@ class BuildTest(unittest.TestCase):
|
||||
ds_path = self.get_test_input("KerningMerging.designspace")
|
||||
ttx_dir = self.get_test_input("master_kerning_merging")
|
||||
|
||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
||||
for source in ds.sources:
|
||||
ttx_dump = TTFont()
|
||||
ttx_dump.importXML(
|
||||
os.path.join(
|
||||
ttx_dir, os.path.basename(source.filename).replace(".ttf", ".ttx")
|
||||
)
|
||||
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||
for source in ds.sources:
|
||||
ttx_dump = TTFont()
|
||||
ttx_dump.importXML(
|
||||
os.path.join(
|
||||
ttx_dir, os.path.basename(source.filename).replace(".ttf", ".ttx")
|
||||
)
|
||||
source.font = reload_font(ttx_dump)
|
||||
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
|
||||
class_kerning_tables = [
|
||||
t
|
||||
for l in varfont["GPOS"].table.LookupList.Lookup
|
||||
for t in l.SubTable
|
||||
if t.Format == 2
|
||||
]
|
||||
assert len(class_kerning_tables) == 1
|
||||
class_kerning_table = class_kerning_tables[0]
|
||||
|
||||
# Test that no class kerned against class zero (containing all glyphs not
|
||||
# classed) has a `XAdvDevice` table attached, which in the variable font
|
||||
# context is a "VariationIndex" table and points to kerning deltas in the GDEF
|
||||
# table. Variation deltas of any kerning class against class zero should
|
||||
# probably never exist.
|
||||
for class1_record in class_kerning_table.Class1Record:
|
||||
class2_zero = class1_record.Class2Record[0]
|
||||
assert getattr(class2_zero.Value1, "XAdvDevice", None) is None
|
||||
|
||||
# Assert the variable font's kerning table (without deltas) is equal to the
|
||||
# default font's kerning table. The bug fixed in
|
||||
# https://github.com/fonttools/fonttools/pull/1638 caused rogue kerning
|
||||
# values to be written to the variable font.
|
||||
assert _extract_flat_kerning(varfont, class_kerning_table) == {
|
||||
("A", ".notdef"): 0,
|
||||
("A", "A"): 0,
|
||||
("A", "B"): -20,
|
||||
("A", "C"): 0,
|
||||
("A", "D"): -20,
|
||||
("B", ".notdef"): 0,
|
||||
("B", "A"): 0,
|
||||
("B", "B"): 0,
|
||||
("B", "C"): 0,
|
||||
("B", "D"): 0,
|
||||
}
|
||||
|
||||
instance_thin = instantiateVariableFont(varfont, {"wght": 100})
|
||||
instance_thin_kerning_table = (
|
||||
instance_thin["GPOS"].table.LookupList.Lookup[0].SubTable[0]
|
||||
)
|
||||
assert _extract_flat_kerning(instance_thin, instance_thin_kerning_table) == {
|
||||
("A", ".notdef"): 0,
|
||||
("A", "A"): 0,
|
||||
("A", "B"): 0,
|
||||
("A", "C"): 10,
|
||||
("A", "D"): 0,
|
||||
("B", ".notdef"): 0,
|
||||
("B", "A"): 0,
|
||||
("B", "B"): 0,
|
||||
("B", "C"): 10,
|
||||
("B", "D"): 0,
|
||||
}
|
||||
source.font = reload_font(ttx_dump)
|
||||
|
||||
instance_black = instantiateVariableFont(varfont, {"wght": 900})
|
||||
instance_black_kerning_table = (
|
||||
instance_black["GPOS"].table.LookupList.Lookup[0].SubTable[0]
|
||||
)
|
||||
assert _extract_flat_kerning(instance_black, instance_black_kerning_table) == {
|
||||
("A", ".notdef"): 0,
|
||||
("A", "A"): 0,
|
||||
("A", "B"): 0,
|
||||
("A", "C"): 0,
|
||||
("A", "D"): 40,
|
||||
("B", ".notdef"): 0,
|
||||
("B", "A"): 0,
|
||||
("B", "B"): 0,
|
||||
("B", "C"): 0,
|
||||
("B", "D"): 40,
|
||||
}
|
||||
varfont, _, _ = build(ds)
|
||||
varfont = reload_font(varfont)
|
||||
|
||||
class_kerning_tables = [
|
||||
t
|
||||
for l in varfont["GPOS"].table.LookupList.Lookup
|
||||
for t in l.SubTable
|
||||
if t.Format == 2
|
||||
]
|
||||
assert len(class_kerning_tables) == 1
|
||||
class_kerning_table = class_kerning_tables[0]
|
||||
|
||||
# Test that no class kerned against class zero (containing all glyphs not
|
||||
# classed) has a `XAdvDevice` table attached, which in the variable font
|
||||
# context is a "VariationIndex" table and points to kerning deltas in the GDEF
|
||||
# table. Variation deltas of any kerning class against class zero should
|
||||
# probably never exist.
|
||||
for class1_record in class_kerning_table.Class1Record:
|
||||
class2_zero = class1_record.Class2Record[0]
|
||||
assert getattr(class2_zero.Value1, "XAdvDevice", None) is None
|
||||
|
||||
# Assert the variable font's kerning table (without deltas) is equal to the
|
||||
# default font's kerning table. The bug fixed in
|
||||
# https://github.com/fonttools/fonttools/pull/1638 caused rogue kerning
|
||||
# values to be written to the variable font.
|
||||
assert _extract_flat_kerning(varfont, class_kerning_table) == {
|
||||
("A", ".notdef"): 0,
|
||||
("A", "A"): 0,
|
||||
("A", "B"): -20,
|
||||
("A", "C"): 0,
|
||||
("A", "D"): -20,
|
||||
("B", ".notdef"): 0,
|
||||
("B", "A"): 0,
|
||||
("B", "B"): 0,
|
||||
("B", "C"): 0,
|
||||
("B", "D"): 0,
|
||||
}
|
||||
|
||||
instance_thin = instantiateVariableFont(varfont, {"wght": 100})
|
||||
instance_thin_kerning_table = (
|
||||
instance_thin["GPOS"].table.LookupList.Lookup[0].SubTable[0]
|
||||
)
|
||||
assert _extract_flat_kerning(instance_thin, instance_thin_kerning_table) == {
|
||||
("A", ".notdef"): 0,
|
||||
("A", "A"): 0,
|
||||
("A", "B"): 0,
|
||||
("A", "C"): 10,
|
||||
("A", "D"): 0,
|
||||
("B", ".notdef"): 0,
|
||||
("B", "A"): 0,
|
||||
("B", "B"): 0,
|
||||
("B", "C"): 10,
|
||||
("B", "D"): 0,
|
||||
}
|
||||
|
||||
instance_black = instantiateVariableFont(varfont, {"wght": 900})
|
||||
instance_black_kerning_table = (
|
||||
instance_black["GPOS"].table.LookupList.Lookup[0].SubTable[0]
|
||||
)
|
||||
assert _extract_flat_kerning(instance_black, instance_black_kerning_table) == {
|
||||
("A", ".notdef"): 0,
|
||||
("A", "A"): 0,
|
||||
("A", "B"): 0,
|
||||
("A", "C"): 0,
|
||||
("A", "D"): 40,
|
||||
("B", ".notdef"): 0,
|
||||
("B", "A"): 0,
|
||||
("B", "B"): 0,
|
||||
("B", "C"): 0,
|
||||
("B", "D"): 40,
|
||||
}
|
||||
|
||||
|
||||
def test_load_masters_layerName_without_required_font():
|
||||
|
Loading…
x
Reference in New Issue
Block a user