Merge pull request #1441 from anthrotype/varlib-load-ttx
[varLib] allow loading masters from TTX files as well
This commit is contained in:
commit
7cbb2da4df
@ -811,14 +811,36 @@ def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
|
|||||||
return vf, model, master_ttfs
|
return vf, model, master_ttfs
|
||||||
|
|
||||||
|
|
||||||
|
def _open_font(path, master_finder):
|
||||||
|
# load TTFont masters from given 'path': this can be either a .TTX or an
|
||||||
|
# OpenType binary font; or if neither of these, try use the 'master_finder'
|
||||||
|
# callable to resolve the path to a valid .TTX or OpenType font binary.
|
||||||
|
from fontTools.ttx import guessFileType
|
||||||
|
|
||||||
|
master_path = os.path.normpath(path)
|
||||||
|
tp = guessFileType(master_path)
|
||||||
|
if tp is None:
|
||||||
|
# not an OpenType binary/ttx, fall back to the master finder.
|
||||||
|
master_path = master_finder(master_path)
|
||||||
|
tp = guessFileType(master_path)
|
||||||
|
if tp in ("TTX", "OTX"):
|
||||||
|
font = TTFont()
|
||||||
|
font.importXML(master_path)
|
||||||
|
elif tp in ("TTF", "OTF", "WOFF", "WOFF2"):
|
||||||
|
font = TTFont(master_path)
|
||||||
|
else:
|
||||||
|
raise VarLibError("Invalid master path: %r" % master_path)
|
||||||
|
return font
|
||||||
|
|
||||||
|
|
||||||
def load_masters(designspace, master_finder=lambda s: s):
|
def load_masters(designspace, master_finder=lambda s: s):
|
||||||
"""Ensure that all SourceDescriptor.font attributes have an appropriate TTFont
|
"""Ensure that all SourceDescriptor.font attributes have an appropriate TTFont
|
||||||
object loaded, or else open TTFont objects from the SourceDescriptor.path
|
object loaded, or else open TTFont objects from the SourceDescriptor.path
|
||||||
attributes.
|
attributes.
|
||||||
|
|
||||||
The paths can point to either an OpenType font or to a UFO. In the latter case,
|
The paths can point to either an OpenType font, a TTX file, or a UFO. In the
|
||||||
use the provided master_finder callable to map from UFO paths to the respective
|
latter case, use the provided master_finder callable to map from UFO paths to
|
||||||
master font binaries (e.g. .ttf or .otf).
|
the respective master font binaries (e.g. .ttf, .otf or .ttx).
|
||||||
|
|
||||||
Return list of master TTFont objects in the same order they are listed in the
|
Return list of master TTFont objects in the same order they are listed in the
|
||||||
DesignSpaceDocument.
|
DesignSpaceDocument.
|
||||||
@ -845,15 +867,10 @@ def load_masters(designspace, master_finder=lambda s: s):
|
|||||||
"Designspace source '%s' has neither 'font' nor 'path' "
|
"Designspace source '%s' has neither 'font' nor 'path' "
|
||||||
"attributes" % (master.name or "<Unknown>")
|
"attributes" % (master.name or "<Unknown>")
|
||||||
)
|
)
|
||||||
# 2. A SourceDescriptor's path might point to a UFO or an OpenType
|
# 2. A SourceDescriptor's path might point an OpenType binary, a
|
||||||
# binary. Find out the hard way.
|
# TTX file, or another source file (e.g. UFO), in which case we
|
||||||
master_path = os.path.normpath(master.path)
|
# resolve the path using 'master_finder' function
|
||||||
try:
|
font = _open_font(master.path, master_finder)
|
||||||
font = TTFont(master_path)
|
|
||||||
except (IOError, TTLibError):
|
|
||||||
# 3. Not an OpenType binary, fall back to the master finder.
|
|
||||||
master_path = master_finder(master_path)
|
|
||||||
font = TTFont(master_path)
|
|
||||||
master_fonts.append(font)
|
master_fonts.append(font)
|
||||||
|
|
||||||
return master_fonts
|
return master_fonts
|
||||||
|
@ -290,7 +290,7 @@ class BuildTest(unittest.TestCase):
|
|||||||
expected_ttx_path = self.get_test_output('BuildMain.ttx')
|
expected_ttx_path = self.get_test_output('BuildMain.ttx')
|
||||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||||
|
|
||||||
def test_varlib_build_from_ds_object(self):
|
def test_varlib_build_from_ds_object_in_memory_ttfonts(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")
|
||||||
@ -314,6 +314,44 @@ class BuildTest(unittest.TestCase):
|
|||||||
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):
|
||||||
|
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")
|
||||||
|
|
||||||
|
self.temp_dir()
|
||||||
|
for path in self.get_file_list(ttx_dir, '.ttx', 'TestFamily-'):
|
||||||
|
self.compile_font(path, ".ttf", self.tempdir)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
def test_load_masters_layerName_without_required_font():
|
def test_load_masters_layerName_without_required_font():
|
||||||
ds = DesignSpaceDocument()
|
ds = DesignSpaceDocument()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user