def getFontsNGlyphs(): source = SelectFont("Select origin font:", "Copy glyphs") destination = SelectFont("Select destination font:", "Copy glyphs") if CurrentFont().selection: copySet = CurrentFont().selection else: copySet = AskString("Enter glyph names:").split() if not copySet: print("☹️ No glyphs selected!") return [source, destination, copySet]
def setMarkColor(): userColor = AskString("Mark copied glyphs as r, g, or b?", "g") if userColor == "r": markColor = (1, .45, .45, .75) elif userColor == "g": markColor = (.45, 1, .55, .75) elif userColor == "b": markColor = (.45, .73, 1, .75) else: markColor = (1*random.random(), 1*random.random(), 1*random.random(), 0.5) print("no color set; using rgba" + str(markColor)) return markColor
# menutitle: Set Glyph Color in All Open Fonts # shortcut: shift+command+control+c from vanilla.dialogs import * import os from mojo.UI import AskString hexColor = AskString('Hex color, e.g. "2F3137" or "#9560FF"') f = CurrentFont() fonts = AllFonts() glyphsToUpdate = list(f.selectedGlyphNames) def RGBAfromHex(hex): h = hex.lstrip('#') RGB = tuple(int(h[i:i + 2], 16) for i in (0, 2, 4)) r1, g1, b1, a1 = RGB[0] / 255, RGB[1] / 255, RGB[2] / 255, 1 return (r1, g1, b1, a1) rgbaColor = RGBAfromHex(hexColor) for font in fonts: for glyphName in glyphsToUpdate: font[glyphName].markColor = rgbaColor
''' Decompose named glyph in selected fonts ''' from mojo.UI import AskString from vanilla.dialogs import * glyphsToDecompose = AskString('Glyph to decompose').split(' ') files = getFile("Select files to decompose glyph in", allowsMultipleSelection=True, fileTypes=["ufo"]) for file in files: font = OpenFont(file, showInterface=False) print("\n", font.info.styleName) for glyphName in glyphsToDecompose: if glyphName in font.keys(): font[glyphName].decompose() print(f"{glyphName} decomposed") else: print(f"{glyphName} not in font") font.save() font.close()
''' For selected fonts, make a space-separated list of suffixed glyphs into defaults, replacing the suffixed versions to with copies ''' from vanilla.dialogs import * import os from mojo.UI import AskString import datetime files = getFile("Select files to update", allowsMultipleSelection=True, fileTypes=["ufo"]) # get currently selected glyphs as a list glyphsToMakeDefault = AskString( 'Space-separated list of glyphs to make default').split(" ") # if the user cancels or inputs an empty string, cancel the script if glyphsToMakeDefault == "": print("canceled") # if the script is valid, keep going else: for file in files: f = OpenFont(file) for altGlyph in glyphsToMakeDefault: splitAltGlyphName = f[altGlyph].name.split('.') # check that selected glyph if len(splitAltGlyphName) == 2:
from vanilla.dialogs import * from mojo.UI import AskString from fontTools.designspaceLib import DesignSpaceDocument """ Remove glyphs from designspace rules 2019_11_28 Benedikt Bramboeck, Alphabet heavily based on https://github.com/arrowtype/varfont-prep/blob/master/remove-list-of-glyphs.py """ glyphsToDelete = AskString( 'Input glyphnames to remove, then select designspace').replace( "'", "").replace(",", "").split(" ") instruction = f"select designspace to remove {glyphsToDelete} from" docPath = getFile(instruction, allowsMultipleSelection=False, fileTypes=["designspace"]) doc = DesignSpaceDocument() doc.read(*docPath) for gName in glyphsToDelete: for rule in doc.rules: newSubs = [] for sub in rule.subs: if gName not in sub: newSubs.append(sub) rule.subs = newSubs doc.write(*docPath)
import pprint # TODO: ignore glyphs marked as "experimental" with robofont marx # TODO: allow user to paste space-separated string of glyphs to limit check to ### SET THIS TO IGNORE GLYPHS YOU WANT TO LEAVE ALONE (e.g. experimental glyphs) ### glyphsToIgnore = "L.noserif Z.noserif .contrast-circles ampersand.code_experimental ampersand.code_experimental_2 ampersand.code_experimental_3 ampersand.crossbar at.monolinear at.replaced_with_prop at.short braceleft.asymmetrical dagger.daggery dollar.lower g.compact_desc g.extra g.ss01 hyphen.simple one.flatflag r.simple_italic zero.ss01 y.longtail two.replaced_with_rounder sterling.replaced_with_flat onehalf.v1 l.ss01 R.trap a.italic_curl ampersand_ampersand.code at.prop at.simple braceright.asymmetrical divisionslash.copy_1 exclam.copy_1 g.long_desc g.longtail i.ss01 j.longtail fi fj fl fl.mono" # save these soon: fi fj fl fl.mono #################################################################################### debug = False # will print full dictionaries widthUnit = AskString('Width unit to check for (e.g. 600, 50, 10)') files = getFile(f"Select files to check glyph widths for units of {widthUnit}", allowsMultipleSelection=True, fileTypes=["ufo"]) fonts = [] widthsDict = {} badWidthGlyphs = {} OutputWindow().show() OutputWindow().clear() print("\nCOMPATIBILITY CHECK: GLYPH CONSISTENCY & WIDTHS\n\n") print("""\
from mojo.UI import AskString import math f = CurrentFont() af = AllFonts() # glyphName = CurrentGlyph().name glyphName = AskString('Glyph to duplex / multiplex / superplex') width = int(AskString('Glyph width')) for f in af: print("----------------------------------") print(f.info.styleName) g = f[glyphName] g.width = width totalMargin = g.leftMargin + g.rightMargin print(totalMargin) g.leftMargin = totalMargin / 2 g.rightMargin = totalMargin / 2 g.width = width
import os from mojo.UI import AskString from vanilla.dialogs import * # copy-paste to fill this list with whatever glyphs fontMake flags as not being interpolatable # glyphsToDelete = ['LISTOFGLYPHSHERE'] glyphsToRemove = AskString( 'Input glyphnames to remove, then select UFOs').replace("'", "").replace(",", "").split(" ") # help(CurrentFont().removeGlyph()) instruction = f"select masters to remove {glyphsToRemove} from" inputFonts = getFile( instruction, allowsMultipleSelection=True, fileTypes=["ufo"]) # copy space-separated glyph names here # glyphsToRemove = list(f.selectedGlyphNames) def removeGlyphs(glyphsToRemove,f): # LAYERS -------------------------------------------------- for layerName in f.layerOrder: layer = f.getLayer(layerName) for glyphToRemove in glyphsToRemove: if glyphToRemove in layer: del layer[glyphToRemove] # else: # print("%s does not contain a glyph named '%s'" %
''' from vanilla.dialogs import * import os from mojo.UI import AskString files = getFile("Select files to update", allowsMultipleSelection=True, fileTypes=["ufo"]) # get the current font # f = CurrentFont() # ask user for a suffix to add to duplicated glyphs newGlyphSuffix = AskString( 'Enter a new suffix for duplicate glyphs, e.g. "alt1"') # get currently selected glyphs as a list glyphsToCopy = AskString( 'Space-separated list of glyphs to copy with suffix').split(" ") # if the user cancels or inputs an empty string, cancel the script if newGlyphSuffix == "" or glyphsToCopy == "": print("canceled") # if the script is valid, keep going else: for file in files: f = OpenFont(file) # loop through list of selected glyphs for glyph in glyphsToCopy:
for all open fonts, duplicate selected glyph & add suffix ''' # TODO: move *ALL* layers of the glyph move. Currently, this only moves the glyph in the foreground/default layer. # import AskString from robofont's mojo UI library from mojo.UI import AskString # get the current font f = CurrentFont() # get currently selected glyphs as a list glyphsToCopy = f.selectedGlyphNames # ask user for a suffix to add to duplicated glyphs newGlyphSuffix = AskString( 'Enter a new suffix for duplicate glyphs, e.g. "alt1"') # if the user cancels or inputs an empty string, cancel the script if newGlyphSuffix == "": print("canceled") # if the script is valid, keep going else: # loop through list of selected glyphs for glyph in glyphsToCopy: for f in AllFonts(): # get the base name of the glyph (before the period) baseNameOfGlyph = glyph.split('.')[0] # form the new glyph name
from vanilla.dialogs import * import os from mojo.UI import AskString layerName = AskString('Layer to adjust color of, e.g. "background"') hexColor = AskString('Hex color, e.g. "2F3137" or "#9560FF"') files = getFile("Select files to update", allowsMultipleSelection=True, fileTypes=["ufo"]) def RGBAfromHex(hex): h = hex.lstrip('#') RGB = tuple(int(h[i:i + 2], 16) for i in (0, 2, 4)) r1, g1, b1, a1 = RGB[0] / 255, RGB[1] / 255, RGB[2] / 255, 1 return (r1, g1, b1, a1) for file in files: font = OpenFont(file) rgbaColor = RGBAfromHex(hexColor) font.getLayer(layerName).color = rgbaColor print(font) print(f'{layerName} color updated to {rgbaColor}') font.save() font.close()
from vanilla.dialogs import * import os from mojo.UI import AskString newLayer = AskString('Layer to copy selected glyphs to, e.g. "overlap"') files = getFile("Select files to update", allowsMultipleSelection=True, fileTypes=["ufo"]) font = CurrentFont() glyphsToCopyToNewLayer = font.selectedGlyphNames for file in files: font = OpenFont(file) for name in glyphsToCopyToNewLayer: font[name].layers[0].copyLayerToLayer("foreground", newLayer) font[name].layers[-1].width = font[name].layers[0].width print( f"Glyphs copied to {newLayer}! Please save font to keep changes.")
from mojo.UI import AskString from vanilla.dialogs import * spaceWidth = int(AskString('Width to set glyph /space to (e.g. 300)')) files = getFile("Select files to check for character set similarity", allowsMultipleSelection=True, fileTypes=["ufo"]) for file in files: f = OpenFont(file, showInterface=False) if f['space'].width != spaceWidth: f['space'].width = spaceWidth print("/space width set to ", spaceWidth) f.save() f.close()
''' Glyph Bezier Tweener - Work in Progress Will animate between glyph beziers to show variable interpolation. This must be used within the Drawbot extension for RoboFont. ''' from datetime import datetime from vanilla.dialogs import * from mojo.UI import AskString timestamp = datetime.now().strftime("%Y_%m_%d") glyphToAnimate = AskString('Enter glyph name to animate') startFont = getFile("Select file to start animation from", allowsMultipleSelection=False, fileTypes=["ufo"]) endFont = getFile("Select file to end animation at", allowsMultipleSelection=False, fileTypes=["ufo"]) # settings glyphScale = 0.8 canvasWidth = 650 canvasHeight = 900 captionSize = 14 def hex2rgb(hex):
from vanilla.dialogs import * import os from mojo.UI import AskString glyphsToRemoveString = AskString( 'space-separated list of glyphs to remove from current font') glyphsToRemove = glyphsToRemoveString.split(" ") f = CurrentFont() # copy space-separated glyph names here # glyphsToRemove = list(f.selectedGlyphNames) # FONT KEYs ----------------------------------------------- # clean up the rest of the data for glyphName in glyphsToRemove: # remove from keys # if glyphToRemove in f.keys(): if glyphName in f: del f[glyphName] else: print("font does not contain a glyph named '%s'" % glyphName) # LAYERS -------------------------------------------------- for layerName in f.layerOrder: layer = f.getLayer(layerName) for glyphToRemove in glyphsToRemove: if glyphToRemove in layer: del layer[glyphToRemove]
from vanilla.dialogs import * import os from mojo.UI import AskString files = getFile("Select files to update", allowsMultipleSelection=True, fileTypes=["ufo"]) newLayer = AskString('Layer to copy all existing glyphs to, e.g. "overlap"') for file in files: font = OpenFont(file) for glyph in font: glyph.layers[0].copyLayerToLayer("foreground", newLayer) # font.save() # font.close() print(f"Glyphs copied to {newLayer}! Please save font to keep changes.")
# menuTitle : Glyphs to Wordmark ''' Compiles a glyph consisting of components of letters in the string you provide. Ryan Bugden 2019.03.31 ''' from mojo.UI import AskString f = CurrentFont() new_g_name = AskString('What word would you like to compose?', value='', title='New wordmark') # If the glyph exists, it removes it. try: f[new_g_name] f.removeGlyph(new_g_name) except ValueError: pass # Create the glyph f.newGlyph(new_g_name) g = f[new_g_name] cursor = 0 # Add each letter of the string to the glyph as a component for letter in new_g_name:
''' For selected fonts, make a space-separated list of suffixed glyphs into defaults, replacing the suffixed versions to with copies ''' from vanilla.dialogs import * import os from mojo.UI import AskString import datetime glyphsToMakeDefault = AskString( 'Space-separated list of glyphs to make default').split(" ") suffixToImpose = AskString( 'suffix you want on the glyphs (e.g. italic, mono, etc)') files = getFile("Select files to update", allowsMultipleSelection=True, fileTypes=["ufo"]) # if the user cancels or inputs an empty string, cancel the script if glyphsToMakeDefault == "": print("canceled") # if the script is valid, keep going else: for file in files: f = OpenFont(file) for altGlyph in glyphsToMakeDefault: if altGlyph in f.keys():
''' For selected fonts, change name of single glyph ''' from vanilla.dialogs import * import os from mojo.UI import AskString files = getFile("Select files to update", allowsMultipleSelection=True, fileTypes=["ufo"]) # get currently selected glyphs as a list oldName = AskString('name of glyph to update (only one)').split(" ") newName = AskString('new name for glyph').split(" ") # if the user cancels or inputs an empty string, cancel the script if len(oldName) > 1 or len(newName) > 1: print("Error: enter only one glyph and one new name") print("\t oldName: ", oldName) print("\t newName: ", newName) # if the script is valid, keep going else: for file in files: font = OpenFont(file, showInterface=False) if oldName[0] in font.keys(): font.renameGlyph(oldName[0], newName[0], renameComponents=True,