Browse files

read/apply ufo2ft 'featureWriters' setup if found in the designspace lib

upcoming glyphsLib will store a custom 'featureWriters' key in the generated
designspace <lib> element, so fontmake needs to read that and pass the option on
to the ufo2ft compile functions.


Following discussions in googlei18n/ufo2ft#280, we decided
to revert the default mode for the ufo2ft kernFeatureWriter to skip (if feature already present).
  • Loading branch information...
anthrotype committed Oct 19, 2018
1 parent 16d1b59 commit 0772d2989f07053645237c90e89fd3fb0d466e60
Showing with 13 additions and 4 deletions.
  1. +13 −4 Lib/fontmake/
@@ -51,6 +51,7 @@ def fullmatch(regex, string, flags=0):
from fontTools.varLib.interpolate_layout import interpolate_layout
from ufo2ft import compileOTF, compileTTF, compileInterpolatableTTFs
from ufo2ft.featureCompiler import FeatureCompiler
from ufo2ft.featureWriters import loadFeatureWriters, FEATURE_WRITERS_KEY
from ufo2ft.util import makeOfficialGlyphOrder
from fontmake.errors import FontmakeError, TTFAError
@@ -563,6 +564,7 @@ def run_from_designspace(
self, designspace_path, interpolate=False,
interpolate_binary_layout=False, round_instances=False,
"""Run toolchain from a MutatorMath design space document.
@@ -597,6 +599,14 @@ def run_from_designspace(
from glyphsLib.interpolation import apply_instance_data
from mutatorMath.ufo.document import DesignSpaceDocumentReader
designspace = designspaceLib.DesignSpaceDocument.fromfile(designspace_path)
# if no --feature-writers option was passed, check in the designspace's
# <lib> element if user supplied a custom featureWriters configuration;
# if so, use that for all the UFOs built from this designspace
if feature_writers is None and FEATURE_WRITERS_KEY in designspace.lib:
feature_writers = loadFeatureWriters(designspace)
ufos = []
reader = DesignSpaceDocumentReader(designspace_path, ufoVersion=3,
@@ -606,7 +616,7 @@ def run_from_designspace(
if interpolate:'Interpolating master UFOs from designspace')
if isinstance(interpolate, basestring):
instances = self._search_instances(designspace_path,
instances = self._search_instances(designspace,
for instance_name in instances:
reader.readInstance(("name", instance_name))
@@ -632,6 +642,7 @@ def run_from_designspace(
is_instance=(interpolate or masters_as_instances),
def run_from_ufos(
@@ -707,9 +718,7 @@ def run_from_ufos(
def _search_instances(designspace_path, pattern):
designspace = designspaceLib.DesignSpaceDocument()
def _search_instances(designspace, pattern):
instances = OrderedDict()
for instance in designspace.instances:
# is 'name' optional? 'filename' certainly must not be

0 comments on commit 0772d29

Please sign in to comment.