Make build and load_designspace accept a DS object

This commit is contained in:
Nikolaus Waxweiler 2018-12-19 13:40:11 +00:00
parent 8e080f2a82
commit e464e450ac
2 changed files with 60 additions and 12 deletions

View File

@ -38,6 +38,7 @@ from fontTools.varLib.iup import iup_delta_optimize
from fontTools.varLib.featureVars import addFeatureVariations
from fontTools.designspaceLib import DesignSpaceDocument, AxisDescriptor
from collections import OrderedDict, namedtuple
import io
import os.path
import logging
from pprint import pformat
@ -647,9 +648,12 @@ def _add_CFF2(varFont, model, master_fonts):
merge_region_fonts(varFont, model, ordered_fonts_list, glyphOrder)
def load_designspace(designspace_filename):
def load_designspace(designspace):
if hasattr(designspace, "sources"): # Assume a DesignspaceDocument
ds = designspace
else: # Assume a file path
ds = DesignSpaceDocument.fromfile(designspace)
ds = DesignSpaceDocument.fromfile(designspace_filename)
masters = ds.sources
if not masters:
raise VarLibError("no sources found in .designspace")
@ -731,7 +735,7 @@ def load_designspace(designspace_filename):
)
def build(designspace_filename, master_finder=lambda s:s, exclude=[], optimize=True):
def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
"""
Build variation font from a designspace file.
@ -740,15 +744,32 @@ def build(designspace_filename, master_finder=lambda s:s, exclude=[], optimize=T
binary as to be opened (eg. .ttf or .otf).
"""
ds = load_designspace(designspace_filename)
ds = load_designspace(designspace)
log.info("Building variable font")
log.info("Loading master fonts")
basedir = os.path.dirname(designspace_filename)
master_ttfs = [master_finder(os.path.join(basedir, m.filename)) for m in ds.masters]
master_fonts = [TTFont(ttf_path) for ttf_path in master_ttfs]
# Reload base font as target font
vf = TTFont(master_ttfs[ds.base_idx])
if hasattr(designspace, "sources"): # Assume a DesignspaceDocument
for master in ds.masters:
if master.font is None:
raise AttributeError(
"designspace source '%s' is missing required 'font' attribute"
% getattr(master, "name", "<Unknown>")
)
master_fonts = [master.font for master in ds.masters]
master_ttfs = []
# Make a copy of the designated base font that we can then modify in-place.
buffer = io.BytesIO()
master_fonts[ds.base_idx].save(buffer)
buffer.seek(0)
vf = TTFont(buffer)
else: # Assume a file path
log.info("Loading master fonts")
basedir = os.path.dirname(designspace)
master_ttfs = [
master_finder(os.path.join(basedir, m.filename)) for m in ds.masters
]
master_fonts = [TTFont(ttf_path) for ttf_path in master_ttfs]
# Reload base font as target font
vf = TTFont(master_ttfs[ds.base_idx])
# TODO append masters as named-instances as well; needs .designspace change.
fvar = _add_fvar(vf, ds.axes, ds.instances)

View File

@ -3,7 +3,7 @@ from fontTools.misc.py23 import *
from fontTools.ttLib import TTFont
from fontTools.varLib import build
from fontTools.varLib import main as varLib_main
from fontTools.designspaceLib import DesignSpaceDocumentError
from fontTools.designspaceLib import DesignSpaceDocumentError, DesignSpaceDocument
import difflib
import os
import shutil
@ -285,6 +285,33 @@ class BuildTest(unittest.TestCase):
expected_ttx_path = self.get_test_output('BuildMain.ttx')
self.expect_ttx(varfont, expected_ttx_path, tables)
def test_varlib_build_from_ds_object(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")
def reload_font(font):
"""(De)serialize to get final binary layout."""
buf = BytesIO()
font.save(buf)
buf.seek(0)
return TTFont(buf)
ds = DesignSpaceDocument.fromfile(ds_path)
for source in ds.sources:
filename = os.path.join(
ttx_dir, os.path.basename(source.filename).replace(".ufo", ".ttx")
)
font = TTFont(recalcBBoxes=False, recalcTimestamp=False)
font.importXML(filename)
source.font = reload_font(font)
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)
if __name__ == "__main__":
sys.exit(unittest.main())