Some legacy documents do not have an <axes> element. This causes problems reading and processing the file.
If there are no defined axes, use the available names from locations in the document. New axes are tagged with "_" as first letter. There is no guarantee that the guessed axes have the same dimensions as the originals.
This commit is contained in:
parent
22ce159ecd
commit
c31da9df47
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,3 +12,5 @@ Lib/designSpaceDocument/testPathName_case3.designspace
|
|||||||
Lib/designSpaceDocument/testPathName_case4.designspace
|
Lib/designSpaceDocument/testPathName_case4.designspace
|
||||||
Lib/designSpaceDocument/testPathName_case5.designspace
|
Lib/designSpaceDocument/testPathName_case5.designspace
|
||||||
Lib/designSpaceDocument/testPathNames.designspace
|
Lib/designSpaceDocument/testPathNames.designspace
|
||||||
|
testNoAxes_recontructed.designspace
|
||||||
|
testNoAxes_source.designspace
|
||||||
|
@ -565,8 +565,70 @@ class BaseDocReader(object):
|
|||||||
self.documentObject.axes.append(axisObject)
|
self.documentObject.axes.append(axisObject)
|
||||||
self.axisDefaults[axisObject.name] = axisObject.default
|
self.axisDefaults[axisObject.name] = axisObject.default
|
||||||
if not axes:
|
if not axes:
|
||||||
|
self.guessAxes()
|
||||||
self._strictAxisNames = False
|
self._strictAxisNames = False
|
||||||
|
|
||||||
|
def _locationFromElement(self, locationElement):
|
||||||
|
# mostly duplicated from readLocationElement, Needs Resolve.
|
||||||
|
loc = {}
|
||||||
|
for dimensionElement in locationElement.findall(".dimension"):
|
||||||
|
dimName = dimensionElement.attrib.get("name")
|
||||||
|
xValue = yValue = None
|
||||||
|
try:
|
||||||
|
xValue = dimensionElement.attrib.get('xvalue')
|
||||||
|
xValue = float(xValue)
|
||||||
|
except ValueError:
|
||||||
|
self.logger.info("KeyError in readLocation xValue %3.3f", xValue)
|
||||||
|
try:
|
||||||
|
yValue = dimensionElement.attrib.get('yvalue')
|
||||||
|
if yValue is not None:
|
||||||
|
yValue = float(yValue)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
if yValue is not None:
|
||||||
|
loc[dimName] = (xValue, yValue)
|
||||||
|
else:
|
||||||
|
loc[dimName] = xValue
|
||||||
|
return loc
|
||||||
|
|
||||||
|
def guessAxes(self):
|
||||||
|
# Called when we have no axes element in the file.
|
||||||
|
# Look at all locations and collect the axis names and values
|
||||||
|
# assumptions:
|
||||||
|
# look for the default value on an axis from a master location
|
||||||
|
allLocations = []
|
||||||
|
minima = {}
|
||||||
|
maxima = {}
|
||||||
|
for locationElement in self.root.findall(".sources/source/location"):
|
||||||
|
allLocations.append(self._locationFromElement(locationElement))
|
||||||
|
for locationElement in self.root.findall(".instances/instance/location"):
|
||||||
|
allLocations.append(self._locationFromElement(locationElement))
|
||||||
|
for loc in allLocations:
|
||||||
|
for dimName, value in loc.items():
|
||||||
|
if not isinstance(value, tuple):
|
||||||
|
value = [value]
|
||||||
|
for v in value:
|
||||||
|
if dimName not in minima:
|
||||||
|
minima[dimName] = v
|
||||||
|
continue
|
||||||
|
if minima[dimName] > v:
|
||||||
|
minima[dimName] = v
|
||||||
|
if dimName not in maxima:
|
||||||
|
maxima[dimName] = v
|
||||||
|
continue
|
||||||
|
if maxima[dimName] < v:
|
||||||
|
maxima[dimName] = v
|
||||||
|
newAxes = []
|
||||||
|
counter = 1
|
||||||
|
for axisName in maxima.keys():
|
||||||
|
a = self.axisDescriptorClass()
|
||||||
|
a.default = a.minimum = minima[axisName]
|
||||||
|
a.maximum = maxima[axisName]
|
||||||
|
a.name = axisName
|
||||||
|
a.tag = "_%03d"%(counter)
|
||||||
|
counter += 1
|
||||||
|
self.documentObject.axes.append(a)
|
||||||
|
|
||||||
def readSources(self):
|
def readSources(self):
|
||||||
for sourceElement in self.root.findall(".sources/source"):
|
for sourceElement in self.root.findall(".sources/source"):
|
||||||
filename = sourceElement.attrib.get('filename')
|
filename = sourceElement.attrib.get('filename')
|
||||||
@ -1283,6 +1345,7 @@ if __name__ == "__main__":
|
|||||||
... axes[axis.tag] = []
|
... axes[axis.tag] = []
|
||||||
... axes[axis.tag].append(axis.serialize())
|
... axes[axis.tag].append(axis.serialize())
|
||||||
>>> for axis in new.axes:
|
>>> for axis in new.axes:
|
||||||
|
... if axis.tag[0] == "_": continue
|
||||||
... if not axis.tag in axes:
|
... if not axis.tag in axes:
|
||||||
... axes[axis.tag] = []
|
... axes[axis.tag] = []
|
||||||
... axes[axis.tag].append(axis.serialize())
|
... axes[axis.tag].append(axis.serialize())
|
||||||
@ -1292,6 +1355,72 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def testHandleNoAxes():
|
||||||
|
# test what happens if the designspacedocument has no axes element.
|
||||||
|
"""
|
||||||
|
>>> import os
|
||||||
|
>>> testDocPath = os.path.join(os.getcwd(), "testNoAxes_source.designspace")
|
||||||
|
>>> testDocPath2 = os.path.join(os.getcwd(), "testNoAxes_recontructed.designspace")
|
||||||
|
>>> masterPath1 = os.path.join(os.getcwd(), "masters", "masterTest1.ufo")
|
||||||
|
>>> masterPath2 = os.path.join(os.getcwd(), "masters", "masterTest2.ufo")
|
||||||
|
>>> instancePath1 = os.path.join(os.getcwd(), "instances", "instanceTest1.ufo")
|
||||||
|
>>> instancePath2 = os.path.join(os.getcwd(), "instances", "instanceTest2.ufo")
|
||||||
|
|
||||||
|
# Case 1: No axes element in the document, but there are sources and instances
|
||||||
|
>>> doc = DesignSpaceDocument()
|
||||||
|
|
||||||
|
>>> for name, value in [('One', 1),('Two', 2),('Three', 3)]:
|
||||||
|
... a = AxisDescriptor()
|
||||||
|
... a.minimum = 0
|
||||||
|
... a.maximum = 1000
|
||||||
|
... a.default = 0
|
||||||
|
... a.name = "axisName%s"%(name)
|
||||||
|
... a.tag = "ax_%d"%(value)
|
||||||
|
... doc.addAxis(a)
|
||||||
|
|
||||||
|
>>> # add master 1
|
||||||
|
>>> s1 = SourceDescriptor()
|
||||||
|
>>> s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath))
|
||||||
|
>>> s1.name = "master.ufo1"
|
||||||
|
>>> s1.copyLib = True
|
||||||
|
>>> s1.copyInfo = True
|
||||||
|
>>> s1.copyFeatures = True
|
||||||
|
>>> s1.location = dict(axisNameOne=-1000, axisNameTwo=0, axisNameThree=1000)
|
||||||
|
>>> s1.familyName = "MasterFamilyName"
|
||||||
|
>>> s1.styleName = "MasterStyleNameOne"
|
||||||
|
>>> doc.addSource(s1)
|
||||||
|
|
||||||
|
>>> # add master 2
|
||||||
|
>>> s2 = SourceDescriptor()
|
||||||
|
>>> s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath))
|
||||||
|
>>> s2.name = "master.ufo1"
|
||||||
|
>>> s2.copyLib = False
|
||||||
|
>>> s2.copyInfo = False
|
||||||
|
>>> s2.copyFeatures = False
|
||||||
|
>>> s2.location = dict(axisNameOne=1000, axisNameTwo=1000, axisNameThree=0)
|
||||||
|
>>> s2.familyName = "MasterFamilyName"
|
||||||
|
>>> s2.styleName = "MasterStyleNameTwo"
|
||||||
|
>>> doc.addSource(s2)
|
||||||
|
|
||||||
|
>>> # add instance 1
|
||||||
|
>>> i1 = InstanceDescriptor()
|
||||||
|
>>> i1.filename = os.path.relpath(instancePath1, os.path.dirname(testDocPath))
|
||||||
|
>>> i1.familyName = "InstanceFamilyName"
|
||||||
|
>>> i1.styleName = "InstanceStyleName"
|
||||||
|
>>> i1.name = "instance.ufo1"
|
||||||
|
>>> i1.location = dict(axisNameOne=(-1000,500), axisNameTwo=100)
|
||||||
|
>>> i1.postScriptFontName = "InstancePostscriptName"
|
||||||
|
>>> i1.styleMapFamilyName = "InstanceStyleMapFamilyName"
|
||||||
|
>>> i1.styleMapStyleName = "InstanceStyleMapStyleName"
|
||||||
|
>>> doc.addInstance(i1)
|
||||||
|
|
||||||
|
>>> doc.write(testDocPath)
|
||||||
|
>>> __removeAxesFromDesignSpace(testDocPath)
|
||||||
|
>>> verify = DesignSpaceDocument()
|
||||||
|
>>> verify.read(testDocPath)
|
||||||
|
>>> verify.write(testDocPath2)
|
||||||
|
"""
|
||||||
|
|
||||||
def testPathNameResolve():
|
def testPathNameResolve():
|
||||||
# test how descriptor.path and descriptor.filename are resolved
|
# test how descriptor.path and descriptor.filename are resolved
|
||||||
"""
|
"""
|
||||||
@ -1631,11 +1760,11 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
>>> new = DesignSpaceDocument()
|
>>> new = DesignSpaceDocument()
|
||||||
>>> new.read(testDocPath)
|
>>> new.read(testDocPath)
|
||||||
>>> new.axes
|
>>> len(new.axes) # include 2 new guessed axes
|
||||||
[]
|
2
|
||||||
>>> new.checkAxes()
|
>>> new.checkAxes()
|
||||||
>>> len(new.axes)
|
>>> len(new.axes)
|
||||||
2
|
4
|
||||||
>>> new.write(testDocPath)
|
>>> new.write(testDocPath)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user