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
|
loaded[source.path] = source.font
|
||||||
fonts.append(source.font)
|
fonts.append(source.font)
|
||||||
return fonts
|
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
|
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.
|
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")
|
log.info("Loading master fonts")
|
||||||
master_fonts = load_masters(designspace, master_finder)
|
master_fonts = load_masters(designspace, master_finder)
|
||||||
|
|
||||||
# TODO: 'master_ttfs' is unused except for return value, remove later
|
try:
|
||||||
master_ttfs = []
|
# TODO: 'master_ttfs' is unused except for return value, remove later
|
||||||
for master in master_fonts:
|
master_ttfs = []
|
||||||
try:
|
for master in master_fonts:
|
||||||
master_ttfs.append(master.reader.file.name)
|
try:
|
||||||
except AttributeError:
|
master_ttfs.append(master.reader.file.name)
|
||||||
master_ttfs.append(None) # in-memory fonts have no path
|
except AttributeError:
|
||||||
|
master_ttfs.append(None) # in-memory fonts have no path
|
||||||
|
|
||||||
# Copy the base master to work from it
|
# Copy the base master to work from it
|
||||||
vf = deepcopy(master_fonts[ds.base_idx])
|
vf = deepcopy(master_fonts[ds.base_idx])
|
||||||
|
|
||||||
# TODO append masters as named-instances as well; needs .designspace change.
|
# TODO append masters as named-instances as well; needs .designspace change.
|
||||||
fvar = _add_fvar(vf, ds.axes, ds.instances)
|
fvar = _add_fvar(vf, ds.axes, ds.instances)
|
||||||
if 'STAT' not in exclude:
|
if 'STAT' not in exclude:
|
||||||
_add_stat(vf, ds.axes)
|
_add_stat(vf, ds.axes)
|
||||||
if 'avar' not in exclude:
|
if 'avar' not in exclude:
|
||||||
_add_avar(vf, ds.axes)
|
_add_avar(vf, ds.axes)
|
||||||
|
|
||||||
# Map from axis names to axis tags...
|
# Map from axis names to axis tags...
|
||||||
normalized_master_locs = [
|
normalized_master_locs = [
|
||||||
{ds.axes[k].tag: v for k,v in loc.items()} for loc in ds.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
|
# From here on, we use fvar axes only
|
||||||
axisTags = [axis.axisTag for axis in fvar.axes]
|
axisTags = [axis.axisTag for axis in fvar.axes]
|
||||||
|
|
||||||
# Assume single-model for now.
|
# Assume single-model for now.
|
||||||
model = models.VariationModel(normalized_master_locs, axisOrder=axisTags)
|
model = models.VariationModel(normalized_master_locs, axisOrder=axisTags)
|
||||||
assert 0 == model.mapping[ds.base_idx]
|
assert 0 == model.mapping[ds.base_idx]
|
||||||
|
|
||||||
log.info("Building variations tables")
|
log.info("Building variations tables")
|
||||||
if 'MVAR' not in exclude:
|
if 'MVAR' not in exclude:
|
||||||
_add_MVAR(vf, model, master_fonts, axisTags)
|
_add_MVAR(vf, model, master_fonts, axisTags)
|
||||||
if 'HVAR' not in exclude:
|
if 'HVAR' not in exclude:
|
||||||
_add_HVAR(vf, model, master_fonts, axisTags)
|
_add_HVAR(vf, model, master_fonts, axisTags)
|
||||||
if 'VVAR' not in exclude and 'vmtx' in vf:
|
if 'VVAR' not in exclude and 'vmtx' in vf:
|
||||||
_add_VVAR(vf, model, master_fonts, axisTags)
|
_add_VVAR(vf, model, master_fonts, axisTags)
|
||||||
if 'GDEF' not in exclude or 'GPOS' not in exclude:
|
if 'GDEF' not in exclude or 'GPOS' not in exclude:
|
||||||
_merge_OTL(vf, model, master_fonts, axisTags)
|
_merge_OTL(vf, model, master_fonts, axisTags)
|
||||||
if 'gvar' not in exclude and 'glyf' in vf:
|
if 'gvar' not in exclude and 'glyf' in vf:
|
||||||
_add_gvar(vf, model, master_fonts, optimize=optimize)
|
_add_gvar(vf, model, master_fonts, optimize=optimize)
|
||||||
if 'cvar' not in exclude and 'glyf' in vf:
|
if 'cvar' not in exclude and 'glyf' in vf:
|
||||||
_merge_TTHinting(vf, model, master_fonts)
|
_merge_TTHinting(vf, model, master_fonts)
|
||||||
if 'GSUB' not in exclude and ds.rules:
|
if 'GSUB' not in exclude and ds.rules:
|
||||||
_add_GSUB_feature_variations(vf, ds.axes, ds.internal_axis_supports, ds.rules, ds.rulesProcessingLast)
|
_add_GSUB_feature_variations(vf, ds.axes, ds.internal_axis_supports, ds.rules, ds.rulesProcessingLast)
|
||||||
if 'CFF2' not in exclude and 'CFF ' in vf:
|
if 'CFF2' not in exclude and 'CFF ' in vf:
|
||||||
_add_CFF2(vf, model, master_fonts)
|
_add_CFF2(vf, model, master_fonts)
|
||||||
if "post" in vf:
|
if "post" in vf:
|
||||||
# set 'post' to format 2 to keep the glyph names dropped from CFF2
|
# set 'post' to format 2 to keep the glyph names dropped from CFF2
|
||||||
post = vf["post"]
|
post = vf["post"]
|
||||||
if post.formatType != 2.0:
|
if post.formatType != 2.0:
|
||||||
post.formatType = 2.0
|
post.formatType = 2.0
|
||||||
post.extraNames = []
|
post.extraNames = []
|
||||||
post.mapping = {}
|
post.mapping = {}
|
||||||
|
finally:
|
||||||
|
if close_source_fonts:
|
||||||
|
for master in master_fonts:
|
||||||
|
master.close()
|
||||||
|
|
||||||
set_default_weight_width_slant(
|
set_default_weight_width_slant(
|
||||||
vf, location={axis.axisTag: axis.defaultValue for axis in vf["fvar"].axes}
|
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_'):
|
for path in self.get_file_list(ttx_dir, '.ttx', 'TestNonMarkingCFF2_'):
|
||||||
self.compile_font(path, ".otf", self.tempdir)
|
self.compile_font(path, ".otf", self.tempdir)
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
source.path = os.path.join(
|
source.path = os.path.join(
|
||||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||||
)
|
)
|
||||||
ds.updatePaths()
|
ds.updatePaths()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
|
|
||||||
tables = ["CFF2"]
|
tables = ["CFF2"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_build_CFF2(self):
|
def test_varlib_build_CFF2(self):
|
||||||
ds_path = self.get_test_input('TestCFF2.designspace')
|
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_'):
|
for path in self.get_file_list(ttx_dir, '.ttx', 'TestCFF2_'):
|
||||||
self.compile_font(path, ".otf", self.tempdir)
|
self.compile_font(path, ".otf", self.tempdir)
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
source.path = os.path.join(
|
source.path = os.path.join(
|
||||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||||
)
|
)
|
||||||
ds.updatePaths()
|
ds.updatePaths()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
|
|
||||||
tables = ["fvar", "CFF2"]
|
tables = ["fvar", "CFF2"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_build_sparse_CFF2(self):
|
def test_varlib_build_sparse_CFF2(self):
|
||||||
ds_path = self.get_test_input('TestSparseCFF2VF.designspace')
|
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-'):
|
for path in self.get_file_list(ttx_dir, '.ttx', 'MasterSet_Kanji-'):
|
||||||
self.compile_font(path, ".otf", self.tempdir)
|
self.compile_font(path, ".otf", self.tempdir)
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
source.path = os.path.join(
|
source.path = os.path.join(
|
||||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||||
)
|
)
|
||||||
ds.updatePaths()
|
ds.updatePaths()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
|
|
||||||
tables = ["fvar", "CFF2"]
|
tables = ["fvar", "CFF2"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_build_vpal(self):
|
def test_varlib_build_vpal(self):
|
||||||
ds_path = self.get_test_input('test_vpal.designspace')
|
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_'):
|
for path in self.get_file_list(ttx_dir, '.ttx', 'master_vpal_test_'):
|
||||||
self.compile_font(path, ".otf", self.tempdir)
|
self.compile_font(path, ".otf", self.tempdir)
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
source.path = os.path.join(
|
source.path = os.path.join(
|
||||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
|
||||||
)
|
)
|
||||||
ds.updatePaths()
|
ds.updatePaths()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
|
|
||||||
tables = ["GPOS"]
|
tables = ["GPOS"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_main_ttf(self):
|
def test_varlib_main_ttf(self):
|
||||||
"""Mostly for testing varLib.main()
|
"""Mostly for testing varLib.main()
|
||||||
@ -416,20 +416,20 @@ class BuildTest(unittest.TestCase):
|
|||||||
for path in self.get_file_list(ttx_dir, '.ttx', 'TestFamily-'):
|
for path in self.get_file_list(ttx_dir, '.ttx', 'TestFamily-'):
|
||||||
self.compile_font(path, ".ttf", self.tempdir)
|
self.compile_font(path, ".ttf", self.tempdir)
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
filename = os.path.join(
|
filename = os.path.join(
|
||||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
||||||
)
|
)
|
||||||
source.font = TTFont(
|
source.font = TTFont(
|
||||||
filename, recalcBBoxes=False, recalcTimestamp=False, lazy=True
|
filename, recalcBBoxes=False, recalcTimestamp=False, lazy=True
|
||||||
)
|
)
|
||||||
source.filename = None # Make sure no file path gets into build()
|
source.filename = None # Make sure no file path gets into build()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_build_from_ttf_paths(self):
|
def test_varlib_build_from_ttf_paths(self):
|
||||||
ds_path = self.get_test_input("Build.designspace")
|
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-'):
|
for path in self.get_file_list(ttx_dir, '.ttx', 'TestFamily-'):
|
||||||
self.compile_font(path, ".ttf", self.tempdir)
|
self.compile_font(path, ".ttf", self.tempdir)
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
source.path = os.path.join(
|
source.path = os.path.join(
|
||||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
self.tempdir, os.path.basename(source.filename).replace(".ufo", ".ttf")
|
||||||
)
|
)
|
||||||
ds.updatePaths()
|
ds.updatePaths()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_build_from_ttx_paths(self):
|
def test_varlib_build_from_ttx_paths(self):
|
||||||
ds_path = self.get_test_input("Build.designspace")
|
ds_path = self.get_test_input("Build.designspace")
|
||||||
ttx_dir = self.get_test_input("master_ttx_interpolatable_ttf")
|
ttx_dir = self.get_test_input("master_ttx_interpolatable_ttf")
|
||||||
expected_ttx_path = self.get_test_output("BuildMain.ttx")
|
expected_ttx_path = self.get_test_output("BuildMain.ttx")
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
source.path = os.path.join(
|
source.path = os.path.join(
|
||||||
ttx_dir, os.path.basename(source.filename).replace(".ufo", ".ttx")
|
ttx_dir, os.path.basename(source.filename).replace(".ufo", ".ttx")
|
||||||
)
|
)
|
||||||
ds.updatePaths()
|
ds.updatePaths()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
tables = [table_tag for table_tag in varfont.keys() if table_tag != "head"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_build_sparse_masters(self):
|
def test_varlib_build_sparse_masters(self):
|
||||||
ds_path = self.get_test_input("SparseMasters.designspace")
|
ds_path = self.get_test_input("SparseMasters.designspace")
|
||||||
@ -482,9 +482,10 @@ class BuildTest(unittest.TestCase):
|
|||||||
import fontTools.varLib.mvar
|
import fontTools.varLib.mvar
|
||||||
|
|
||||||
ds_path = self.get_test_input("SparseMasters.designspace")
|
ds_path = self.get_test_input("SparseMasters.designspace")
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
load_masters(ds)
|
master_fonts = load_masters(ds)
|
||||||
|
|
||||||
|
try:
|
||||||
# Trigger MVAR generation so varLib is forced to create deltas with a
|
# Trigger MVAR generation so varLib is forced to create deltas with a
|
||||||
# sparse master inbetween.
|
# sparse master inbetween.
|
||||||
font_0_os2 = ds.sources[0].font["OS/2"]
|
font_0_os2 = ds.sources[0].font["OS/2"]
|
||||||
@ -558,6 +559,9 @@ class BuildTest(unittest.TestCase):
|
|||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
mvar_tags = [vr.ValueTag for vr in varfont["MVAR"].table.ValueRecord]
|
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)
|
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):
|
def test_varlib_build_VVAR_CFF2(self):
|
||||||
ds_path = self.get_test_input('TestVVAR.designspace')
|
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'):
|
for path in self.get_file_list(ttx_dir, '.ttx', 'TestVVAR'):
|
||||||
font, savepath = self.compile_font(path, suffix, self.tempdir)
|
font, savepath = self.compile_font(path, suffix, self.tempdir)
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
source.path = os.path.join(
|
source.path = os.path.join(
|
||||||
self.tempdir, os.path.basename(source.filename).replace(".ufo", suffix)
|
self.tempdir, os.path.basename(source.filename).replace(".ufo", suffix)
|
||||||
)
|
)
|
||||||
ds.updatePaths()
|
ds.updatePaths()
|
||||||
|
|
||||||
varfont, _, _ = build(ds)
|
varfont, _, _ = build(ds)
|
||||||
varfont = reload_font(varfont)
|
varfont = reload_font(varfont)
|
||||||
|
|
||||||
expected_ttx_path = self.get_test_output(expected_ttx_name + '.ttx')
|
expected_ttx_path = self.get_test_output(expected_ttx_name + '.ttx')
|
||||||
tables = ["VVAR"]
|
tables = ["VVAR"]
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
self.check_ttx_dump(varfont, expected_ttx_path, tables, suffix)
|
self.check_ttx_dump(varfont, expected_ttx_path, tables, suffix)
|
||||||
|
|
||||||
def test_varlib_build_single_master(self):
|
def test_varlib_build_single_master(self):
|
||||||
self._run_varlib_build_test(
|
self._run_varlib_build_test(
|
||||||
@ -603,87 +607,87 @@ class BuildTest(unittest.TestCase):
|
|||||||
ds_path = self.get_test_input("KerningMerging.designspace")
|
ds_path = self.get_test_input("KerningMerging.designspace")
|
||||||
ttx_dir = self.get_test_input("master_kerning_merging")
|
ttx_dir = self.get_test_input("master_kerning_merging")
|
||||||
|
|
||||||
with DesignSpaceDocument.fromfile(ds_path) as ds:
|
ds = DesignSpaceDocument.fromfile(ds_path)
|
||||||
for source in ds.sources:
|
for source in ds.sources:
|
||||||
ttx_dump = TTFont()
|
ttx_dump = TTFont()
|
||||||
ttx_dump.importXML(
|
ttx_dump.importXML(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
ttx_dir, os.path.basename(source.filename).replace(".ttf", ".ttx")
|
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) == {
|
source.font = reload_font(ttx_dump)
|
||||||
("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})
|
varfont, _, _ = build(ds)
|
||||||
instance_black_kerning_table = (
|
varfont = reload_font(varfont)
|
||||||
instance_black["GPOS"].table.LookupList.Lookup[0].SubTable[0]
|
|
||||||
)
|
class_kerning_tables = [
|
||||||
assert _extract_flat_kerning(instance_black, instance_black_kerning_table) == {
|
t
|
||||||
("A", ".notdef"): 0,
|
for l in varfont["GPOS"].table.LookupList.Lookup
|
||||||
("A", "A"): 0,
|
for t in l.SubTable
|
||||||
("A", "B"): 0,
|
if t.Format == 2
|
||||||
("A", "C"): 0,
|
]
|
||||||
("A", "D"): 40,
|
assert len(class_kerning_tables) == 1
|
||||||
("B", ".notdef"): 0,
|
class_kerning_table = class_kerning_tables[0]
|
||||||
("B", "A"): 0,
|
|
||||||
("B", "B"): 0,
|
# Test that no class kerned against class zero (containing all glyphs not
|
||||||
("B", "C"): 0,
|
# classed) has a `XAdvDevice` table attached, which in the variable font
|
||||||
("B", "D"): 40,
|
# 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():
|
def test_load_masters_layerName_without_required_font():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user