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.varLib.featureVars import addFeatureVariations
from fontTools.designspaceLib import DesignSpaceDocument, AxisDescriptor from fontTools.designspaceLib import DesignSpaceDocument, AxisDescriptor
from collections import OrderedDict, namedtuple from collections import OrderedDict, namedtuple
import io
import os.path import os.path
import logging import logging
from pprint import pformat from pprint import pformat
@ -647,9 +648,12 @@ def _add_CFF2(varFont, model, master_fonts):
merge_region_fonts(varFont, model, ordered_fonts_list, glyphOrder) 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 masters = ds.sources
if not masters: if not masters:
raise VarLibError("no sources found in .designspace") 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. Build variation font from a designspace file.
@ -740,12 +744,29 @@ def build(designspace_filename, master_finder=lambda s:s, exclude=[], optimize=T
binary as to be opened (eg. .ttf or .otf). 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("Building variable font")
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") log.info("Loading master fonts")
basedir = os.path.dirname(designspace_filename) basedir = os.path.dirname(designspace)
master_ttfs = [master_finder(os.path.join(basedir, m.filename)) for m in ds.masters] 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] master_fonts = [TTFont(ttf_path) for ttf_path in master_ttfs]
# Reload base font as target font # Reload base font as target font
vf = TTFont(master_ttfs[ds.base_idx]) vf = TTFont(master_ttfs[ds.base_idx])

View File

@ -3,7 +3,7 @@ from fontTools.misc.py23 import *
from fontTools.ttLib import TTFont from fontTools.ttLib import TTFont
from fontTools.varLib import build from fontTools.varLib import build
from fontTools.varLib import main as varLib_main from fontTools.varLib import main as varLib_main
from fontTools.designspaceLib import DesignSpaceDocumentError from fontTools.designspaceLib import DesignSpaceDocumentError, DesignSpaceDocument
import difflib import difflib
import os import os
import shutil import shutil
@ -285,6 +285,33 @@ 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):
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__": if __name__ == "__main__":
sys.exit(unittest.main()) sys.exit(unittest.main())