def testOuroborosKerning(rootPath, cleanUp=True): # that works, let's do it via MutatorMath path1, path2, path3 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, "kerningTest.designspace") doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource( path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True ) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=100)) doc.writeKerning(location=dict(width=500)) doc.endInstance() doc.save() # execute the designspace. Kerning errors should be tripped by the doc = DesignSpaceDocumentReader(documentPath, 2, roundGeometry=True, verbose=True, progressFunc=testingProgressFunc) doc.process(makeGlyphs=True, makeKerning=True, makeInfo=True) if cleanUp: # remove the mess shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) return True
def testOuroborosKerning(rootPath, cleanUp=True): # that works, let's do it via MutatorMath path1, path2, path3 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, 'kerningTest.designspace') logPath = os.path.join(rootPath,"kerningTest.log") try: testLogFile = open(logPath, 'w') testLogFile.close() except: print "Can't make a logfile." doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource( path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True, ) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=100) ) doc.writeKerning(location=dict(width=500)) doc.endInstance() doc.save() # execute the designspace. Kerning errors should be tripped by the doc = DesignSpaceDocumentReader(documentPath, 2, roundGeometry=True, verbose=True, logPath=logPath, progressFunc=testingProgressFunc) doc.process(makeGlyphs=True, makeKerning=True, makeInfo=True) # did we log the error? report = u"""invalidInstance.ufo:\nThese kerning pairs failed validation and have been removed:\nglyphOne, public.kern2.@MMK_R_two (-400) conflicts with public.kern1.@MMK_L_one, glyphThree (-250)\npublic.kern1.@MMK_L_one, glyphThree (-250) conflicts with glyphOne, public.kern2.@MMK_R_two (-400)""" log = open(logPath, 'r') logText = log.read() log.close() #print logText #assert report in logText if cleanUp: # remove the mess shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) return True
def testOuroborosKerning(rootPath, cleanUp=True): # that works, let's do it via MutatorMath path1, path2, path3 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, 'kerningTest.designspace') logPath = os.path.join(rootPath,"kerningTest.log") try: testLogFile = open(logPath, 'w') testLogFile.close() except: print("Can't make a logfile.") doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource( path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True, ) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=100) ) doc.writeKerning(location=dict(width=500)) doc.endInstance() doc.save() # execute the designspace. Kerning errors should be tripped by the doc = DesignSpaceDocumentReader(documentPath, 2, roundGeometry=True, verbose=True, logPath=logPath, progressFunc=testingProgressFunc) doc.process(makeGlyphs=True, makeKerning=True, makeInfo=True) # did we log the error? report = u"""invalidInstance.ufo:\nThese kerning pairs failed validation and have been removed:\nglyphOne, public.kern2.@MMK_R_two (-400) conflicts with public.kern1.@MMK_L_one, glyphThree (-250)\npublic.kern1.@MMK_L_one, glyphThree (-250) conflicts with glyphOne, public.kern2.@MMK_R_two (-400)""" log = open(logPath, 'r') logText = log.read() log.close() #print logText #assert report in logText if cleanUp: # remove the mess shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) return True
def testGeometry(rootPath, cleanUp=True): # that works, let's do it via MutatorMath path1, path2, path3, path4, path5 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, "geometryTest.designspace") logPath = os.path.join(rootPath, "geometryTest.log") try: testLogFile = open(logPath, "w") testLogFile.close() except: print "Can't make a logfile." doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource( path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True ) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=500)) doc.endInstance() doc.startInstance( fileName=path4, familyName="TestInstance", styleName="Anisotropic1", location=dict(width=(0, 1000)) ) doc.endInstance() doc.startInstance( fileName=path5, familyName="TestInstance", styleName="Anisotropic2", location=dict(width=(1000, 0)) ) doc.endInstance() doc.save() # execute the designspace. doc = DesignSpaceDocumentReader( documentPath, 2, roundGeometry=True, verbose=True, logPath=logPath, progressFunc=testingProgressFunc ) doc.process(makeGlyphs=True, makeKerning=False, makeInfo=True) r1 = Font(path3) assert r1["glyphOne"].bounds == (0, 0, 300, 300) r2 = Font(path4) assert r2["glyphOne"].bounds == (0, 0, 100, 500) r3 = Font(path5) assert r3["glyphOne"].bounds == (0, 0, 500, 100) if cleanUp: # remove the mess shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) return True
def testOuroborosKerning(rootPath, cleanUp=True): # that works, let's do it via MutatorMath path1, path2, path3 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, 'kerningTest.designspace') doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource( path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True, ) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=100)) doc.writeKerning(location=dict(width=500)) doc.endInstance() doc.save() # execute the designspace. Kerning errors should be tripped by the doc = DesignSpaceDocumentReader(documentPath, 2, roundGeometry=True, verbose=True, progressFunc=testingProgressFunc) doc.process(makeGlyphs=True, makeKerning=True, makeInfo=True) if cleanUp: # remove the mess shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) return True def test1(): """
def generate_designspace(family, path): def normalize_path(path): return os.path.join(family['working_directory'], path) doc = DesignSpaceDocumentWriter(normalize_path(path)) for i, master in enumerate(family['masters']): doc.addSource( path = normalize_path(master['path']), name = 'master-' + master['name'], location = {'weight': master['interpolation_value']}, copyLib = True if i == 0 else False, copyGroups = True if i == 0 else False, copyInfo = True if i == 0 else False, # muteInfo = False, # muteKerning = False, # mutedGlyphNames = None, ) for style in family['styles']: doc.startInstance( name = 'instance-' + style['name'], location = {'weight': style['interpolation_value']}, familyName = family['output_name'], styleName = style['name'], fileName = normalize_path(style['path']), postScriptFontName = style['output_full_name_postscript'], # styleMapFamilyName = None, # styleMapStyleName = None, ) doc.writeInfo() if family['has_kerning']: doc.writeKerning() doc.endInstance() doc.save()
def makeInstances(stepsWeight, stepsWidth): doc = DesignSpaceDocumentWriter(designSpacePath, verbose=True) doc.addSource(os.path.join(mutatorSansFolder, "MutatorSansLightCondensed.ufo"), name="LightCondensed", location=dict(weight=0, width=0), copyInfo=True, familyName="MutatorSans", styleName="LightCondensed") doc.addSource(os.path.join(mutatorSansFolder, "MutatorSansLightWide.ufo"), name="LightWide", location=dict(weight=0, width=1)) doc.addSource(os.path.join(mutatorSansFolder, "MutatorSansBoldCondensed.ufo"), name="BoldCondensed", location=dict(weight=1, width=0)) doc.addSource(os.path.join(mutatorSansFolder, "MutatorSansBoldWide.ufo"), name="BoldWide", location=dict(weight=1, width=1)) for i in range(stepsWeight): wt = i * 1.0 / (stepsWeight - 1) for j in range(stepsWidth): wd = j * 1.0 / (stepsWidth - 1) doc.startInstance(fileName=os.path.join( ufosFolder, "MutatorSansInstance_%s-%s.ufo" % (int(wt * 1000), int(wd * 1000))), familyName="MutatorSansExample", styleName="%s-%s" % (int(wt * 1000), int(wd * 1000)), location=dict(weight=wt, width=wd)) doc.endInstance() doc.save() doc = DesignSpaceDocumentReader(designSpacePath, 3, roundGeometry=True, verbose=False) doc.process(makeGlyphs=True, makeKerning=False, makeInfo=False)
def testMutingOptions(rootPath, cleanUp=True): # that works, let's do it via MutatorMath # path1 and path2 are masters. path3 is the instance path1, path2, path3 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, 'mutingTest.designspace') logPath = os.path.join(rootPath,"mutingTest.log") try: testLogFile = open(logPath, 'w') testLogFile.close() except: print "Can't make a logfile." doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource( path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True, muteKerning=True ) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, muteInfo=True, mutedGlyphNames=['glyphThree'] # mute glyphThree in master 1 ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=500) ) doc.writeGlyph('glyphFour', mute=True) # mute glyphFour in the instance doc.writeKerning() doc.writeInfo() doc.endInstance() doc.save() # execute the designspace. doc = DesignSpaceDocumentReader(documentPath, 2, roundGeometry=True, verbose=True, logPath=logPath, progressFunc=testingProgressFunc) doc.process(makeGlyphs=True, makeKerning=True, makeInfo=True) # look at the results m1 = Font(path1) m2 = Font(path2) r = Font(path3) # # the glyphThree master was muted in the second master # so the instance glyphThree should be the same as the first master: assert r['glyphThree'].bounds == m1['glyphThree'].bounds # we muted glyphFour in the instance. # so it should not be part of the instance UFO: assert "glyphFour" not in r # font.info is muted for master2, so the instance has to have the values from master 1 assert r.info.unitsPerEm == m1.info.unitsPerEm # kerning is muted for master1, so the instance has to have the kerning from master 2 assert r.kerning[('glyphOne', 'glyphOne')] == m2.kerning[('glyphOne', 'glyphOne')] if cleanUp: # remove the mess try: shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) except: pass return True
def testMutingOptions(rootPath, cleanUp=True): # that works, let's do it via MutatorMath # path1 and path2 are masters. path3 is the instance path1, path2, path3 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, 'mutingTest.designspace') doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource(path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True, muteKerning=True) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, muteInfo=True, mutedGlyphNames=['glyphThree'] # mute glyphThree in master 1 ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=500)) doc.writeGlyph('glyphFour', mute=True) # mute glyphFour in the instance doc.writeKerning() doc.writeInfo() doc.endInstance() doc.save() # execute the designspace. doc = DesignSpaceDocumentReader(documentPath, 2, roundGeometry=True, verbose=True, progressFunc=testingProgressFunc) doc.process(makeGlyphs=True, makeKerning=True, makeInfo=True) # look at the results m1 = Font(path1) m2 = Font(path2) r = Font(path3) # # the glyphThree master was muted in the second master # so the instance glyphThree should be the same as the first master: assert r['glyphThree'].bounds == m1['glyphThree'].bounds # we muted glyphFour in the instance. # so it should not be part of the instance UFO: assert "glyphFour" not in r # font.info is muted for master2, so the instance has to have the values from master 1 assert r.info.unitsPerEm == m1.info.unitsPerEm # kerning is muted for master1, so the instance has to have the kerning from master 2 assert r.kerning[('glyphOne', 'glyphOne')] == m2.kerning[('glyphOne', 'glyphOne')] if cleanUp: # remove the mess try: shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) except: pass return True
def testGeometry(rootPath, cleanUp=True): # that works, let's do it via MutatorMath path1, path2, path3, path4, path5 = makeTestFonts(rootPath) documentPath = os.path.join(rootPath, 'geometryTest.designspace') doc = DesignSpaceDocumentWriter(documentPath, verbose=True) doc.addSource( path1, name="master_1", location=dict(width=0), copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True, ) doc.addSource( path2, name="master_2", location=dict(width=1000), copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, ) doc.startInstance(fileName=path3, familyName="TestInstance", styleName="Regular", location=dict(width=500) ) doc.endInstance() doc.startInstance(fileName=path4, familyName="TestInstance", styleName="Anisotropic1", location=dict(width=(0, 1000)) ) doc.endInstance() doc.startInstance(fileName=path5, familyName="TestInstance", styleName="Anisotropic2", location=dict(width=(1000, 0)) ) doc.endInstance() doc.save() # execute the designspace. doc = DesignSpaceDocumentReader(documentPath, 2, roundGeometry=True, verbose=True, progressFunc=testingProgressFunc) doc.process(makeGlyphs=True, makeKerning=False, makeInfo=True) r1 = Font(path3) assert r1['glyphOne'].bounds == (0, 0, 300, 300) r2 = Font(path4) assert r2['glyphOne'].bounds == (0, 0, 100, 500) r3 = Font(path5) assert r3['glyphOne'].bounds == (0, 0, 500, 100) if cleanUp: # remove the mess shutil.rmtree(path1) shutil.rmtree(path2) shutil.rmtree(path3) return True
class DesignSpaceMaker(object): axes = [] masters = [] instances = [] neutral = None def __init__(self, project): self.project = project # remove existing .designspace file if os.path.exists(self.project.designspace_path): os.remove(self.project.designspace_path) # create fresh .designspace file self.doc_writer = DesignSpaceDocumentWriter(self.project.designspace_path, verbose=True) def add_masters(self, verbose=False): if verbose: print('\tadding masters...') for master in self.masters: ufo_path = os.path.join(self.project.ufos_folder, '%s.ufo' % master) # check if master exists if os.path.exists(ufo_path): # make Location L = {} for i in range(len(self.axes)): axis = self.axes[i] param = self.masters[master][i] L[axis] = param # add neutral if master == self.neutral: if verbose: print('\t\tadding %s [neutral]...' % master) self.doc_writer.addSource( ufo_path, master, location=L, copyInfo=True, copyGroups=True, copyLib=False, copyFeatures=False) # add deltas else: if verbose: print('\t\tadding %s...' % master) self.doc_writer.addSource(ufo_path, master, location=L) def add_instances(self, verbose=False): if verbose: print('\tadding instances...') for instance in self.instances: ufo_filename = '%s.ufo' % instance.replace(' ', '-') ufo_path = os.path.join(self.project.instances_folder, ufo_filename) # make Location L = {} for i in range(len(self.axes)): axis = self.axes[i] param = self.instances[instance][i] L[axis] = param # add instance if verbose: print('\t\tadding %s...' % instance) self.doc_writer.startInstance( fileName=ufo_path, familyName='Untitled', styleName=instance, location=L) self.doc_writer.endInstance() def save(self, verbose=False): if verbose: print('creating .designspace file...') # add masters self.add_masters(verbose) # add instances self.add_instances(verbose) if verbose: print('\tsaving file %s...' % self.project.designspace_path, end=' ') # save designspace file self.doc_writer.save() if verbose: print(os.path.exists(self.project.designspace_path)) if verbose: print('...done.\n')
# Copy sources to temporary 1-drawings for source in src: copy_tree(source, src_dir) # use a temporary designspace to build instances with mutator math familyName = "Amstelvar" tmpDesignSpace = "tmp.designspace" doc = DesignSpaceDocumentWriter(tmpDesignSpace) # sources doc.addSource(path="sources/1-drawings/Amstelvar-Italic.ufo", name="Amstelvar-Italic.ufo", location=dict(wght=0, wdth=0, opsz=0), styleName="Italic", familyName=familyName, copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, muteKerning=False, muteInfo=False, mutedGlyphNames=None) # axes doc.addAxis(tag="wght", name="wght", minimum=100, maximum=900, default=400, warpMap=None) doc.addAxis(tag="wdth", name="wdth",
src_dir = "1-drawings" master_dir = "master_ufo" instance_dir = "instances" # use a temporary designspace to build instances with mutator math familyName = "RobotoDelta" tmpDesignSpace = "tmp.designspace" doc = DesignSpaceDocumentWriter(tmpDesignSpace) # sources doc.addSource(path="1-drawings/RobotoDelta-Regular.ufo", name="RobotoDelta-Regular.ufo", location=dict(XYOPQ=0, XTRA=0, YTLC=0, YTUC=0, YTAS=0, YTDE=0), styleName="Regular", familyName=familyName, copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, muteKerning=False, muteInfo=False, mutedGlyphNames=None) doc.addSource(path="1-drawings/RobotoDelta-XOPQmin-YOPQmin.ufo", name="RobotoDelta-XOPQmin-YOPQmin.ufo", location=dict(XYOPQ=-1), styleName="XOPQmin-YOPQmin", familyName=familyName, copyLib=False, copyGroups=False, copyInfo=False, copyFeatures=False, muteKerning=False,
# Copy sources to temporary 1-drawings for source in src: copy_tree(source, src_dir) # use a temporary designspace to build instances with mutator math familyName = "Lexend" tmpDesignSpace = "tmp.designspace" doc = DesignSpaceDocumentWriter(tmpDesignSpace) # sources doc.addSource(path="sources/1-drawings/Lexend-Regular.ufo", name="Lexend-Regular.ufo", location=dict(wdth=100), styleName="Regular", familyName=familyName, copyLib=True, copyGroups=True, copyInfo=True, copyFeatures=True, muteKerning=False, muteInfo=False, mutedGlyphNames=None) # axes # doc.addAxis(tag="wght", name="wght", minimum=300, maximum=800, default=500, warpMap=None) doc.addAxis(tag="wdth", name="wdth", minimum=100, maximum=125, default=100, warpMap=None) # doc.addAxis(tag="opsz", name="opsz", minimum=8, maximum=144, default=14, warpMap=None)
class DesignSpaceMaker(object): axes = [] masters = [] instances = [] neutral = None def __init__(self, project): self.project = project # remove existing .designspace file if os.path.exists(self.project.designspace_path): os.remove(self.project.designspace_path) # create fresh .designspace file self.doc_writer = DesignSpaceDocumentWriter(self.project.designspace_path, verbose=True) def add_masters(self, verbose=False): if verbose: print '\tadding masters...' for master in self.masters: ufo_path = os.path.join(self.project.ufos_folder, '%s.ufo' % master) # check if master exists if os.path.exists(ufo_path): # make Location L = {} for i in range(len(self.axes)): axis = self.axes[i] param = self.masters[master][i] L[axis] = param # add neutral if master == self.neutral: if verbose: print '\t\tadding %s [neutral]...' % master self.doc_writer.addSource( ufo_path, master, location=L, copyInfo=True, copyGroups=True, copyLib=False, copyFeatures=False) # add deltas else: if verbose: print '\t\tadding %s...' % master self.doc_writer.addSource(ufo_path, master, location=L) def add_instances(self, verbose=False): if verbose: print '\tadding instances...' for instance in self.instances: ufo_filename = '%s.ufo' % instance.replace(' ', '-') ufo_path = os.path.join(self.project.instances_folder, ufo_filename) # make Location L = {} for i in range(len(self.axes)): axis = self.axes[i] param = self.instances[instance][i] L[axis] = param # add instance if verbose: print '\t\tadding %s...' % instance self.doc_writer.startInstance( fileName=ufo_path, familyName='Untitled', styleName=instance, location=L) self.doc_writer.endInstance() def save(self, verbose=False): if verbose: print 'creating .designspace file...' # add masters self.add_masters(verbose) # add instances self.add_instances(verbose) if verbose: print '\tsaving file %s...' % self.project.designspace_path, # save designspace file self.doc_writer.save() if verbose: print os.path.exists(self.project.designspace_path) if verbose: print '...done.\n'