From 33177bf65b21313763e5d10a6cd86c6d88365c3f Mon Sep 17 00:00:00 2001 From: ReadRoberts Date: Wed, 22 Feb 2017 21:22:34 -0800 Subject: [PATCH] If the design space file uses an element, use this to define the axis map, and preserve the axis order. --- Lib/fontTools/varLib/__init__.py | 23 ++++++++--------- Lib/fontTools/varLib/designspace.py | 29 ++++++++++++++++++++-- Lib/fontTools/varLib/interpolate_layout.py | 2 +- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/Lib/fontTools/varLib/__init__.py b/Lib/fontTools/varLib/__init__.py index d8d80c1e1..1a4df7d61 100644 --- a/Lib/fontTools/varLib/__init__.py +++ b/Lib/fontTools/varLib/__init__.py @@ -29,6 +29,7 @@ from fontTools.ttLib.tables._g_v_a_r import TupleVariation from fontTools.ttLib.tables import otTables as ot from fontTools.varLib import builder, designspace, models from fontTools.varLib.merger import VariationMerger +import collections import warnings import os.path import logging @@ -59,7 +60,9 @@ def _add_fvar(font, axes, instances, axis_map): font['fvar'] = fvar = newTable('fvar') nameTable = font['name'] - for iden in sorted(axes.keys(), key=lambda k: axis_map[k][0]): + for iden in axis_map.keys(): + if not axes.has_key(iden): + continue axis = Axis() axis.axisTag = Tag(axis_map[iden][0]) axis.minValue, axis.defaultValue, axis.maxValue = axes[iden] @@ -265,7 +268,7 @@ def build(designspace_filename, master_finder=lambda s:s, axisMap=None): (axis-tag, axis-name). """ - masters, instances = designspace.load(designspace_filename) + masters, instances, axisMapDS = designspace.load(designspace_filename) base_idx = None for i,m in enumerate(masters): if 'info' in m and m['info']['copy']: @@ -281,18 +284,14 @@ def build(designspace_filename, master_finder=lambda s:s, axisMap=None): master_ttfs = [master_finder(os.path.join(basedir, m['filename'])) for m in masters] master_fonts = [TTFont(ttf_path) for ttf_path in master_ttfs] - standard_axis_map = { - 'weight': ('wght', 'Weight'), - 'width': ('wdth', 'Width'), - 'slant': ('slnt', 'Slant'), - 'optical': ('opsz', 'Optical Size'), - 'custom': ('xxxx', 'Custom'), - } - - axis_map = standard_axis_map if axisMap: - axis_map = axis_map.copy() + axis_map = designspace.standard_axis_map.copy() axis_map.update(axisMap) + elif axisMapDS: + axis_map = axisMapDS + else: + axis_map = designspace.standard_axis_map + # TODO: For weight & width, use OS/2 values and setup 'avar' mapping. diff --git a/Lib/fontTools/varLib/designspace.py b/Lib/fontTools/varLib/designspace.py index 6489dd91b..ec6c0660d 100644 --- a/Lib/fontTools/varLib/designspace.py +++ b/Lib/fontTools/varLib/designspace.py @@ -1,5 +1,6 @@ """Rudimentary support for loading MutatorMath .designspace files.""" from __future__ import print_function, division, absolute_import +import collections from fontTools.misc.py23 import * try: import xml.etree.cElementTree as ET @@ -8,6 +9,14 @@ except ImportError: __all__ = ['load', 'loads'] +standard_axis_map = collections.OrderedDict( + [['weight', ('wght', 'Weight')], + ['width', ('wdth', 'Width')], + ['slant', ('slnt', 'Slant')], + ['optical', ('opsz', 'Optical Size')], + ['custom',('xxxx', 'Custom')]] + ) + def _xmlParseLocation(et): loc = {} for dim in et.find('location'): @@ -32,8 +41,24 @@ def _loadItem(et): return item def _load(et): - masters = [] ds = et.getroot() + + axisMap = collections.OrderedDict() + axesET = ds.find('axes') + if axesET: + axisList = axesET.findall('axis') + for axisET in axisList: + axisName = axisET.attrib["name"] + labelET = axisET.find('labelname') + if (None == labelET): + # If the designpsace file axes is a std axes, the label name may be omitted. + tag, label = standard_axis_map[axisName] + else: + label = labelET.text + tag = axisET.attrib["tag"] + axisMap[axisName] = (tag, label) + + masters = [] for et in ds.find('sources'): masters.append(_loadItem(et)) @@ -41,7 +66,7 @@ def _load(et): for et in ds.find('instances'): instances.append(_loadItem(et)) - return masters, instances + return masters, instances, axisMap def load(filename): """Load designspace from a file name or object. Returns two items: diff --git a/Lib/fontTools/varLib/interpolate_layout.py b/Lib/fontTools/varLib/interpolate_layout.py index cc5891cd1..5159365d0 100644 --- a/Lib/fontTools/varLib/interpolate_layout.py +++ b/Lib/fontTools/varLib/interpolate_layout.py @@ -12,7 +12,7 @@ import os.path def interpolate_layout(designspace_filename, loc, finder): - masters, instances = designspace.load(designspace_filename) + masters, instances, axisMap = designspace.load(designspace_filename) base_idx = None for i,m in enumerate(masters): if 'info' in m and m['info']['copy']: