def scaleNums(): question = "Is your num height " + str( currentNumHeight) + "?" + " If not, please enter it:" customNumHeight = AskString(question, currentNumHeight, "Current Numeral Height") customNumHeight = int(float(customNumHeight.upper())) yesNoQuestion = "This will scale all your numerals to " + str( targetNumHeight) + ". " + "Continue?" confirmScale = AskYesNoCancel(yesNoQuestion, title='Just Checking...', default=0) print confirmScale numScale = targetNumHeight / customNumHeight if confirmScale == 1: for g in f: if customNumHeight != targetNumHeight: g.prepareUndo() if g.name in numerals: g.selected = True print "scaled ", g.name, " to ", targetNumHeight g.scale(numScale) g.width = g.width * numScale g.update() g.performUndo()
def renameFont(font): family = AskString('New font family name:') font.family_name = family font.full_name = font.family_name font.font_name = font.family_name font.menu_name = font.family_name font.apple_name = font.family_name return font
def addDelButtons(self, sender): try: # If it's an add button, ask for its name, and add an instance # if it's a delete button, give a warning, and delete the instance uiList = self.w.list if sender == self.w.add: newInstance = GSInstance() newInsName = AskString("Please name the new instance.", title="Creating New Instance") newInstance.active = True newInstance.name = newInsName newInstance.weightValue = weMin newInstance.widthValue = wiMin newInstance.customValue = csMin newInstance.isItalic = False newInstance.isBold = False font.addInstance_(newInstance) insList.append({ "Instance": "%s %s" % (font.familyName, newInsName), "Weight": weMin, "Width": wiMin, "Custom": csMin, "WeightY": None }) uiList.append({ "Instance": "%s %s" % (font.familyName, newInsName), "Weight": weMin, "Width": wiMin, "Custom": csMin, "WeightY": None }) elif sender == self.w.delete: if askYesNo( "Deleting Instance", 'Are you sure you want to delete the selected instance?', alertStyle=1, parentWindow=None, resultCallback=None): index = uiList.getSelection()[0] font.removeInstanceAtIndex_(index) del insList[index] del uiList[index] else: pass except Exception, e: Glyphs.showMacroWindow() print "Instance Slider Error (addDelButtons): %s" % e
def getNumber(message, allowZeroOrLess): userInput = AskString(message) if userInput is not None: try: int(userInput) except ValueError: userInput = getNumber('Please enter a number', allowZeroOrLess) if (userInput <= 0) and (allowZeroOrLess == 0): userInput = getNumber('Please enter a number greater than 0', 0) return int(userInput)
def optionTasks( self, sender ): # variety of stuff tabs[0].option has to do try: favNameList = self.favNameList() index = sender.get() global lastIndex emptyList = [{" ":"1", "Left":"", "Right":"", "Add Flipped":False, "Pair Count":0}] if not "lastIndex" in globals(): # only the case with first access lastIndex = 8 if index == 1: # New Set self.w.tabs[0].permList.set(emptyList) self.refreshSectionPreview(0) self.w.tabs[0].options.set(0) elif index == 2: # Save Set in Favourites lastName = favNameList[lastIndex-8] self.SavePreferences(lastName, False) # deleteBool = False self.w.tabs[0].options.set(lastIndex) elif index == 3: # Save Set in Favourites As... newName = AskString("Save As:", title="Save Pair List") if newName == "": #exists already or empty, or None: self.w.tabs[0].options.set(lastIndex) elif newName in favDic: Glyphs.displayDialog_("A set with the same name already exists.") self.w.tabs[0].options.set(lastIndex) else: self.SavePreferences(newName, False) # deleteBool = False self.refreshOptions() favNameList = self.favNameList() self.w.tabs[0].options.set(favNameList.index(newName)+8) elif index == 4: # Delete Set from Favourites... lastName = favNameList[lastIndex-8] if len(favNameList)==1: Glyphs.displayDialog_("Actually, you can't empty the Favourites list.\nSorry for my incompetent coding.") else: if askYesNo(messageText='Are you sure you want to delete "%s"?' % lastName, alertStyle=1,) == 1: self.SavePreferences(lastName, True) # deleteBool = True self.refreshOptions() self.w.tabs[0].permList.set(emptyList) self.w.tabs[0].options.set(0) else: self.w.tabs[0].options.set(lastIndex) elif index == 5: # Copy Set As Flat Text self.BubbleKernMain(sender) self.w.tabs[0].options.set(lastIndex) elif index >= 8: # if one of Favourites lastIndex = index self.favDicToList(favNameList[index-8]) except Exception, e: Glyphs.showMacroWindow() print "BubbleKern Error (optionTasks): %s" % e
def switch(): anchor = int( AskString("1:top, 2:bottom, 3:center, 4:topleft, 5:topright, 6:all")) def top(): for a in layer.anchors: a.selected = False layer.anchors["top"].selected = True def bottom(): for a in layer.anchors: a.selected = False layer.anchors["bottom"].selected = True def center(): for a in layer.anchors: a.selected = False layer.anchors["center"].selected = True def topleft(): for a in layer.anchors: a.selected = False layer.anchors["topleft"].selected = True def topright(): for a in layer.anchors: a.selected = False layer.anchors["topright"].selected = True def total(): for a in layer.anchors: a.selected = True def default(): Message("Invalid option") dict = { 1: top, 2: bottom, 3: center, 4: topleft, 5: topright, 6: total, } dict.get(anchor, default)()
def addDelButtons(self, sender): try: # If it's an add button, ask for its name, and add an instance # if it's a delete button, give a warning, and delete the instance uiList = self.w.list values = [int((v[1] + v[2]) / 2) for v in av] if sender == self.w.add: newInstance = GSInstance() newInsName = AskString("Please name the new instance.", title="Creating New Instance") newInstance.active = True newInstance.name = newInsName newInstance.isItalic = False newInstance.isBold = False f.addInstance_(newInstance) newInstance.axes = values newInsParameters = { "Instance": "%s %s" % (f.familyName, newInsName), "WeightY": None } for i in range(len(self.usedAxisElements)): newInsParameters[self.usedAxisElements[i][0].get()] = int( (av[i][1] + av[i][2]) / 2) insList.append(newInsParameters) uiList.append(newInsParameters) elif sender == self.w.delete: if askYesNo( "Deleting Instance", 'Are you sure you want to delete the selected instance?', alertStyle=1, parentWindow=None, resultCallback=None): index = uiList.getSelection()[0] f.removeInstance_ f.removeInstanceAtIndex_(index) del insList[index] del uiList[index] else: pass except Exception as e: Glyphs.showMacroWindow() print("Instance Slider Error (addDelButtons): %s" % e)
#Program font = CurrentFont() overwrite = TwoChecks('Ask to overwrite glyphs', 'Overwrite, do not ask', value1=0, value2=0) whatToBuild = TwoChecks('Cap accents in font?', 'Small Caps in font?', value1=0, value2=0) buildSmallCap = 0 if whatToBuild == 0: upperCaseList = baseUpperCaseList if whatToBuild == 1: suffix = AskString('Suffix for cap accents') upperCaseList = rewriteAccentNames(baseUpperCaseList, suffix) if whatToBuild == 2: scAccentSuffix = '' upperCaseList = baseUpperCaseList buildSmallCap = 1 scAccentSuffix = '' scSuffix = AskString('Suffix for small caps?') specialSmallCapAccents = AskYesNoCancel('Special small cap accents?') if specialSmallCapAccents == 1: scAccentSuffix = AskString('Suffix for small cap accents', scSuffix) smallCapList = rewriteSmallCapList(baseUpperCaseList, scSuffix, scAccentSuffix) if whatToBuild == 3: buildSmallCap = 1 scAccentSuffix = ''
# 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()
from mojo.drawingTools import * from robofab.interface.all.dialogs import AskString from robofab.interface.all.dialogs import AskYesNoCancel f = CurrentFont() uppercase = [] numerals = [ 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine' ] for letter in string.uppercase: uppercase += letter targetCapHeight = AskString("Enter your target height for caps and numerals:", "", "Target Cap Height") targetCapHeight = int(float(targetCapHeight.upper())) currentCapHeight = f.info.capHeight def getNumHeight(numeralToCheckHeight): for g in f: if g.name == numeralToCheckHeight: for counter in g: currentNumHeight = counter.points[0].y print "currentNumHeight is ", currentNumHeight return currentNumHeight targetNumHeight = targetCapHeight
from robofab.interface.all.dialogs import AskString, Message font = CurrentFont() text = AskString("A height") try: height = int(text) except: Message("Hey! A number please!") for name in font.selection: glyph = font[name] center = glyph.width/2 glyph.appendAnchor('_top', (center,height))
from robofab.interface.all.dialogs import AskString, Message font = CurrentFont() minGlyph = AskString("Min Glyph") maxGlyph = AskString("Max Glyph") steps = AskString("How many?") try: steps = int(steps) except: Message("Number please!") for n in range(1, steps, 1): name = "test." + str(n) n = n / 10 glyph = font.newGlyph(name) glyph.interpolate(n, font[minGlyph], font[maxGlyph]) glyph.mark = (1, 0, 0, 1)
from robofab.interface.all.dialogs import AskString, Message f = CurrentFont() currentEm = f.info.ascender + -f.info.descender #Total measurement from ascender to descender newEm = AskString("Target height (ascender to descender)", title="Scale-a-mucci") #Returns message when input is blank if newEm == None: Message("You're fired!") else: try: #Convert input string to integers & calculate scale xFactor = int(newEm) / currentEm #Decompose every glyph first (in case of component-based font) for glyph in f: glyph.decompose() #Scale & tans every glyph for glyph in f: glyph.width *= xFactor glyph.scale((xFactor)) glyph.mark = (0.69, 0.43, 0.18, 1) #Modify vertical metrics to new dimensions f.info.ascender *= xFactor f.info.capHeight *= xFactor
axisTypesInOrder = [] numberOfAxis = 0 if fl.count == 0: Message('A MM Font needs to be open to run this macro') else: fontMM = fl.font #the MM Font if fontMM[0].layers_number == 1: Message('This Font does not have a MM axis') else: #Get the family name family = AskString('Family Name') if family is None: family = AskString('Please enter a Family Name') #Get number of axis numberOfAxis = math.log(fontMM[0].layers_number, 2) numberOfAxis = int(numberOfAxis) #Get the axis info if numberOfAxis >= 1: firstAxisType = OneList(axisTypes, 'What type is the first axis?') if firstAxisType is not None: axisTypes.remove(firstAxisType) axisInFont[firstAxisType] = getInstances(firstAxisType) axisTypesInOrder.append(firstAxisType)
import GlyphsApp from robofab.interface.all.dialogs import AskString import time Glyphs.clearLog() print "Shift background in selected glyphs @ " + time.strftime("%H:%M:%S") def is_a_number(number): try: float(number) return True except ValueError: return False shift = AskString("Shift background content in (number as units)") if not is_a_number(shift): Glyphs.showMacroWindow() print "Error: Not a number" else: shift = float(shift) thisFont = Glyphs.font listOfSelectedLayers = thisFont.selectedLayers thisFont.disableUpdateInterface() for thisLayer in listOfSelectedLayers: for comp in thisLayer.background.components: pos = comp.position pos.x = pos.x + shift comp.position = pos for path in thisLayer.background.paths: for node in path.nodes:
import GlyphsApp from robofab.interface.all.dialogs import AskString import time Glyphs.clearLog() print "Scale background in selected glyphs @ " + time.strftime("%H:%M:%S") def is_a_number(number): try: float(number) return True except ValueError: return False scale = AskString("Scale background content in (number as percentage)") if not is_a_number(scale): Glyphs.showMacroWindow() print "Error: Not a number" else: scale = float(scale) * 0.01 thisFont = Glyphs.font listOfSelectedLayers = thisFont.selectedLayers thisFont.disableUpdateInterface() for thisLayer in listOfSelectedLayers: for path in thisLayer.background.paths: for node in path.nodes: pos = node.position pos.x = pos.x * scale pos.y = pos.y * scale node.position = pos
try: from robofab.interface.all.dialogs import AskString, Message except: from fontParts.ui import AskString, Message font = CurrentFont() width_text = AskString("What width?") try: width = int(width_text) except: Message("A number, come on!") for glyph in font: if glyph.isEmpty(): glyph.width = width elif glyph.width < width: dif = width - glyph.width glyph.leftMargin += dif / 2 glyph.rightMargin += dif / 2 elif glyph.width > width: f = width / glyph.width glyph.scale((f, 1)) gw = glyph.box[2] - glyph.box[0] dif = width - gw glyph.leftMargin = dif / 2 glyph.rightMargin = dif / 2 else: pass
from robofab.world import CurrentFont,CurrentGlyph from robofab.interface.all.dialogs import Message, ProgressBar, AskYesNoCancel, TwoChecks, AskString import string #Program def check(font,name): result = False for g in font.glyphs: if g.name == name: result = True return result font = CurrentFont() cglyph = CurrentGlyph() sb = AskString('SB values') values = sb.split(',') if check(font,values[0]): valueL=font[values[0]].leftMargin else: valueL = cglyph.leftMargin if check(font,values[1]): valueR=font[values[1]].rightMargin else: valueL = cglyph.rightMargin if valueL == 0: valueL = cglyph.leftMargin
#MenuTitle: Note for Selection # ################################################################### # # adds a note to all selected characters # # --> let me know if you have ideas for improving # --> Mark Froemberg aka DeutschMark @ GitHub <-- # # ToDo: - # # ################################################################### Glyphs.clearLog() from robofab.interface.all.dialogs import AskString Note = AskString("What is your Note for the Selected Glyphs?") Doc = Glyphs.currentDocument Font = Glyphs.font selectedGlyphs = [x.parent for x in Font.selectedLayers] def process(thisGlyph): thisGlyph.setNote_(Note) for thisGlyph in selectedGlyphs: process(thisGlyph) print "%s -->" % thisGlyph.name, Note Glyphs.showMacroWindow()
font.info.ascender = int(round(font.info.ascender * factor)) # Finally set new UPM font.info.unitsPerEm = newUpm font.update() if __name__ == "__main__": from robofab.interface.all.dialogs import AskString print "Change Units Per Em" if CurrentFont() is not None: oldUpm = CurrentFont().info.unitsPerEm newUpm = CurrentFont().info.unitsPerEm try: newUpm = int(AskString("New units per em size?", oldUpm)) except: pass if newUpm == oldUpm: print " Not changing upm size." else: factor = float(newUpm) / oldUpm print " Scaling all font measurements by", factor changeUPM(CurrentFont(), factor) else: print " Open a font first to change upm, please." print " Done."
# import the robofab dialog to ask user for a value from robofab.interface.all.dialogs import AskString # import the robofab dialog to confirm yes/no/cancel from robofab.interface.all.dialogs import AskYesNoCancel # grab current font f = CurrentFont() ## get the glyphs you have selected as a list glyphSelection = f.selection # just to check that it's working print glyphSelection # Allow user to set a skew value skewValue = AskString("Please enter the horizontal skew you want:", "") # make the entered skew value a float (number with a decimal), because you need to for the skew function skewValue = float(skewValue) # get the font name for the upcoming dialog box fontName = f.info.familyName + " " + f.info.styleName # set up a skewing function def skewSelection(): # set up the question for a yes/no/cancel yesNoQuestion = "This will horizontall skew *all* your selected glyphs in " + fontName + " by " + str(skewValue) + " degrees. You should have a backup before any batch operation. " + "Continue?" # double check with the user before doing anything crazy confirmSkew = AskYesNoCancel(yesNoQuestion ,title='Just Checking...', default=0) # if the user answers "yes", proceed if confirmSkew == 1: ## loop through font
from robofab.interface.all.dialogs import SearchList, AskString, Message #asks for a number. if allowZeroOrLess is 0 it will not allow a number that is zero or less def getNumber(message, allowZeroOrLess): userInput = AskString(message) if userInput is not None: try: int(userInput) except ValueError: userInput = getNumber('Please enter a number', allowZeroOrLess) if (userInput <= 0) and (allowZeroOrLess == 0): userInput = getNumber('Please enter a number greater than 0', 0) return int(userInput) def getGlyphWidth(glyph): box = glyph.box width = box[2] - box[0] return width #Program font = CurrentFont() glyphs = font.selection y = getNumber('Vertical Position?', 1) name = AskString('Name of anchors') for glyph in glyphs: x = int(getGlyphWidth(font[glyph])/2) + font[glyph].leftMargin font[glyph].appendAnchor(name, (x,y)) font.update() Message('All done!')
from robofab.interface.all.dialogs import AskString, Message font = CurrentFont() change = AskString("How much?") try: change = int(change) except: Message("Number Please!") for name in font.selection: glyph = font[name] for c in glyph: for p in c.bPoints: y = p.anchor[1] if y < -15: p.move((0, -change)) glyph.update()
Finds and selects small paths (smaller than a user-definable area) in the current glyph. """ import GlyphsApp, time from robofab.interface.all.dialogs import AskString Glyphs.clearLog() print("Select small paths @ " + time.strftime("%H:%M:%S")) def is_a_number(number): try: float(number) return True except ValueError: return False minArea = AskString("Select paths with an area smaller than (in square units)") if not is_a_number(minArea): Glyphs.showMacroWindow() print("Error: Not a number") else: minArea = float(minArea) pathCounter = 0 thisFont = Glyphs.font currentLayer = thisFont.selectedLayers[0] thisFont.disableUpdateInterface() currentLayer.clearSelection() currentGlyph = currentLayer.parent currentGlyph.beginUndo() for path in currentLayer.paths: if path.area() < minArea: for thisNode in path.nodes:
from robofab.interface.all.dialogs import AskYesNoCancel from robofab.interface.all.dialogs import AskString g = CurrentGlyph() f = CurrentFont() glyphsWithAscenders = ['b', 'd', 'f', 'h', 'k', 'l'] # targetAscender = 693 targetAscender = AskString("Please enter the ascender you would like:", "") targetAscender = int(float(targetAscender)) currentAscender = f.info.ascender moveAscenderBy = targetAscender - currentAscender xHeightClearance = 50 def moveAscenders(): yesNoQuestion = "This will move your ascender to " + str( targetAscender) + ". " + "Continue?" confirmScale = AskYesNoCancel(yesNoQuestion, title='Just Checking...', default=0) print confirmScale if confirmScale == 1: for g in f: g.prepareUndo() if g.name in glyphsWithAscenders: g.selected = True for contour in g: for seg in contour: