def makeInstance(counter, ufoMasters, instanceInfo, outputDirPath, options): if len(ufoMasters) == 2: 'Linear interpolation with 2 masters' pass else: 'Linear interpolation with intermediate masters' ufoMasters = [master for master in ufoMasters if os.path.basename(master.path) in instanceInfo.get(kMasters)] try: faceName = instanceInfo[kFontName].split('-')[1] except IndexError: faceName = 'Regular' print print "%s (%d/%d)" % (faceName, counter[0], counter[1]) # Calculate the value of the interpolation factor # XXX It's currently assuming a 0-1000 axis interpolationFactor = instanceInfo[kCoordsKey][0]/1000.000 glyphOrder = ufoMasters[0].lib["public.glyphOrder"] # aGlyph.isCompatible(otherGlyph, report=True) # for glyphName in glyphOrder: # ufoMasters[0][glyphName].isCompatible(ufoMasters[1][glyphName], True) ufoInstance = NewFont() # Interpolate the masters # Documentation: http://www.robofab.org/howto/interpolate.html # aFont.interpolate(factor, minFont, maxFont, suppressError=True, analyzeOnly=False) # aFont.interpolate() interpolates: # - positions of components # - anchors # - ascender # - descender # - glyph widths for the whole font ufoInstance.interpolate(interpolationFactor, ufoMasters[0], ufoMasters[1]) # Round all the point coordinates to whole integer numbers ufoInstance.round() # Interpolate the kerning # Documentation: http://www.robofab.org/objects/kerning.html # f.kerning.interpolate(sourceDictOne, sourceDictTwo, value, clearExisting=True) if len(ufoMasters[0].kerning): ufoInstance.kerning.interpolate(ufoMasters[0].kerning, ufoMasters[1].kerning, interpolationFactor) ufoInstance.kerning.round(1) # convert the interpolated values to integers for glyphName in glyphOrder: ufoInstance[glyphName].unicode = ufoMasters[0][glyphName].unicode if len(ufoMasters[0][glyphName]) != len(ufoInstance[glyphName]): print "\tWARNING: Interpolation failed in glyph %s" % glyphName styleName = instanceInfo[kFullName].replace(instanceInfo[kFamilyName], '').strip() ufoInstance.info.styleName = styleName ufoInstance.info.familyName = instanceInfo[kFamilyName] ufoInstance.info.postscriptFontName = instanceInfo[kFontName] ufoInstance.info.postscriptFullName = instanceInfo[kFullName] ufoInstance.info.postscriptWeightName = instanceInfo[kWeight] ufoInstance.info.postscriptForceBold = True if instanceInfo[kIsBoldKey] else False ufoInstance.lib = ufoMasters[0].lib ufoInstance.groups = ufoMasters[0].groups ufoInstance.info.copyright = ufoMasters[0].info.copyright ufoInstance.info.trademark = ufoMasters[0].info.trademark ufoInstance.info.unitsPerEm = ufoMasters[0].info.unitsPerEm ufoInstance.info.versionMajor = ufoMasters[0].info.versionMajor ufoInstance.info.versionMinor = ufoMasters[0].info.versionMinor ufoInstance.info.postscriptIsFixedPitch = ufoMasters[0].info.postscriptIsFixedPitch # ascender if ufoMasters[0].info.ascender and ufoMasters[1].info.ascender: ufoInstance.info.ascender = int(round(objectsBase._interpolate(ufoMasters[0].info.ascender, ufoMasters[1].info.ascender, interpolationFactor))) # descender if ufoMasters[0].info.descender and ufoMasters[1].info.descender: ufoInstance.info.descender = int(round(objectsBase._interpolate(ufoMasters[0].info.descender, ufoMasters[1].info.descender, interpolationFactor))) # capHeight if ufoMasters[0].info.capHeight and ufoMasters[1].info.capHeight: ufoInstance.info.capHeight = int(round(objectsBase._interpolate(ufoMasters[0].info.capHeight, ufoMasters[1].info.capHeight, interpolationFactor))) # xHeight if ufoMasters[0].info.xHeight and ufoMasters[1].info.xHeight: ufoInstance.info.xHeight = int(round(objectsBase._interpolate(ufoMasters[0].info.xHeight, ufoMasters[1].info.xHeight, interpolationFactor))) # italicAngle if (ufoMasters[0].info.italicAngle != None) and (ufoMasters[1].info.italicAngle != None): ufoInstance.info.italicAngle = int(round(objectsBase._interpolate(ufoMasters[0].info.italicAngle, ufoMasters[1].info.italicAngle, interpolationFactor))) # postscriptUnderlinePosition if ufoMasters[0].info.postscriptUnderlinePosition and ufoMasters[1].info.postscriptUnderlinePosition: ufoInstance.info.postscriptUnderlinePosition = int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptUnderlinePosition, ufoMasters[1].info.postscriptUnderlinePosition, interpolationFactor))) # postscriptUnderlineThickness if ufoMasters[0].info.postscriptUnderlineThickness and ufoMasters[1].info.postscriptUnderlineThickness: ufoInstance.info.postscriptUnderlineThickness = int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptUnderlineThickness, ufoMasters[1].info.postscriptUnderlineThickness, interpolationFactor))) # postscriptBlueFuzz if (ufoMasters[0].info.postscriptBlueFuzz != None) and (ufoMasters[1].info.postscriptBlueFuzz != None): ufoInstance.info.postscriptBlueFuzz = int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptBlueFuzz, ufoMasters[1].info.postscriptBlueFuzz, interpolationFactor))) # postscriptBlueScale if ufoMasters[0].info.postscriptBlueScale and ufoMasters[1].info.postscriptBlueScale: ufoInstance.info.postscriptBlueScale = objectsBase._interpolate(ufoMasters[0].info.postscriptBlueScale, ufoMasters[1].info.postscriptBlueScale, interpolationFactor) # postscriptBlueShift if ufoMasters[0].info.postscriptBlueShift and ufoMasters[1].info.postscriptBlueShift: ufoInstance.info.postscriptBlueShift = int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptBlueShift, ufoMasters[1].info.postscriptBlueShift, interpolationFactor))) # postscriptBlueValues if len(ufoMasters[0].info.postscriptBlueValues) == len(ufoMasters[1].info.postscriptBlueValues): ufoMasters[0].info.postscriptBlueValues.sort() ufoMasters[1].info.postscriptBlueValues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptBlueValues)): tempArray.append(int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptBlueValues[i], ufoMasters[1].info.postscriptBlueValues[i], interpolationFactor)))) ufoInstance.info.postscriptBlueValues = tempArray # postscriptOtherBlues if len(ufoMasters[0].info.postscriptOtherBlues) == len(ufoMasters[1].info.postscriptOtherBlues): ufoMasters[0].info.postscriptOtherBlues.sort() ufoMasters[1].info.postscriptOtherBlues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptOtherBlues)): tempArray.append(int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptOtherBlues[i], ufoMasters[1].info.postscriptOtherBlues[i], interpolationFactor)))) ufoInstance.info.postscriptOtherBlues = tempArray # postscriptFamilyBlues if len(ufoMasters[0].info.postscriptFamilyBlues) == len(ufoMasters[1].info.postscriptFamilyBlues): ufoMasters[0].info.postscriptFamilyBlues.sort() ufoMasters[1].info.postscriptFamilyBlues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptFamilyBlues)): tempArray.append(int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptFamilyBlues[i], ufoMasters[1].info.postscriptFamilyBlues[i], interpolationFactor)))) ufoInstance.info.postscriptFamilyBlues = tempArray # postscriptFamilyOtherBlues if len(ufoMasters[0].info.postscriptFamilyOtherBlues) == len(ufoMasters[1].info.postscriptFamilyOtherBlues): ufoMasters[0].info.postscriptFamilyOtherBlues.sort() ufoMasters[1].info.postscriptFamilyOtherBlues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptFamilyOtherBlues)): tempArray.append(int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptFamilyOtherBlues[i], ufoMasters[1].info.postscriptFamilyOtherBlues[i], interpolationFactor)))) ufoInstance.info.postscriptFamilyOtherBlues = tempArray # postscriptStemSnapH if len(ufoMasters[0].info.postscriptStemSnapH) == len(ufoMasters[1].info.postscriptStemSnapH): ufoMasters[0].info.postscriptStemSnapH.sort() ufoMasters[1].info.postscriptStemSnapH.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptStemSnapH)): tempArray.append(int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptStemSnapH[i], ufoMasters[1].info.postscriptStemSnapH[i], interpolationFactor)))) ufoInstance.info.postscriptStemSnapH = tempArray # postscriptStemSnapV if len(ufoMasters[0].info.postscriptStemSnapV) == len(ufoMasters[1].info.postscriptStemSnapV): ufoMasters[0].info.postscriptStemSnapV.sort() ufoMasters[1].info.postscriptStemSnapV.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptStemSnapV)): tempArray.append(int(round(objectsBase._interpolate(ufoMasters[0].info.postscriptStemSnapV[i], ufoMasters[1].info.postscriptStemSnapV[i], interpolationFactor)))) ufoInstance.info.postscriptStemSnapV = tempArray faceFolder = makeFaceFolder(outputDirPath, faceName) ufoPath = os.path.join(faceFolder, kFontInstanceFileName) # Save UFO instance if not options.noUFOs: print '\tSaving %s file...' % kFontInstanceFileName # Delete the old UFO file, if it exists while os.path.exists(ufoPath): shutil.rmtree(ufoPath) ufoInstance.save(ufoPath) # Generate 'kern' feature if options.genKernFeature: print "\tGenerating 'kern' feature..." WriteFeaturesKernFDK.KernDataClass(ufoInstance, faceFolder, options.minKern, options.writeTrimmed, options.writeSubtables) # Generate 'mark/mkmk' features if options.genMarkFeature: if options.genMkmkFeature: print "\tGenerating 'mark' and 'mkmk' features..." else: print "\tGenerating 'mark' feature..." WriteFeaturesMarkFDK.MarkDataClass(ufoInstance, faceFolder, options.trimCasingTags, options.genMkmkFeature, options.writeClassesFile, options.indianScriptsFormat) # Decompose and remove overlaps (using checkoutlines) if options.flatten: print '\tFlattening the glyphs...' if os.name == "nt": coTool = 'checkoutlines.cmd' else: coTool = 'checkoutlines' cmd = '%s -e "%s"' % (coTool, ufoPath) popen = Popen(cmd, shell=True, stdout=PIPE) popenout, popenerr = popen.communicate() if options.verboseMode: if popenout: print popenout if popenerr: print popenerr # Autohint if options.autohint: print '\tHinting the font...' cmd = 'autohint -q "%s"' % ufoPath popen = Popen(cmd, shell=True, stdout=PIPE) popenout, popenerr = popen.communicate() if options.verboseMode: if popenout: print popenout if popenerr: print popenerr
def makeInstance(counter, ufoMasters, instanceInfo, outputDirPath, options): try: faceName = instanceInfo[kFontName].split('-')[1] except IndexError: faceName = 'Regular' print print "%s (%d/%d)" % (faceName, counter[0], counter[1]) # Calculate the value of the interpolation factor # XXX It's currently assuming a 0-1000 axis interpolationFactor = instanceInfo[kCoordsKey][0] / 1000.000 glyphOrder = ufoMasters[0].lib["public.glyphOrder"] # aGlyph.isCompatible(otherGlyph, report=True) # for glyphName in glyphOrder: # ufoMasters[0][glyphName].isCompatible(ufoMasters[1][glyphName], True) ufoInstance = NewFont() # Interpolate the masters # Documentation: http://www.robofab.org/howto/interpolate.html # aFont.interpolate(factor, minFont, maxFont, suppressError=True, analyzeOnly=False) # aFont.interpolate() interpolates: # - positions of components # - anchors # - ascender # - descender # - glyph widths for the whole font ufoInstance.interpolate(interpolationFactor, ufoMasters[0], ufoMasters[1]) # Round all the point coordinates to whole integer numbers ufoInstance.round() # Interpolate the kerning # Documentation: http://www.robofab.org/objects/kerning.html # f.kerning.interpolate(sourceDictOne, sourceDictTwo, value, clearExisting=True) if len(ufoMasters[0].kerning): ufoInstance.kerning.interpolate(ufoMasters[0].kerning, ufoMasters[1].kerning, interpolationFactor) ufoInstance.kerning.round( 1) # convert the interpolated values to integers for glyphName in glyphOrder: ufoInstance[glyphName].unicode = ufoMasters[0][glyphName].unicode if len(ufoMasters[0][glyphName]) != len(ufoInstance[glyphName]): print "\tWARNING: Interpolation failed in glyph %s" % glyphName styleName = instanceInfo[kFullName].replace(instanceInfo[kFamilyName], '').strip() ufoInstance.info.styleName = styleName ufoInstance.info.familyName = instanceInfo[kFamilyName] ufoInstance.info.postscriptFontName = instanceInfo[kFontName] ufoInstance.info.postscriptFullName = instanceInfo[kFullName] ufoInstance.info.postscriptWeightName = instanceInfo[kWeight] ufoInstance.info.postscriptForceBold = True if instanceInfo[ kIsBoldKey] else False ufoInstance.lib = ufoMasters[0].lib ufoInstance.groups = ufoMasters[0].groups ufoInstance.info.copyright = ufoMasters[0].info.copyright ufoInstance.info.trademark = ufoMasters[0].info.trademark ufoInstance.info.unitsPerEm = ufoMasters[0].info.unitsPerEm ufoInstance.info.versionMajor = ufoMasters[0].info.versionMajor ufoInstance.info.versionMinor = ufoMasters[0].info.versionMinor ufoInstance.info.postscriptIsFixedPitch = ufoMasters[ 0].info.postscriptIsFixedPitch # ascender if ufoMasters[0].info.ascender and ufoMasters[1].info.ascender: ufoInstance.info.ascender = int( round( objectsBase._interpolate(ufoMasters[0].info.ascender, ufoMasters[1].info.ascender, interpolationFactor))) # descender if ufoMasters[0].info.descender and ufoMasters[1].info.descender: ufoInstance.info.descender = int( round( objectsBase._interpolate(ufoMasters[0].info.descender, ufoMasters[1].info.descender, interpolationFactor))) # capHeight if ufoMasters[0].info.capHeight and ufoMasters[1].info.capHeight: ufoInstance.info.capHeight = int( round( objectsBase._interpolate(ufoMasters[0].info.capHeight, ufoMasters[1].info.capHeight, interpolationFactor))) # xHeight if ufoMasters[0].info.xHeight and ufoMasters[1].info.xHeight: ufoInstance.info.xHeight = int( round( objectsBase._interpolate(ufoMasters[0].info.xHeight, ufoMasters[1].info.xHeight, interpolationFactor))) # italicAngle if (ufoMasters[0].info.italicAngle != None) and (ufoMasters[1].info.italicAngle != None): ufoInstance.info.italicAngle = int( round( objectsBase._interpolate(ufoMasters[0].info.italicAngle, ufoMasters[1].info.italicAngle, interpolationFactor))) # postscriptUnderlinePosition if ufoMasters[0].info.postscriptUnderlinePosition and ufoMasters[ 1].info.postscriptUnderlinePosition: ufoInstance.info.postscriptUnderlinePosition = int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptUnderlinePosition, ufoMasters[1].info.postscriptUnderlinePosition, interpolationFactor))) # postscriptUnderlineThickness if ufoMasters[0].info.postscriptUnderlineThickness and ufoMasters[ 1].info.postscriptUnderlineThickness: ufoInstance.info.postscriptUnderlineThickness = int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptUnderlineThickness, ufoMasters[1].info.postscriptUnderlineThickness, interpolationFactor))) # postscriptBlueFuzz if (ufoMasters[0].info.postscriptBlueFuzz != None) and (ufoMasters[1].info.postscriptBlueFuzz != None): ufoInstance.info.postscriptBlueFuzz = int( round( objectsBase._interpolate(ufoMasters[0].info.postscriptBlueFuzz, ufoMasters[1].info.postscriptBlueFuzz, interpolationFactor))) # postscriptBlueScale if ufoMasters[0].info.postscriptBlueScale and ufoMasters[ 1].info.postscriptBlueScale: ufoInstance.info.postscriptBlueScale = objectsBase._interpolate( ufoMasters[0].info.postscriptBlueScale, ufoMasters[1].info.postscriptBlueScale, interpolationFactor) # postscriptBlueShift if ufoMasters[0].info.postscriptBlueShift and ufoMasters[ 1].info.postscriptBlueShift: ufoInstance.info.postscriptBlueShift = int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptBlueShift, ufoMasters[1].info.postscriptBlueShift, interpolationFactor))) # postscriptBlueValues if len(ufoMasters[0].info.postscriptBlueValues) == len( ufoMasters[1].info.postscriptBlueValues): ufoMasters[0].info.postscriptBlueValues.sort() ufoMasters[1].info.postscriptBlueValues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptBlueValues)): tempArray.append( int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptBlueValues[i], ufoMasters[1].info.postscriptBlueValues[i], interpolationFactor)))) ufoInstance.info.postscriptBlueValues = tempArray # postscriptOtherBlues if len(ufoMasters[0].info.postscriptOtherBlues) == len( ufoMasters[1].info.postscriptOtherBlues): ufoMasters[0].info.postscriptOtherBlues.sort() ufoMasters[1].info.postscriptOtherBlues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptOtherBlues)): tempArray.append( int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptOtherBlues[i], ufoMasters[1].info.postscriptOtherBlues[i], interpolationFactor)))) ufoInstance.info.postscriptOtherBlues = tempArray # postscriptFamilyBlues if len(ufoMasters[0].info.postscriptFamilyBlues) == len( ufoMasters[1].info.postscriptFamilyBlues): ufoMasters[0].info.postscriptFamilyBlues.sort() ufoMasters[1].info.postscriptFamilyBlues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptFamilyBlues)): tempArray.append( int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptFamilyBlues[i], ufoMasters[1].info.postscriptFamilyBlues[i], interpolationFactor)))) ufoInstance.info.postscriptFamilyBlues = tempArray # postscriptFamilyOtherBlues if len(ufoMasters[0].info.postscriptFamilyOtherBlues) == len( ufoMasters[1].info.postscriptFamilyOtherBlues): ufoMasters[0].info.postscriptFamilyOtherBlues.sort() ufoMasters[1].info.postscriptFamilyOtherBlues.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptFamilyOtherBlues)): tempArray.append( int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptFamilyOtherBlues[i], ufoMasters[1].info.postscriptFamilyOtherBlues[i], interpolationFactor)))) ufoInstance.info.postscriptFamilyOtherBlues = tempArray # postscriptStemSnapH if len(ufoMasters[0].info.postscriptStemSnapH) == len( ufoMasters[1].info.postscriptStemSnapH): ufoMasters[0].info.postscriptStemSnapH.sort() ufoMasters[1].info.postscriptStemSnapH.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptStemSnapH)): tempArray.append( int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptStemSnapH[i], ufoMasters[1].info.postscriptStemSnapH[i], interpolationFactor)))) ufoInstance.info.postscriptStemSnapH = tempArray # postscriptStemSnapV if len(ufoMasters[0].info.postscriptStemSnapV) == len( ufoMasters[1].info.postscriptStemSnapV): ufoMasters[0].info.postscriptStemSnapV.sort() ufoMasters[1].info.postscriptStemSnapV.sort() tempArray = [] for i in range(len(ufoMasters[0].info.postscriptStemSnapV)): tempArray.append( int( round( objectsBase._interpolate( ufoMasters[0].info.postscriptStemSnapV[i], ufoMasters[1].info.postscriptStemSnapV[i], interpolationFactor)))) ufoInstance.info.postscriptStemSnapV = tempArray faceFolder = makeFaceFolder(outputDirPath, faceName) ufoPath = os.path.join(faceFolder, kFontInstanceFileName) # Save UFO instance if not options.noUFOs: print '\tSaving %s file...' % kFontInstanceFileName # Delete the old UFO file, if it exists while os.path.exists(ufoPath): shutil.rmtree(ufoPath) ufoInstance.save(ufoPath) # Generate 'kern' feature if options.genKernFeature: print "\tGenerating 'kern' feature..." WriteFeaturesKernFDK.KernDataClass(ufoInstance, faceFolder, options.minKern, options.writeTrimmed, options.writeSubtables) # Generate 'mark/mkmk' features if options.genMarkFeature: if options.genMkmkFeature: print "\tGenerating 'mark' and 'mkmk' features..." else: print "\tGenerating 'mark' feature..." WriteFeaturesMarkFDK.MarkDataClass(ufoInstance, faceFolder, options.trimCasingTags, options.genMkmkFeature, options.writeClassesFile, options.indianScriptsFormat) # Decompose and remove overlaps (using checkoutlines) if options.flatten: print '\tFlattening the glyphs...' if os.name == "nt": coTool = 'checkoutlines.cmd' else: coTool = 'checkoutlines' cmd = '%s -e "%s"' % (coTool, ufoPath) popen = Popen(cmd, shell=True, stdout=PIPE) popenout, popenerr = popen.communicate() if options.verboseMode: if popenout: print popenout if popenerr: print popenerr # Autohint if options.autohint: print '\tHinting the font...' cmd = 'autohint -q "%s"' % ufoPath popen = Popen(cmd, shell=True, stdout=PIPE) popenout, popenerr = popen.communicate() if options.verboseMode: if popenout: print popenout if popenerr: print popenerr
font1 = SelectFont("Select font 1") font2 = SelectFont("Select font 2") where = GetFolder("Select a folder to save the interpolations") instances = [ ("Light", 0), ("NotTooLight", 0.25), ("Regular", 0.5), ("Demi", 0.75), ("Medium", 1), ] for thing in instances: name, value = thing print "generating", name, value dst = NewFont() # this interpolates the glyphs dst.interpolate(value, font1, font2, doProgress=True) # this interpolates the kerning # comment this line out of you're just testing #dst.kerning.interpolate(font1.kerning, font2.kerning, value) dst.info.familyName = "MyBigFamily" dst.info.styleName = name dst.info.autoNaming() dst.update() fileName = dst.info.familyName + "-" + dst.info.styleName + ".vfb" path = os.path.join(where, fileName) print 'saving at', path dst.save(path) dst.close()
# robothon 2006 # batch interpolate import os from robofab.world import SelectFont, NewFont # ask for two masters to interpolate: font1 = SelectFont("Select font 1") font2 = SelectFont("Select font 2") # these are the interpolation factors: values = [.3, .6] for value in values: # make a new font destination = NewFont() # do the interpolation destination.interpolate(value, font1, font2, doProgress=True) destination.update() # make a new path + filename for the new font to be saved at: dir = os.path.dirname(font1.path) fileName = "Demo_%d.vfb" % (1000 * value) # save at this path and close the font destination.save(os.path.join(dir, fileName)) destination.close()
# robothon06 # interpolate two fonts from robofab.world import SelectFont, NewFont from robofab.interface.all.dialogs import AskString font1 = SelectFont("Select font 1") font2 = SelectFont("Select font 2") value = AskString("What percentage?") value = int(value) * .01 destination = NewFont() # this interpolates the glyphs destination.interpolate(value, font1, font2, doProgress=True) # this interpolates the kerning # comment this line out of you're just testing destination.kerning.interpolate(font1.kerning, font2.kerning, value) destination.update()