def test_unicodes(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "testUnicodes.designspace") testDocPath2 = os.path.join(tmpdir, "testUnicodes_roundtrip.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # add master 1 s1 = SourceDescriptor() s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath)) s1.name = "master.ufo1" s1.copyInfo = True s1.location = dict(weight=0) doc.addSource(s1) # add master 2 s2 = SourceDescriptor() s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s2.name = "master.ufo2" s2.location = dict(weight=1000) doc.addSource(s2) # add instance 1 i1 = InstanceDescriptor() i1.filename = os.path.relpath(instancePath1, os.path.dirname(testDocPath)) i1.name = "instance.ufo1" i1.location = dict(weight=500) glyphData = dict(name="arrow", mute=True, unicodes=[100, 200, 300]) i1.glyphs['arrow'] = glyphData doc.addInstance(i1) # now we have sources and instances, but no axes yet. doc.axes = [] # clear the axes # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 a1.name = "weight" a1.tag = "wght" doc.addAxis(a1) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) # import it again new = DesignSpaceDocument() new.read(testDocPath) new.write(testDocPath2) # compare the file contents f1 = open(testDocPath, 'r', encoding='utf-8') t1 = f1.read() f1.close() f2 = open(testDocPath2, 'r', encoding='utf-8') t2 = f2.read() f2.close() assert t1 == t2 # check the unicode values read from the document assert new.instances[0].glyphs['arrow']['unicodes'] == [100, 200, 300]
def test_unicodes(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "testUnicodes.designspace") testDocPath2 = os.path.join(tmpdir, "testUnicodes_roundtrip.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # add master 1 s1 = SourceDescriptor() s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath)) s1.name = "master.ufo1" s1.copyInfo = True s1.location = dict(weight=0) doc.addSource(s1) # add master 2 s2 = SourceDescriptor() s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s2.name = "master.ufo2" s2.location = dict(weight=1000) doc.addSource(s2) # add instance 1 i1 = InstanceDescriptor() i1.filename = os.path.relpath(instancePath1, os.path.dirname(testDocPath)) i1.name = "instance.ufo1" i1.location = dict(weight=500) glyphData = dict(name="arrow", mute=True, unicodes=[100, 200, 300]) i1.glyphs['arrow'] = glyphData doc.addInstance(i1) # now we have sources and instances, but no axes yet. doc.axes = [] # clear the axes # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 a1.name = "weight" a1.tag = "wght" doc.addAxis(a1) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) # import it again new = DesignSpaceDocument() new.read(testDocPath) new.write(testDocPath2) # compare the file contents with open(testDocPath, 'r', encoding='utf-8') as f1: t1 = f1.read() with open(testDocPath2, 'r', encoding='utf-8') as f2: t2 = f2.read() assert t1 == t2 # check the unicode values read from the document assert new.instances[0].glyphs['arrow']['unicodes'] == [100,200,300]
def test_updatePaths(tmpdir): doc = DesignSpaceDocument() doc.path = str(tmpdir / "foo" / "bar" / "MyDesignspace.designspace") s1 = SourceDescriptor() doc.addSource(s1) doc.updatePaths() # expect no changes assert s1.path is None assert s1.filename is None name1 = "../masters/Source1.ufo" path1 = posix(str(tmpdir / "foo" / "masters" / "Source1.ufo")) s1.path = path1 s1.filename = None doc.updatePaths() assert s1.path == path1 assert s1.filename == name1 # empty filename updated name2 = "../masters/Source2.ufo" s1.filename = name2 doc.updatePaths() # conflicting filename discarded, path always gets precedence assert s1.path == path1 assert s1.filename == "../masters/Source1.ufo" s1.path = None s1.filename = name2 doc.updatePaths() # expect no changes assert s1.path is None assert s1.filename == name2
def test_updatePaths(tmpdir): doc = DesignSpaceDocument() doc.path = str(tmpdir / "foo" / "bar" / "MyDesignspace.designspace") s1 = SourceDescriptor() doc.addSource(s1) doc.updatePaths() # expect no changes assert s1.path is None assert s1.filename is None name1 = "../masters/Source1.ufo" path1 = posix(str(tmpdir / "foo" / "masters" / "Source1.ufo")) s1.path = path1 s1.filename = None doc.updatePaths() assert s1.path == path1 assert s1.filename == name1 # empty filename updated name2 = "../masters/Source2.ufo" s1.filename = name2 doc.updatePaths() # conflicting filename discarded, path always gets precedence assert s1.path == path1 assert s1.filename == "../masters/Source1.ufo" s1.path = None s1.filename = name2 doc.updatePaths() # expect no changes assert s1.path is None assert s1.filename == name2
def getSpecialSources(font): sources = [] special_layer_axes = getSpecialLayerAxes(font) for i, special_layer_axis in enumerate(special_layer_axes): axes = list(special_layer_axis.values()) s = SourceDescriptor() s.location = special_layer_axis if is_vf: font_name = "%s %s -" % (font.familyName, getVariableFontFamily(font)) else: font_name = font.familyName for i, axis in enumerate(axes): font_name = "%s %s %s" % (font_name, axis, font.axes[i].name) s.filename = "%s.ufo" % font_name sources.append(s) return sources
def test_adjustAxisDefaultToNeutral(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "testAdjustAxisDefaultToNeutral.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # add master 1 s1 = SourceDescriptor() s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath)) s1.name = "master.ufo1" s1.copyInfo = True s1.copyFeatures = True s1.location = dict(weight=55, width=1000) doc.addSource(s1) # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 # the wrong value a1.name = "weight" a1.tag = "wght" doc.addAxis(a1) a2 = AxisDescriptor() a2.minimum = -10 a2.maximum = 10 a2.default = 0 # the wrong value a2.name = "width" a2.tag = "wdth" doc.addAxis(a2) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) # import it again new = DesignSpaceDocument() new.read(testDocPath) new.check() loc = new.default.location for axisObj in new.axes: n = axisObj.name assert axisObj.default == loc.get(n)
def getSources(font): sources = [] for i, master in enumerate(font.masters): s = SourceDescriptor() if is_vf: font_name = "%s %s - %s" % ( font.familyName, getVariableFontFamily(font), master.name) else: font_name = "%s - %s" % (font.familyName, master.name) s.filename = "%s.ufo" % font_name locations = dict() for x, axis in enumerate(master.axes): locations[font.axes[x].name] = axis s.location = locations origin_master_id = getOriginMaster(font) if master.id == origin_master_id: s.copyLib = True s.copyFeatures = True s.copyGroups = True s.copyInfo = True s.mutedGlyphNames = getMutedGlyphs(font) sources.append(s) return sources
def test_fill_document(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "test.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 a1.name = "weight" a1.tag = "wght" # note: just to test the element language, not an actual label name recommendations. a1.labelNames[u'fa-IR'] = u"قطر" a1.labelNames[u'en'] = u"Wéíght" doc.addAxis(a1) a2 = AxisDescriptor() a2.minimum = 0 a2.maximum = 1000 a2.default = 15 a2.name = "width" a2.tag = "wdth" a2.map = [(0.0, 10.0), (15.0, 20.0), (401.0, 66.0), (1000.0, 990.0)] a2.hidden = True a2.labelNames[u'fr'] = u"Chasse" doc.addAxis(a2) # add master 1 s1 = SourceDescriptor() s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath)) assert s1.font is None s1.name = "master.ufo1" s1.copyLib = True s1.copyInfo = True s1.copyFeatures = True s1.location = dict(weight=0) s1.familyName = "MasterFamilyName" s1.styleName = "MasterStyleNameOne" s1.mutedGlyphNames.append("A") s1.mutedGlyphNames.append("Z") doc.addSource(s1) # add master 2 s2 = SourceDescriptor() s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s2.name = "master.ufo2" s2.copyLib = False s2.copyInfo = False s2.copyFeatures = False s2.muteKerning = True s2.location = dict(weight=1000) s2.familyName = "MasterFamilyName" s2.styleName = "MasterStyleNameTwo" doc.addSource(s2) # add master 3 from a different layer s3 = SourceDescriptor() s3.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s3.name = "master.ufo2" s3.copyLib = False s3.copyInfo = False s3.copyFeatures = False s3.muteKerning = False s3.layerName = "supports" s3.location = dict(weight=1000) s3.familyName = "MasterFamilyName" s3.styleName = "Supports" doc.addSource(s3) # 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(weight=500, spooky=666) # this adds a dimension that is not defined. i1.postScriptFontName = "InstancePostscriptName" i1.styleMapFamilyName = "InstanceStyleMapFamilyName" i1.styleMapStyleName = "InstanceStyleMapStyleName" glyphData = dict(name="arrow", mute=True, unicodes=[0x123, 0x124, 0x125]) i1.glyphs['arrow'] = glyphData i1.lib['com.coolDesignspaceApp.binaryData'] = plistlib.Data(b'<binary gunk>') i1.lib['com.coolDesignspaceApp.specimenText'] = "Hamburgerwhatever" doc.addInstance(i1) # add instance 2 i2 = InstanceDescriptor() i2.filename = os.path.relpath(instancePath2, os.path.dirname(testDocPath)) i2.familyName = "InstanceFamilyName" i2.styleName = "InstanceStyleName" i2.name = "instance.ufo2" # anisotropic location i2.location = dict(weight=500, width=(400,300)) i2.postScriptFontName = "InstancePostscriptName" i2.styleMapFamilyName = "InstanceStyleMapFamilyName" i2.styleMapStyleName = "InstanceStyleMapStyleName" glyphMasters = [dict(font="master.ufo1", glyphName="BB", location=dict(width=20,weight=20)), dict(font="master.ufo2", glyphName="CC", location=dict(width=900,weight=900))] glyphData = dict(name="arrow", unicodes=[101, 201, 301]) glyphData['masters'] = glyphMasters glyphData['note'] = "A note about this glyph" glyphData['instanceLocation'] = dict(width=100, weight=120) i2.glyphs['arrow'] = glyphData i2.glyphs['arrow2'] = dict(mute=False) doc.addInstance(i2) doc.filename = "suggestedFileName.designspace" doc.lib['com.coolDesignspaceApp.previewSize'] = 30 # write some rules r1 = RuleDescriptor() r1.name = "named.rule.1" r1.conditionSets.append([ dict(name='axisName_a', minimum=0, maximum=1), dict(name='axisName_b', minimum=2, maximum=3) ]) r1.subs.append(("a", "a.alt")) doc.addRule(r1) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) assert_equals_test_file(testDocPath, 'data/test.designspace') # import it again new = DesignSpaceDocument() new.read(testDocPath) assert new.default.location == {'width': 20.0, 'weight': 0.0} assert new.filename == 'test.designspace' assert new.lib == doc.lib assert new.instances[0].lib == doc.instances[0].lib # test roundtrip for the axis attributes and data axes = {} for axis in doc.axes: if axis.tag not in axes: axes[axis.tag] = [] axes[axis.tag].append(axis.serialize()) for axis in new.axes: if axis.tag[0] == "_": continue if axis.tag not in axes: axes[axis.tag] = [] axes[axis.tag].append(axis.serialize()) for v in axes.values(): a, b = v assert a == b
def test_pathNameResolve(tmpdir): tmpdir = str(tmpdir) # test how descriptor.path and descriptor.filename are resolved testDocPath1 = os.path.join(tmpdir, "testPathName_case1.designspace") testDocPath2 = os.path.join(tmpdir, "testPathName_case2.designspace") testDocPath3 = os.path.join(tmpdir, "testPathName_case3.designspace") testDocPath4 = os.path.join(tmpdir, "testPathName_case4.designspace") testDocPath5 = os.path.join(tmpdir, "testPathName_case5.designspace") testDocPath6 = os.path.join(tmpdir, "testPathName_case6.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") a1 = AxisDescriptor() a1.tag = "TAGA" a1.name = "axisName_a" a1.minimum = 0 a1.maximum = 1000 a1.default = 0 # Case 1: filename and path are both empty. Nothing to calculate, nothing to put in the file. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = None s.path = None s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath1) verify = DesignSpaceDocument() verify.read(testDocPath1) assert verify.sources[0].filename == None assert verify.sources[0].path == None # Case 2: filename is empty, path points somewhere: calculate a new filename. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = None s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath2) verify = DesignSpaceDocument() verify.read(testDocPath2) assert verify.sources[0].filename == "masters/masterTest1.ufo" assert verify.sources[0].path == posix(masterPath1) # Case 3: the filename is set, the path is None. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = "../somewhere/over/the/rainbow.ufo" s.path = None s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath3) verify = DesignSpaceDocument() verify.read(testDocPath3) assert verify.sources[0].filename == "../somewhere/over/the/rainbow.ufo" # make the absolute path for filename so we can see if it matches the path p = os.path.abspath(os.path.join(os.path.dirname(testDocPath3), verify.sources[0].filename)) assert verify.sources[0].path == posix(p) # Case 4: the filename points to one file, the path points to another. The path takes precedence. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = "../somewhere/over/the/rainbow.ufo" s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath4) verify = DesignSpaceDocument() verify.read(testDocPath4) assert verify.sources[0].filename == "masters/masterTest1.ufo" # Case 5: the filename is None, path has a value, update the filename doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = None s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath5) # so that the document has a path doc.updateFilenameFromPath() assert doc.sources[0].filename == "masters/masterTest1.ufo" # Case 6: the filename has a value, path has a value, update the filenames with force doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = "../somewhere/over/the/rainbow.ufo" s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.write(testDocPath5) # so that the document has a path doc.addSource(s) assert doc.sources[0].filename == "../somewhere/over/the/rainbow.ufo" doc.updateFilenameFromPath(force=True) assert doc.sources[0].filename == "masters/masterTest1.ufo"
def test_handleNoAxes(tmpdir): tmpdir = str(tmpdir) # test what happens if the designspacedocument has no axes element. testDocPath = os.path.join(tmpdir, "testNoAxes_source.designspace") testDocPath2 = os.path.join(tmpdir, "testNoAxes_recontructed.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "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) verify = DesignSpaceDocument() verify.read(testDocPath) verify.write(testDocPath2)
def test_localisedNames(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "testLocalisedNames.designspace") testDocPath2 = os.path.join(tmpdir, "testLocalisedNames_roundtrip.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # add master 1 s1 = SourceDescriptor() s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath)) s1.name = "master.ufo1" s1.copyInfo = True s1.location = dict(weight=0) doc.addSource(s1) # add master 2 s2 = SourceDescriptor() s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s2.name = "master.ufo2" s2.location = dict(weight=1000) doc.addSource(s2) # add instance 1 i1 = InstanceDescriptor() i1.filename = os.path.relpath(instancePath1, os.path.dirname(testDocPath)) i1.familyName = "Montserrat" i1.styleName = "SemiBold" i1.styleMapFamilyName = "Montserrat SemiBold" i1.styleMapStyleName = "Regular" i1.setFamilyName("Montserrat", "fr") i1.setFamilyName(u"モンセラート", "ja") i1.setStyleName("Demigras", "fr") i1.setStyleName(u"半ば", "ja") i1.setStyleMapStyleName(u"Standard", "de") i1.setStyleMapFamilyName("Montserrat Halbfett", "de") i1.setStyleMapFamilyName(u"モンセラート SemiBold", "ja") i1.name = "instance.ufo1" i1.location = dict(weight=500, spooky=666) # this adds a dimension that is not defined. i1.postScriptFontName = "InstancePostscriptName" glyphData = dict(name="arrow", mute=True, unicodes=[0x123]) i1.glyphs['arrow'] = glyphData doc.addInstance(i1) # now we have sources and instances, but no axes yet. doc.axes = [] # clear the axes # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 a1.name = "weight" a1.tag = "wght" # note: just to test the element language, not an actual label name recommendations. a1.labelNames[u'fa-IR'] = u"قطر" a1.labelNames[u'en'] = u"Wéíght" doc.addAxis(a1) a2 = AxisDescriptor() a2.minimum = 0 a2.maximum = 1000 a2.default = 0 a2.name = "width" a2.tag = "wdth" a2.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)] a2.labelNames[u'fr'] = u"Poids" doc.addAxis(a2) # add an axis that is not part of any location to see if that works a3 = AxisDescriptor() a3.minimum = 333 a3.maximum = 666 a3.default = 444 a3.name = "spooky" a3.tag = "spok" a3.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)] #doc.addAxis(a3) # uncomment this line to test the effects of default axes values # write some rules r1 = RuleDescriptor() r1.name = "named.rule.1" r1.conditionSets.append([ dict(name='weight', minimum=200, maximum=500), dict(name='width', minimum=0, maximum=150) ]) r1.subs.append(("a", "a.alt")) doc.addRule(r1) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) # import it again new = DesignSpaceDocument() new.read(testDocPath) new.write(testDocPath2) with open(testDocPath, 'r', encoding='utf-8') as f1: t1 = f1.read() with open(testDocPath2, 'r', encoding='utf-8') as f2: t2 = f2.read() assert t1 == t2
def test_fill_document(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "test.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # 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(weight=0) s1.familyName = "MasterFamilyName" s1.styleName = "MasterStyleNameOne" s1.mutedGlyphNames.append("A") s1.mutedGlyphNames.append("Z") doc.addSource(s1) # add master 2 s2 = SourceDescriptor() s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s2.name = "master.ufo2" s2.copyLib = False s2.copyInfo = False s2.copyFeatures = False s2.muteKerning = True s2.location = dict(weight=1000) 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( weight=500, spooky=666) # this adds a dimension that is not defined. i1.postScriptFontName = "InstancePostscriptName" i1.styleMapFamilyName = "InstanceStyleMapFamilyName" i1.styleMapStyleName = "InstanceStyleMapStyleName" glyphData = dict(name="arrow", mute=True, unicodes=[0x123, 0x124, 0x125]) i1.glyphs['arrow'] = glyphData doc.addInstance(i1) # add instance 2 i2 = InstanceDescriptor() i2.filename = os.path.relpath(instancePath2, os.path.dirname(testDocPath)) i2.familyName = "InstanceFamilyName" i2.styleName = "InstanceStyleName" i2.name = "instance.ufo2" # anisotropic location i2.location = dict(weight=500, width=(400, 300)) i2.postScriptFontName = "InstancePostscriptName" i2.styleMapFamilyName = "InstanceStyleMapFamilyName" i2.styleMapStyleName = "InstanceStyleMapStyleName" glyphMasters = [ dict(font="master.ufo1", glyphName="BB", location=dict(width=20, weight=20)), dict(font="master.ufo2", glyphName="CC", location=dict(width=900, weight=900)) ] glyphData = dict(name="arrow", unicodes=[101, 201, 301]) glyphData['masters'] = glyphMasters glyphData['note'] = "A note about this glyph" glyphData['instanceLocation'] = dict(width=100, weight=120) i2.glyphs['arrow'] = glyphData i2.glyphs['arrow2'] = dict(mute=False) doc.addInstance(i2) # now we have sources and instances, but no axes yet. doc.check() # Here, since the axes are not defined in the document, but instead are # infered from the locations of the instances, we cannot guarantee the # order in which they will be created by the `check()` method. assert set(doc.getAxisOrder()) == set(['spooky', 'weight', 'width']) doc.axes = [] # clear the axes # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 a1.name = "weight" a1.tag = "wght" # note: just to test the element language, not an actual label name recommendations. a1.labelNames[u'fa-IR'] = u"قطر" a1.labelNames[u'en'] = u"Wéíght" doc.addAxis(a1) a2 = AxisDescriptor() a2.minimum = 0 a2.maximum = 1000 a2.default = 20 a2.name = "width" a2.tag = "wdth" a2.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)] a2.hidden = True a2.labelNames[u'fr'] = u"Poids" doc.addAxis(a2) # add an axis that is not part of any location to see if that works a3 = AxisDescriptor() a3.minimum = 333 a3.maximum = 666 a3.default = 444 a3.name = "spooky" a3.tag = "spok" a3.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)] #doc.addAxis(a3) # uncomment this line to test the effects of default axes values # write some rules r1 = RuleDescriptor() r1.name = "named.rule.1" r1.conditions.append(dict(name='aaaa', minimum=0, maximum=1)) r1.conditions.append(dict(name='bbbb', minimum=2, maximum=3)) r1.subs.append(("a", "a.alt")) doc.addRule(r1) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) # import it again new = DesignSpaceDocument() new.read(testDocPath) new.check() assert new.default.location == {'width': 20.0, 'weight': 0.0} # >>> for a, b in zip(doc.instances, new.instances): # ... a.compare(b) # >>> for a, b in zip(doc.sources, new.sources): # ... a.compare(b) # >>> for a, b in zip(doc.axes, new.axes): # ... a.compare(b) # >>> [n.mutedGlyphNames for n in new.sources] # [['A', 'Z'], []] # >>> doc.getFonts() # [] # test roundtrip for the axis attributes and data axes = {} for axis in doc.axes: if axis.tag not in axes: axes[axis.tag] = [] axes[axis.tag].append(axis.serialize()) for axis in new.axes: if axis.tag[0] == "_": continue if axis.tag not in axes: axes[axis.tag] = [] axes[axis.tag].append(axis.serialize()) for v in axes.values(): a, b = v assert a == b
def test_fill_document(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "test.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 a1.name = "weight" a1.tag = "wght" # note: just to test the element language, not an actual label name recommendations. a1.labelNames[u'fa-IR'] = u"قطر" a1.labelNames[u'en'] = u"Wéíght" doc.addAxis(a1) a2 = AxisDescriptor() a2.minimum = 0 a2.maximum = 1000 a2.default = 20 a2.name = "width" a2.tag = "wdth" a2.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)] a2.hidden = True a2.labelNames[u'fr'] = u"Chasse" doc.addAxis(a2) # add master 1 s1 = SourceDescriptor() s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath)) assert s1.font is None s1.name = "master.ufo1" s1.copyLib = True s1.copyInfo = True s1.copyFeatures = True s1.location = dict(weight=0) s1.familyName = "MasterFamilyName" s1.styleName = "MasterStyleNameOne" s1.mutedGlyphNames.append("A") s1.mutedGlyphNames.append("Z") doc.addSource(s1) # add master 2 s2 = SourceDescriptor() s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s2.name = "master.ufo2" s2.copyLib = False s2.copyInfo = False s2.copyFeatures = False s2.muteKerning = True s2.location = dict(weight=1000) s2.familyName = "MasterFamilyName" s2.styleName = "MasterStyleNameTwo" doc.addSource(s2) # add master 3 from a different layer s3 = SourceDescriptor() s3.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s3.name = "master.ufo2" s3.copyLib = False s3.copyInfo = False s3.copyFeatures = False s3.muteKerning = False s3.layerName = "supports" s3.location = dict(weight=1000) s3.familyName = "MasterFamilyName" s3.styleName = "Supports" doc.addSource(s3) # 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(weight=500, spooky=666) # this adds a dimension that is not defined. i1.postScriptFontName = "InstancePostscriptName" i1.styleMapFamilyName = "InstanceStyleMapFamilyName" i1.styleMapStyleName = "InstanceStyleMapStyleName" glyphData = dict(name="arrow", mute=True, unicodes=[0x123, 0x124, 0x125]) i1.glyphs['arrow'] = glyphData i1.lib['com.coolDesignspaceApp.binaryData'] = plistlib.Data(b'<binary gunk>') i1.lib['com.coolDesignspaceApp.specimenText'] = "Hamburgerwhatever" doc.addInstance(i1) # add instance 2 i2 = InstanceDescriptor() i2.filename = os.path.relpath(instancePath2, os.path.dirname(testDocPath)) i2.familyName = "InstanceFamilyName" i2.styleName = "InstanceStyleName" i2.name = "instance.ufo2" # anisotropic location i2.location = dict(weight=500, width=(400,300)) i2.postScriptFontName = "InstancePostscriptName" i2.styleMapFamilyName = "InstanceStyleMapFamilyName" i2.styleMapStyleName = "InstanceStyleMapStyleName" glyphMasters = [dict(font="master.ufo1", glyphName="BB", location=dict(width=20,weight=20)), dict(font="master.ufo2", glyphName="CC", location=dict(width=900,weight=900))] glyphData = dict(name="arrow", unicodes=[101, 201, 301]) glyphData['masters'] = glyphMasters glyphData['note'] = "A note about this glyph" glyphData['instanceLocation'] = dict(width=100, weight=120) i2.glyphs['arrow'] = glyphData i2.glyphs['arrow2'] = dict(mute=False) doc.addInstance(i2) doc.filename = "suggestedFileName.designspace" doc.lib['com.coolDesignspaceApp.previewSize'] = 30 # write some rules r1 = RuleDescriptor() r1.name = "named.rule.1" r1.conditionSets.append([ dict(name='axisName_a', minimum=0, maximum=1), dict(name='axisName_b', minimum=2, maximum=3) ]) r1.subs.append(("a", "a.alt")) doc.addRule(r1) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) assert_equals_test_file(testDocPath, 'data/test.designspace') # import it again new = DesignSpaceDocument() new.read(testDocPath) assert new.default.location == {'width': 20.0, 'weight': 0.0} assert new.filename == 'test.designspace' assert new.lib == doc.lib assert new.instances[0].lib == doc.instances[0].lib # test roundtrip for the axis attributes and data axes = {} for axis in doc.axes: if axis.tag not in axes: axes[axis.tag] = [] axes[axis.tag].append(axis.serialize()) for axis in new.axes: if axis.tag[0] == "_": continue if axis.tag not in axes: axes[axis.tag] = [] axes[axis.tag].append(axis.serialize()) for v in axes.values(): a, b = v assert a == b
def test_pathNameResolve(tmpdir): tmpdir = str(tmpdir) # test how descriptor.path and descriptor.filename are resolved testDocPath1 = os.path.join(tmpdir, "testPathName_case1.designspace") testDocPath2 = os.path.join(tmpdir, "testPathName_case2.designspace") testDocPath3 = os.path.join(tmpdir, "testPathName_case3.designspace") testDocPath4 = os.path.join(tmpdir, "testPathName_case4.designspace") testDocPath5 = os.path.join(tmpdir, "testPathName_case5.designspace") testDocPath6 = os.path.join(tmpdir, "testPathName_case6.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") a1 = AxisDescriptor() a1.tag = "TAGA" a1.name = "axisName_a" a1.minimum = 0 a1.maximum = 1000 a1.default = 0 # Case 1: filename and path are both empty. Nothing to calculate, nothing to put in the file. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = None s.path = None s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath1) verify = DesignSpaceDocument() verify.read(testDocPath1) assert verify.sources[0].filename == None assert verify.sources[0].path == None # Case 2: filename is empty, path points somewhere: calculate a new filename. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = None s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath2) verify = DesignSpaceDocument() verify.read(testDocPath2) assert verify.sources[0].filename == "masters/masterTest1.ufo" assert verify.sources[0].path == posix(masterPath1) # Case 3: the filename is set, the path is None. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = "../somewhere/over/the/rainbow.ufo" s.path = None s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath3) verify = DesignSpaceDocument() verify.read(testDocPath3) assert verify.sources[0].filename == "../somewhere/over/the/rainbow.ufo" # make the absolute path for filename so we can see if it matches the path p = os.path.abspath(os.path.join(os.path.dirname(testDocPath3), verify.sources[0].filename)) assert verify.sources[0].path == posix(p) # Case 4: the filename points to one file, the path points to another. The path takes precedence. doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = "../somewhere/over/the/rainbow.ufo" s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath4) verify = DesignSpaceDocument() verify.read(testDocPath4) assert verify.sources[0].filename == "masters/masterTest1.ufo" # Case 5: the filename is None, path has a value, update the filename doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = None s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.addSource(s) doc.write(testDocPath5) # so that the document has a path doc.updateFilenameFromPath() assert doc.sources[0].filename == "masters/masterTest1.ufo" # Case 6: the filename has a value, path has a value, update the filenames with force doc = DesignSpaceDocument() doc.addAxis(a1) s = SourceDescriptor() s.filename = "../somewhere/over/the/rainbow.ufo" s.path = masterPath1 s.copyInfo = True s.location = dict(weight=0) s.familyName = "MasterFamilyName" s.styleName = "MasterStyleNameOne" doc.write(testDocPath5) # so that the document has a path doc.addSource(s) assert doc.sources[0].filename == "../somewhere/over/the/rainbow.ufo" doc.updateFilenameFromPath(force=True) assert doc.sources[0].filename == "masters/masterTest1.ufo"
def test_handleNoAxes(tmpdir): tmpdir = str(tmpdir) # test what happens if the designspacedocument has no axes element. testDocPath = os.path.join(tmpdir, "testNoAxes_source.designspace") testDocPath2 = os.path.join(tmpdir, "testNoAxes_recontructed.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "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) verify = DesignSpaceDocument() verify.read(testDocPath) verify.write(testDocPath2)
def test_localisedNames(tmpdir): tmpdir = str(tmpdir) testDocPath = os.path.join(tmpdir, "testLocalisedNames.designspace") testDocPath2 = os.path.join(tmpdir, "testLocalisedNames_roundtrip.designspace") masterPath1 = os.path.join(tmpdir, "masters", "masterTest1.ufo") masterPath2 = os.path.join(tmpdir, "masters", "masterTest2.ufo") instancePath1 = os.path.join(tmpdir, "instances", "instanceTest1.ufo") instancePath2 = os.path.join(tmpdir, "instances", "instanceTest2.ufo") doc = DesignSpaceDocument() # add master 1 s1 = SourceDescriptor() s1.filename = os.path.relpath(masterPath1, os.path.dirname(testDocPath)) s1.name = "master.ufo1" s1.copyInfo = True s1.location = dict(weight=0) doc.addSource(s1) # add master 2 s2 = SourceDescriptor() s2.filename = os.path.relpath(masterPath2, os.path.dirname(testDocPath)) s2.name = "master.ufo2" s2.location = dict(weight=1000) doc.addSource(s2) # add instance 1 i1 = InstanceDescriptor() i1.filename = os.path.relpath(instancePath1, os.path.dirname(testDocPath)) i1.familyName = "Montserrat" i1.styleName = "SemiBold" i1.styleMapFamilyName = "Montserrat SemiBold" i1.styleMapStyleName = "Regular" i1.setFamilyName("Montserrat", "fr") i1.setFamilyName(u"モンセラート", "ja") i1.setStyleName("Demigras", "fr") i1.setStyleName(u"半ば", "ja") i1.setStyleMapStyleName(u"Standard", "de") i1.setStyleMapFamilyName("Montserrat Halbfett", "de") i1.setStyleMapFamilyName(u"モンセラート SemiBold", "ja") i1.name = "instance.ufo1" i1.location = dict(weight=500, spooky=666) # this adds a dimension that is not defined. i1.postScriptFontName = "InstancePostscriptName" glyphData = dict(name="arrow", mute=True, unicodes=[0x123]) i1.glyphs['arrow'] = glyphData doc.addInstance(i1) # now we have sources and instances, but no axes yet. doc.axes = [] # clear the axes # write some axes a1 = AxisDescriptor() a1.minimum = 0 a1.maximum = 1000 a1.default = 0 a1.name = "weight" a1.tag = "wght" # note: just to test the element language, not an actual label name recommendations. a1.labelNames[u'fa-IR'] = u"قطر" a1.labelNames[u'en'] = u"Wéíght" doc.addAxis(a1) a2 = AxisDescriptor() a2.minimum = 0 a2.maximum = 1000 a2.default = 0 a2.name = "width" a2.tag = "wdth" a2.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)] a2.labelNames[u'fr'] = u"Poids" doc.addAxis(a2) # add an axis that is not part of any location to see if that works a3 = AxisDescriptor() a3.minimum = 333 a3.maximum = 666 a3.default = 444 a3.name = "spooky" a3.tag = "spok" a3.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)] #doc.addAxis(a3) # uncomment this line to test the effects of default axes values # write some rules r1 = RuleDescriptor() r1.name = "named.rule.1" r1.conditionSets.append([ dict(name='weight', minimum=200, maximum=500), dict(name='width', minimum=0, maximum=150) ]) r1.subs.append(("a", "a.alt")) doc.addRule(r1) # write the document doc.write(testDocPath) assert os.path.exists(testDocPath) # import it again new = DesignSpaceDocument() new.read(testDocPath) new.write(testDocPath2) with open(testDocPath, 'r', encoding='utf-8') as f1: t1 = f1.read() with open(testDocPath2, 'r', encoding='utf-8') as f2: t2 = f2.read() assert t1 == t2