Merge pull request #865 from fonttools/designspace-fixups

[varLib/designspace] fixups
This commit is contained in:
Cosimo Lupo 2017-02-27 18:11:42 +00:00 committed by GitHub
commit dc46296532
3 changed files with 59 additions and 43 deletions

View File

@ -37,6 +37,10 @@ from pprint import pformat
log = logging.getLogger("fontTools.varLib")
class VarLibError(Exception):
pass
#
# Creation routines
#
@ -265,9 +269,10 @@ def build(designspace_filename, master_finder=lambda s:s, axisMap=None):
"""
ds = designspace.load(designspace_filename)
axes = ds['axes']
masters = ds['masters']
instances = ds['instances']
axes = ds['axes'] if 'axes' in ds else []
if 'sources' not in ds or not ds['sources']:
raise VarLibError("no 'sources' defined in .designspace")
instances = ds['instances'] if 'instances' in ds else []
base_idx = None
for i,m in enumerate(masters):

View File

@ -1,6 +1,5 @@
"""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
@ -11,7 +10,8 @@ __all__ = ['load', 'loads']
namespaces = {'xml': '{http://www.w3.org/XML/1998/namespace}'}
def _xmlParseLocation(et):
def _xml_parse_location(et):
loc = {}
for dim in et.find('location'):
assert dim.tag == 'dimension'
@ -21,76 +21,87 @@ def _xmlParseLocation(et):
loc[name] = value
return loc
def _loadItem(et):
def _load_item(et):
item = dict(et.attrib)
for elt in et:
if elt.tag == 'location':
value = _xmlParseLocation(et)
for element in et:
if element.tag == 'location':
value = _xml_parse_location(et)
else:
value = {}
if 'copy' in elt.attrib:
value['copy'] = bool(int(elt.attrib['copy']))
if 'copy' in element.attrib:
value['copy'] = bool(int(element.attrib['copy']))
# TODO load more?!
item[elt.tag] = value
item[element.tag] = value
return item
def _xmlParseAxisOrMap(elt):
def _xml_parse_axis_or_map(element):
dic = {}
for name in elt.attrib:
for name in element.attrib:
if name in ['name', 'tag']:
dic[name] = elt.attrib[name]
dic[name] = element.attrib[name]
else:
dic[name] = float(elt.attrib[name])
dic[name] = float(element.attrib[name])
return dic
def _loadAxis(et):
item = dict(_xmlParseAxisOrMap(et))
def _load_axis(et):
item = _xml_parse_axis_or_map(et)
maps = []
labelnames = {}
for elt in et:
assert elt.tag in ['labelname', 'map']
if elt.tag == 'labelname':
lang = elt.attrib["{0}lang".format(namespaces['xml'])]
labelnames[lang] = elt.text
elif elt.tag == 'map':
maps.append(_xmlParseAxisOrMap(elt))
for element in et:
assert element.tag in ['labelname', 'map']
if element.tag == 'labelname':
lang = element.attrib["{0}lang".format(namespaces['xml'])]
labelnames[lang] = element.text
elif element.tag == 'map':
maps.append(_xml_parse_axis_or_map(element))
if labelnames:
item['labelname'] = labelnames
if maps:
item['map'] = maps
return item
def _load(et):
designspace = {}
ds = et.getroot()
axes = []
ds_axes = ds.find('axes')
if ds_axes:
for et in ds_axes:
axes.append(_loadAxis(et))
designspace['axes'] = axes
axes_element = ds.find('axes')
if axes_element is not None:
axes = []
for et in axes_element:
axes.append(_load_axis(et))
designspace['axes'] = axes
masters = []
for et in ds.find('sources'):
masters.append(_loadItem(et))
designspace['masters'] = masters
sources_element = ds.find('sources')
if sources_element is not None:
sources = []
for et in sources_element:
sources.append(_load_item(et))
designspace['sources'] = sources
instances = []
for et in ds.find('instances'):
instances.append(_loadItem(et))
designspace['instances'] = instances
instances_element = ds.find('instances')
if instances_element is not None:
instances = []
for et in instances_element:
instances.append(_load_item(et))
designspace['instances'] = instances
return designspace
def load(filename):
"""Load designspace from a file name or object.
Returns a dictionary containing three items:
- list of axes
- list of masters (aka sources)
- list of instances"""
- list of "axes"
- list of "sources" (aka masters)
- list of "instances"
"""
return _load(ET.parse(filename))
def loads(string):
"""Load designspace from a string."""
return _load(ET.fromstring(string))

View File

@ -18,7 +18,7 @@ class DesignspaceTest(unittest.TestCase):
'location': {'weight': 0.5},
'stylename': 'Medium'}],
'masters':
'sources':
[{'info': {'copy': True},
'name': 'master_1',
'lib': {'copy': True},