def __init__(self): col = getDefaultColor("glyphViewSelectionColor") self.glyphViewSelectionColor = (col.redComponent(), col.greenComponent(), col.blueComponent(), col.alphaComponent()) self.rightMarginIsSelected = False self.leftMarginIsSelected = False self.glyph = None self.font = None self.mousePoint = None self.mouseDelta = None self.deltaX = 0 self.threshold = 5 self.increment = 1 self.glyphViewShiftIncrement = getDefault("glyphViewShiftIncrement") self.glyphViewCommandShiftIncrement = getDefault( "glyphViewCommandShiftIncrement") self.shiftDown = False self.commandDown = False addObserver(self, 'mouseDragged', 'mouseDragged') addObserver(self, 'mouseUp', 'mouseUp') addObserver(self, 'mouseDown', 'mouseDown') addObserver(self, 'keyDown', 'keyDown') addObserver(self, 'modifiersChanged', 'modifiersChanged') addObserver(self, 'draw', 'draw') addObserver(self, 'viewDidChangeGlyph', 'viewDidChangeGlyph')
def __init__(self): addObserver(self, "drawMetricsBox", "drawBackground") self.color = getDefault("glyphViewMarginColor") self.height = getDefault("glyphViewDefaultHeight") / 2 self.useItalicAngle = getDefault("glyphViewShouldUseItalicAngleForDisplay")
def _turnOn(self): pass pref_as_is = getDefault('glyphZoomViewShowItems') pref_new = dict() for i in getDefault('glyphZoomViewShowItems'): if i in turnOnItems: pref_new[i] = 1 else: pass setDefault('glyphZoomViewShowItems', pref_new) preferencesChanged()
def get_glyphs(font): # current_glyph=True, font_selection=True, """ Return current glyph selection in the font as glyph names or ``RGlyph`` objects. """ # get glyphs current_glyph = CurrentGlyph() font_selection = font.selection # get RoboFont's window mode single_window = [False, True][getDefault("singleWindowMode")] # handle multi-window mode glyphs = [] if not single_window: if current_glyph is not None: glyphs += [current_glyph.name] else: glyphs += font_selection # multi-window: return else: if current_glyph is not None: glyphs += [current_glyph.name] glyphs += font_selection else: glyphs += font_selection # done return list(set(glyphs))
def checkSyntax(self, sender=None): # get the code code = self.code() # get te path of the document (will be None for an untitled document) path = self.path() # when enabled clear the output text view if getDefault("PyDEClearOutput", True): self.outPutView.set("") # create a new std output, catching all print statements and tracebacks self.output = [] self.stdout = StdOutput(self.output) self.stderr = StdOutput(self.output, True) # run the code, but with the optional flag checkSyntaxOnly so it will just compile the code ScriptRunner(code, path, stdout=self.stdout, stderr=self.stderr, checkSyntaxOnly=True) # set the catched print statements and tracebacks in the the output text view for text, isError in self.output: self.outPutView.append(text, isError) # clean up self.output = None self.stdout = None self.stderr = None
def runCode(self, liveCoding=False): # get the code code = self.code() # save the code in the defaults, if something goes wrong setDefault("pythonCodeBackup", code) # get te path of the document (will be None for an untitled document) path = self.path() # reset the internal warning system warnings.resetWarnings() # reset the drawing tool _drawBotDrawingTool.newDrawing() # create a namespace namespace = DrawBotNamespace(_drawBotDrawingTool, _drawBotDrawingTool._magicVariables) # add the tool callbacks in the name space _drawBotDrawingTool._addToNamespace(namespace) # when enabled clear the output text view if getDefault("PyDEClearOutput", True): self.outPutView.clear() # create a new std output, catching all print statements and tracebacks self.output = [] self.stdout = StdOutput(self.output) self.stderr = StdOutput(self.output, True) # warnings should show the warnings warnings.shouldShowWarnings = True # run the code ScriptRunner(code, path, namespace=namespace, stdout=self.stdout, stderr=self.stderr) # warnings should stop posting them warnings.shouldShowWarnings = False # set context, only when the panes are visible if self.w.split.isPaneVisible("drawView") or self.w.split.isPaneVisible("thumbnails"): def createContext(context): # draw the tool in to the context _drawBotDrawingTool._drawInContext(context) # create a context to draw in context = DrawBotContext() # savely run the callback and track all traceback back the the output CallbackRunner(createContext, stdout=self.stdout, stderr=self.stderr, args=[context]) # get the pdf document and set in the draw view pdfDocument = context.getNSPDFDocument() if not liveCoding or (pdfDocument and pdfDocument.pageCount()): self.drawView.setPDFDocument(pdfDocument) # scroll down self.drawView.scrollDown() else: # if the panes are not visible, clear the draw view self.drawView.setPDFDocument(None) # set the catched print statements and tracebacks in the the output text view for text, isError in self.output: if liveCoding and isError: continue self.outPutView.append(text, isError) # reset the code backup if the script runs with any crashes setDefault("pythonCodeBackup", None) # clean up self.output = None self.stdout = None self.stderr = None
def getGlyphReport(font, glyph, options): #start = time() options["grid_length"] = getDefault('glyphViewRoundValues') myPen = OutlineTestPen(font, options) glyph.drawPoints(myPen) #stop = time() #print("updateOutlineCheck in %0.2f ms." % ((stop-start) * 1000)) return myPen.errors
def getGlyphReport(font, glyph, options): #start = time() options["grid_length"] = getDefault('glyphViewRoundValues') myPen = OutlineTestPen(font, options) glyph.drawPoints(myPen) #stop = time() #print "updateOutlineCheck in %0.2f ms." % ((stop-start) * 1000) return myPen.errors
def _turnOff(self): pref_as_is = getDefault('glyphZoomViewShowItems') setExtensionDefault('restoreGlyphZoomViewShowItems', pref_as_is) pref_new = dict() for i in pref_as_is: if i in turnOffItems: pref_new[i] = 0 else: pref_new[i] = pref_as_is[i] setDefault('glyphZoomViewShowItems', pref_new) preferencesChanged()
def restoreGlyphViewItems(self): pref_as_is = getDefault('glyphZoomViewShowItems') pref_new = dict() for i in pref_as_is: if i in turnOffItems: # global gridWasOn # gridWasOn = pref_as_is[i] pref_new[i] = 1 else: pref_new[i] = pref_as_is[i] setDefault('glyphZoomViewShowItems', pref_new) PostNotification("doodle.preferencesChanged")
def runCode(self): self._errorView.set("") if not self._code: return self._drawingTools._reset() if getDefault("PyDEClearOutput", True): self._errorView.clear() self.stdout = Output(self._errorView) self.stderr = Output(self._errorView, True) path = self.getPath() namespace = dict() for name in self._drawingTools.__all__: namespace[name] = getattr(self._drawingTools, name) ScriptRunner(text=self._code, path=path, stdout=self.stdout, stderr=self.stderr, namespace=namespace)
def getColorTheme(): try: tokens = dict(getDefault("PyDETokenColors")) except: tokens = {} print('no custom colors defined.\n') background = getDefaultColor("PyDEbackgroundColor") highlight = getDefaultColor("PyDEHightLightColor") return { 'background': background, 'highlight': highlight, 'tokens': tokens, }
def runCode(self, sender=None): code = self.codeEditor.get() container = self.merzView.getMerzContainer() container.clearSublayers() namespace = dict(container=container, merz=merz) if getDefault("PyDEClearOutput", True): self.outputEditor.clear() self.output = [] self.stdout = StdOutput(self.output) self.stderr = StdOutput(self.output, True) ScriptRunner(code, "<Merz Playground>", namespace=namespace, stdout=self.stdout, stderr=self.stderr) for text, isError in self.output: self.outputEditor.append(text, isError) self.output = None self.stdout = None self.stderr = None
def saverCallback(self, sender): print("saving input text") csc = CurrentSpaceCenter() string = csc.getRaw() print("string is", string) before = getDefault("spaceCenterInputSamples") print("before is ", before) after = list(before) print("after is ", after) if string not in after: after.append(string) print("after2 is ", after) setDefault("spaceCenterInputSamples", after) print("saved input text.") else: print("did nothing.") preferencesChanged()
from __future__ import print_function, division #import outlineTestPen #reload(outlineTestPen) from outlineTestPen import OutlineTestPen from lib.tools.defaults import getDefault options = { "extremum_calculate_badness": True, "fractional_ignore_point_zero": True, "extremum_ignore_badness_below": 0, "smooth_connection_max_distance": 4, "collinear_vectors_max_distance": 2, "semi_hv_vectors_min_distance": 30, "zero_handles_max_distance": 0, "grid_length": getDefault('glyphViewRoundValues'), } def run_test(font, glyphnames): selection = [] for n in glyphnames: g = font[n] otp = OutlineTestPen(CurrentFont(), options) g.drawPoints(otp) if otp.errors: #if len(otp.errors) > 0: # g.mark = (1, 0.65, 0.6, 1) selection.append(g.name) #for e in otp.errors: # print(e) font.selection = selection
def runCode(self, liveCoding=False): # get the code code = self.code() # save the code in the defaults, if something goes wrong setDefault("pythonCodeBackup", code) # get te path of the document (will be None for an untitled document) path = self.path() # reset the internal warning system warnings.resetWarnings() # reset the drawing tool _drawBotDrawingTool.newDrawing() # create a namespace namespace = DrawBotNamespace(_drawBotDrawingTool, _drawBotDrawingTool._magicVariables) # add the tool callbacks in the name space _drawBotDrawingTool._addToNamespace(namespace) # when enabled clear the output text view if getDefault("PyDEClearOutput", True): self.outPutView.clear() # create a new std output, catching all print statements and tracebacks self.output = [] self.stdout = StdOutput(self.output) self.stderr = StdOutput(self.output, True) # warnings should show the warnings warnings.shouldShowWarnings = True # run the code ScriptRunner(code, path, namespace=namespace, stdout=self.stdout, stderr=self.stderr) # warnings should stop posting them warnings.shouldShowWarnings = False # set context, only when the panes are visible if self.w.split.isPaneVisible( "drawView") or self.w.split.isPaneVisible("thumbnails"): def createContext(context): # draw the tool in to the context _drawBotDrawingTool._drawInContext(context) # create a context to draw in context = DrawBotContext() # savely run the callback and track all traceback back the the output CallbackRunner(createContext, stdout=self.stdout, stderr=self.stderr, args=[context]) # get the pdf document and set in the draw view pdfDocument = context.getNSPDFDocument() if not liveCoding or (pdfDocument and pdfDocument.pageCount()): self.drawView.setPDFDocument(pdfDocument) # scroll down self.drawView.scrollDown() else: # if the panes are not visible, clear the draw view self.drawView.setPDFDocument(None) # set the catched print statements and tracebacks in the the output text view for text, isError in self.output: if liveCoding and isError: continue self.outPutView.append(text, isError) # reset the code backup if the script runs with any crashes setDefault("pythonCodeBackup", None) # clean up self.output = None self.stdout = None self.stderr = None
# import outlineTestPen # reload(outlineTestPen) from outlineTestPen import OutlineTestPen from lib.tools.defaults import getDefault options = { "extremum_calculate_badness": True, "fractional_ignore_point_zero": True, "extremum_ignore_badness_below": 0, "smooth_connection_max_distance": 4, "collinear_vectors_max_distance": 2, "semi_hv_vectors_min_distance": 30, "zero_handles_max_distance": 0, "grid_length": getDefault("glyphViewRoundValues"), } def run_test(font, glyphnames): selection = [] for n in glyphnames: g = font[n] otp = OutlineTestPen(CurrentFont(), options) g.drawPoints(otp) if otp.errors: # if len(otp.errors) > 0: # g.mark = (1, 0.65, 0.6, 1) selection.append(g.name) # for e in otp.errors: # print e font.selection = selection
def __init__(self): # Preferences self._drawing = getExtensionDefault(self.DEFAULTKEY_DRAW, True) self._fill = getExtensionDefault(self.DEFAULTKEY_FILL, True) self._stroke = getExtensionDefault(self.DEFAULTKEY_STROKE, True) self._points = getExtensionDefault(self.DEFAULTKEY_POINTS, True) self._fillColor = getExtensionDefaultColor(self.DEFAULTKEY_FILLCOLOR, self.FALLBACK_FILLCOLOR) self._strokeColor = getExtensionDefaultColor(self.DEFAULTKEY_STROKECOLOR, self.FALLBACK_STROKECOLOR) self._pointsColor = getExtensionDefaultColor(self.DEFAULTKEY_POINTSCOLOR, self.FALLBACK_POINTSCOLOR) self._alignment = getExtensionDefault(self.DEFAULTKEY_ALIGNMENT, 0) self._kerning = getExtensionDefault(self.DEFAULTKEY_KERNING, 1) self._floating = getExtensionDefault(self.DEFAULTKEY_FLOATING, 1) # User preferences self._onCurvePointsSize = getDefault("glyphViewOncurvePointsSize") # typo, should be: OnCurve self._offCurvePointsSize = getDefault("glyphViewOffCurvePointsSize") self._strokeWidth = getDefault("glyphViewStrokeWidth") w, h = 400, 195 x = y = 10 self.initAllFonts() self.w = FloatingWindow((w, h), "Overlay UFOs") self.w.draw = CheckBox((x, y, 95, 18), "Draw", callback=self.drawCallback, value=self._drawing, sizeStyle="small") x += 60 self.w.fill = CheckBox((x, y, 95, 18), "Fill", callback=self.fillCallback, value=self._fill, sizeStyle="small") x += 40 self.w.fillColor = ColorWell((x, y, 45, 20), callback=self.fillColorCallback, color=self._fillColor) x += 60 self.w.stroke = CheckBox((x, y, 95, 18), "Stroke", callback=self.strokeCallback, value=self._stroke, sizeStyle="small") x += 60 self.w.strokeColor = ColorWell((x, y, 45, 20), callback=self.strokeColorCallback, color=self._strokeColor) x += 60 self.w.points = CheckBox((x, y, 95, 18), "Points", callback=self.pointsCallback, value=self._points, sizeStyle="small") x += 60 self.w.pointsColor = ColorWell((x, y, 45, 20), callback=self.pointsColorCallback, color=self._pointsColor) x, y = 10, 40 self.w.alignText = TextBox((x, y, 250, 15), "Alignment:", sizeStyle="small") y += 18 self.w.alignment = RadioGroup((x, y, 80, 55), ['Left', 'Center', 'Right'], isVertical=True, callback=self.alignmentCallback, sizeStyle="small") self.w.alignment.set(self._alignment) y += 62 self.w.kerning = CheckBox((x, y, 100, 10), "Show kerning", callback=self.kerningCallback, value=self._kerning, sizeStyle="mini") y += 18 self.w.floating = CheckBox((x, y, 100, 10), "Floating Window", callback=self.floatingCallback, value=self._floating, sizeStyle="mini") y += 25 self.w.resetDefaults = Button((x, y, 85, 14), "Reset settings", callback=self.resetSettingsCallback, sizeStyle="mini") x, y = 110, 40 self.w.fontList = List((x, y, 240, 55), self.getFontItems(), columnDescriptions=self.getListDescriptor(), showColumnTitles=False, selectionCallback=None, doubleClickCallback=self.fontListCallback, allowsMultipleSelection=True, allowsEmptySelection=True, drawVerticalLines=False, drawHorizontalLines=True, drawFocusRing=False, rowHeight=16 ) y += 55 self.w.hiddenFontList = List((x, y, 240, 55), self.getHiddenFontItems(), columnDescriptions=self.getListDescriptor(), showColumnTitles=False, selectionCallback=None, doubleClickCallback=self.hiddenFontListCallback, allowsMultipleSelection=True, allowsEmptySelection=True, drawVerticalLines=False, drawHorizontalLines=True, drawFocusRing=False, rowHeight=16 ) self._selectionChanging = False self.w.fontList.setSelection([]) # unselect y += 65 self.w.contextLeft = EditText((x, y, 90, 20), callback=self.contextCallback, continuous=True, placeholder="Left", sizeStyle="small") self.w.contextCurrent = EditText((x+95, y, 50, 20), callback=self.contextCallback, continuous=True, placeholder="?", sizeStyle="small") self.w.contextRight = EditText((x+150, y, 90, 20), callback=self.contextCallback, continuous=True, placeholder="Right", sizeStyle="small") x, y = 360, 100 self.w.addFonts = Button((x, y, 30, 20), "+", callback=self.addHiddenFontsCallback, sizeStyle="regular") y += 25 self.w.removeFonts = Button((x, y, 30, 20), unichr(8722), callback=self.removeHiddenFontsCallback, sizeStyle="regular") # Observers addObserver(self, "fontDidOpen", "fontDidOpen") addObserver(self, "fontWillClose", "fontWillClose") # fontDidClose? addObserver(self, "draw", "drawInactive") addObserver(self, "draw", "draw") # Prepare and open window self.setWindowLevel() self.setUpBaseWindowBehavior() self.w.open()
from mojo.events import addObserver from mojo.drawingTools import * from lib.tools.defaults import getDefaultColor, getDefault from mojo.UI import getGlyphViewDisplaySettings from lib.tools.misc import NSColorToRgba from fontTools.misc.fixedTools import otRound rad_base = getDefault("glyphViewOncurvePointsSize") * 1.75 class Eyeliner(): ''' Adds a little eye around points and anchors that are on the vertical font dimensions or guidelines. Ryan Bugden v1.2.5 : 2020.07.15 v1.2.1 : 2020.04.03 v1.2.0 : 2020.03.26 v1.1.1 : 2020.01.27 v1.0.0 : 2020.01.24 v0.9.0 : 2019.06.04 ''' def __init__(self): self.col_font_dim = self.getFlattenedAlpha( NSColorToRgba(getDefaultColor("glyphViewMetricsColor"))) self.col_glob_guides = self.getFlattenedAlpha( NSColorToRgba(getDefaultColor("glyphViewGlobalGuidesColor"))) self.col_loc_guides = self.getFlattenedAlpha( NSColorToRgba(getDefaultColor("glyphViewLocalGuidesColor")))
class BoundingTool(EditingTool, BaseWindowController): slantPointCoordinates = int( getDefault("glyphViewShouldSlantPointCoordinates")) offsetPointCoordinates = getDefault( "glyphViewShouldOffsetPointCoordinates") DEFAULTKEY = "com.fontbureau.boundingTool" DEFAULTKEY_FILLCOLOR = "%s.fillColor" % DEFAULTKEY DEFAULTKEY_STROKECOLOR = "%s.strokeColor" % DEFAULTKEY DEFAULTKEY_SHOWCOORDINATES = "%s.showCoordinates" % DEFAULTKEY DEFAULTKEY_SHOWDIMENSIONS = "%s.showCoordinates" % DEFAULTKEY DEFAULTKEY_SELECTION = "%s.selection" % DEFAULTKEY DEFAULTKEY_DIVISIONSX = "%s.divisionsX" % DEFAULTKEY DEFAULTKEY_DIVISIONSY = "%s.divisionsY" % DEFAULTKEY DEFAULTKEY_USEITALIC = "%s.useItalic" % DEFAULTKEY FALLBACK_FILLCOLOR = NSColor.colorWithCalibratedRed_green_blue_alpha_( 1, .5, .5, .3) FALLBACK_STROKECOLOR = NSColor.colorWithCalibratedRed_green_blue_alpha_( 1, .5, .5, .5) VERSION = 1.0 NAME = u'Bounding Tool' MANUAL = u"""TK""" color = (1, 0, .2) alpha = 1 divisionsStringList = ['1', '2', '3', '4'] divisionsList = [1, 2, 3, 4] def getToolbarTip(self): return self.NAME def getToolbarIcon(self): return toolbarIcon def getBox(self, selected=True): g = self.getGlyph() if g is not None and g.box is not None: n = g if selected: hasSelection = False copyGlyph = g.naked().selection.getCopyGlyph() if copyGlyph and copyGlyph[1].get('contours'): n = RGlyph(copyGlyph[0]) else: n = g if self.w.useItalic.get(): italicAngle = g.getParent().info.italicAngle or 0 if n.box: boxTop = n.box[3] boxBottom = n.box[1] boxWidth = n.box[2] - n.box[0] else: boxTop = g.getParent().info.ascender boxBottom = g.getParent().info.descender boxWidth = g.width #print n.angledLeftMargin, g.getParent().lib.get('com.typemytype.robofont.italicSlantOffset') try: leftX = n.angledLeftMargin or 0 + g.getParent().lib.get( 'com.typemytype.robofont.italicSlantOffset') or 0 rightX = n.width - n.angledRightMargin or 0 + g.getParent( ).lib.get('com.typemytype.robofont.italicSlantOffset') or 0 except: leftX = rightX = 0 topY = n.box[3] bottomY = n.box[1] topX = TX.getItalicOffset(topY, italicAngle) bottomX = TX.getItalicOffset(bottomY, italicAngle) box = ( (leftX + bottomX, bottomY), # bottom left (leftX + topX, topY), # top left (rightX + topX, topY), # top right (rightX + bottomX, bottomY), # bottom right (n.naked().angledBounds[2] - n.naked().angledBounds[0], n.naked().angledBounds[3] - n.naked().angledBounds[1])) else: box = ((n.box[0], n.box[1]), (n.box[0], n.box[3]), (n.box[2], n.box[3]), (n.box[2], n.box[1]), (n.box[2] - n.box[0], n.box[3] - n.box[1])) else: box = None #((0, 0), (0, 0), (0, 0), (0, 0), (0, 0)) return box def drawBackground(self, scale): g = self.getGlyph() self.fillColor.setFill() slantCoordinates = self.slantPointCoordinates italicSlantOffset = 0 if self.offsetPointCoordinates: italicSlantOffset = g.getParent().lib.get( 'com.typemytype.robofont.italicSlantOffset') or 0 color = self.fillColor.colorUsingColorSpaceName_( NSCalibratedRGBColorSpace) red = color.redComponent() green = color.greenComponent() blue = color.blueComponent() alpha = color.alphaComponent() fill(red, green, blue, alpha) stroke(red, green, blue, alpha) strokeWidth(1 * scale) dashLine(1) fontSizeValue = 8 fontSize(fontSizeValue * scale) showCoordinates = self.w.showCoordinates.get() showDimensions = self.w.showDimensions.get() selectedBox = self.getBox(selected=True) if selectedBox: # switch them around so that we draw a line perpindicular to the axis we want to subdivide divisionsY = int(self.w.divisionsRadioX.get()) divisionsX = int(self.w.divisionsRadioY.get()) pt1, pt2, pt3, pt4, dimensions = selectedBox pt1X, pt1Y = pt1 # bottom left pt2X, pt2Y = pt2 # top left pt3X, pt3Y = pt3 # top right pt4X, pt4Y = pt4 # bottom right pt1X += italicSlantOffset pt2X += italicSlantOffset pt3X += italicSlantOffset pt4X += italicSlantOffset width, height = dimensions startRectX = pt1X startRectY = pt1Y rectWidth = width / float(divisionsY) rectHeight = height / float(divisionsX) if self.w.useItalic.get(): italicAngle = g.getParent().info.italicAngle or 0 else: italicAngle = 0 margin = 0 f = g.getParent() asc = f.info.ascender + f.info.unitsPerEm desc = f.info.descender - f.info.unitsPerEm ascOffset = TX.getItalicOffset(asc - pt3Y, italicAngle) descOffset = TX.getItalicOffset(desc - pt1Y, italicAngle) line(pt1X + descOffset, desc, pt2X + ascOffset, asc) line(pt4X + descOffset, desc, pt3X + ascOffset, asc) line(pt1X - f.info.unitsPerEm, pt1Y, pt4X + f.info.unitsPerEm, pt1Y) line(pt2X - f.info.unitsPerEm, pt2Y, pt3X + f.info.unitsPerEm, pt2Y) margin = 10 * scale #((width + height) / 2) / 20 if showDimensions: widthYBump = 0 if italicAngle: widthYBump = 20 * scale widthString = 'w: %s' % (TX.formatStringValue(width)) widthXPos = pt2X + (width / 2.0) + TX.getItalicOffset( margin, italicAngle) - 10 * scale widthYPos = pt2Y + margin + widthYBump if divisionsY > 1: subWidthString = ' %s' % (TX.formatStringValue( width / divisionsY)) text(subWidthString, widthXPos, widthYPos) widthYPos += fontSizeValue * scale font("LucidaGrande-Bold") text(widthString, widthXPos, widthYPos) if divisionsY >= 1: xoffset = pt1X for divY in range(divisionsY + 1): if divY != 0 and divY != divisionsY: line( xoffset - TX.getItalicOffset(margin, italicAngle), pt1Y - margin, xoffset + TX.getItalicOffset(pt2Y - pt1Y, italicAngle) + TX.getItalicOffset(margin, italicAngle), pt3Y + margin) if showCoordinates: font("LucidaGrande") x, y = bezierTools.angledPoint((xoffset, pt1Y), italicAngle, roundValue=italicAngle, reverse=-1) text( '%s' % (TX.formatStringValue(x - italicSlantOffset)), xoffset - TX.getItalicOffset(margin, italicAngle) + 2 * scale, pt1Y - margin - fontSizeValue) if italicAngle != 0: x, y = bezierTools.angledPoint( (xoffset, pt1Y), italicAngle, roundValue=italicAngle, reverse=-1) text( '%s' % (TX.formatStringValue(x - italicSlantOffset)), xoffset + TX.getItalicOffset(pt3Y - pt1Y, italicAngle) + TX.getItalicOffset(margin, italicAngle) + 2 * scale, pt3Y + margin) xoffset += rectWidth ################### ################### ################### ################### margin = 10 * scale if showDimensions: heightString = 'h: %s' % (TX.formatStringValue(height)) heightXPos = pt4X + TX.getItalicOffset(height / 2.0, italicAngle) + margin heightYPos = pt4Y + (height / 2.0) - fontSizeValue / 2 if divisionsX > 1: heightYPos -= fontSizeValue * scale / 2 subHeightString = ' %s' % (TX.formatStringValue( height / divisionsX)) text( subHeightString, heightXPos, heightYPos, ) heightYPos += fontSizeValue * scale font("LucidaGrande-Bold") text(heightString, heightXPos, heightYPos) if divisionsX >= 1: yoffset = pt1Y for divX in range(divisionsX + 1): if divX != 0 and divX != divisionsX: line( pt1X + TX.getItalicOffset(yoffset - pt1Y, italicAngle) - margin, yoffset, pt1X + TX.getItalicOffset(yoffset - pt1Y, italicAngle) + width + margin, yoffset) if showCoordinates: font("LucidaGrande") text( '%s' % (TX.formatStringValue(yoffset)), pt1X + TX.getItalicOffset(yoffset - pt1Y, italicAngle) - margin - 14 * scale, yoffset) yoffset += rectHeight def becomeActive(self): """ Boot up the dialog. """ self.fillColor = getExtensionDefaultColor(self.DEFAULTKEY_FILLCOLOR, self.FALLBACK_FILLCOLOR) self.strokeColor = getExtensionDefaultColor( self.DEFAULTKEY_STROKECOLOR, self.FALLBACK_STROKECOLOR) self.w = FloatingWindow((260, 130), "Bounding Options", minSize=(100, 100), closable=False) self.w.viewOptions = RadioGroup((10, 10, 150, 20), ['Selection', 'Glyph'], callback=self.selectionCallback, isVertical=False, sizeStyle="small") self.w.viewOptions.set( getExtensionDefault(self.DEFAULTKEY_SELECTION, 0)) self.w.useItalic = CheckBox( (165, 10, 100, 20), "Use Italic", value=getExtensionDefault(self.DEFAULTKEY_USEITALIC, True), sizeStyle="small", callback=self.useItalicCallback) self.w.xLabel = TextBox((10, 40, 70, 20), "Divisions: X", sizeStyle="small") self.w.divisionsRadioX = Slider( (80, 40, 70, 20), value=getExtensionDefault(self.DEFAULTKEY_DIVISIONSX, 1), minValue=1, maxValue=4, tickMarkCount=4, stopOnTickMarks=True, continuous=True, sizeStyle="small", callback=self.divisionsXCallback) self.w.yLabel = TextBox((160, 40, 70, 20), "Y", sizeStyle="small") self.w.divisionsRadioY = Slider( (175, 40, 70, 20), value=getExtensionDefault(self.DEFAULTKEY_DIVISIONSY, 1), minValue=1, maxValue=4, tickMarkCount=4, stopOnTickMarks=True, continuous=True, sizeStyle="small", callback=self.divisionsYCallback) self.w.drawGuidesButton = Button((10, 100, 90, 20), 'Div Guides', callback=self.drawDivGuides, sizeStyle="small") self.w.drawBoxGuidesButton = Button( (120, 100, 90, 20), 'Box Guides', callback=self.drawBoxGuides, sizeStyle="small", ) x = 10 y = 70 self.w.showCoordinates = CheckBox( (x, y, 90, 20), "Coordinates", value=getExtensionDefault(self.DEFAULTKEY_SHOWCOORDINATES, True), sizeStyle="small", callback=self.showCoordinatesCallback) x += 90 self.w.showDimensions = CheckBox( (x, y, 90, 20), "Dimensions", value=getExtensionDefault(self.DEFAULTKEY_SHOWDIMENSIONS, True), sizeStyle="small", callback=self.showDimensionsCallback) x += 90 color = getExtensionDefaultColor(self.DEFAULTKEY_FILLCOLOR, self.FALLBACK_FILLCOLOR) self.w.color = ColorWell((x, y, 30, 22), color=color, callback=self.colorCallback) self.setUpBaseWindowBehavior() self.w.open() def becomeInactive(self): """ Remove the dialog when the tool is inactive. """ self.windowCloseCallback(None) self.w.close() def colorCallback(self, sender): """ Change the color. """ selectedColor = sender.get() r = selectedColor.redComponent() g = selectedColor.greenComponent() b = selectedColor.blueComponent() a = 1 strokeColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( r, g, b, a) setExtensionDefaultColor(self.DEFAULTKEY_FILLCOLOR, selectedColor) setExtensionDefaultColor(self.DEFAULTKEY_STROKECOLOR, strokeColor) self.fillColor = selectedColor self.strokeColor = strokeColor self.updateView() def showCoordinatesCallback(self, sender): setExtensionDefault(self.DEFAULTKEY_SHOWCOORDINATES, sender.get()) self.updateView() def showDimensionsCallback(self, sender): setExtensionDefault(self.DEFAULTKEY_SHOWDIMENSIONS, sender.get()) self.updateView() def divisionsXCallback(self, sender): setExtensionDefault(self.DEFAULTKEY_DIVISIONSX, sender.get()) self.updateView() def divisionsYCallback(self, sender): setExtensionDefault(self.DEFAULTKEY_DIVISIONSY, sender.get()) self.updateView() def selectionCallback(self, sender): setExtensionDefault(self.DEFAULTKEY_SELECTION, sender.get()) self.updateView() def useItalicCallback(self, sender): setExtensionDefault(self.DEFAULTKEY_USEITALIC, sender.get()) self.updateView() def drawDivGuides(self, sender): """ Draw guidelines for the current divisions. """ g = self.getGlyph() if self.w.viewOptions.get() == 0: selectedBox = self.getBox(selected=True) else: selectedBox = self.getBox(selected=False) if selectedBox: divisionsX = int(self.w.divisionsRadioY.get()) divisionsY = int(self.w.divisionsRadioX.get()) pt1, pt2, pt3, pt4, dimensions = selectedBox pt1X, pt1Y = pt1 # bottom left pt2X, pt2Y = pt2 # top left pt3X, pt3Y = pt3 # top right pt4X, pt4Y = pt4 # bottom right width, height = dimensions italicAngle = 0 if self.w.useItalic.get(): italicAngle = g.getParent().info.italicAngle or 0 g.prepareUndo() offset = pt1X advance = float(width) / divisionsX for i in range(divisionsX - 1): xmid = offset + advance g.addGuide((xmid, pt1Y), 90 + italicAngle) offset += advance offset = pt1Y advance = float(height) / divisionsY for i in range(divisionsY - 1): ymid = offset + advance g.addGuide((pt1X, ymid), 0) offset += advance g.performUndo() def drawBoxGuides(self, sender): """ Draw guidelines for the current box. """ g = self.getGlyph() selectedBox = self.getBox(selected=True) if selectedBox: divisionsX = int(self.w.divisionsRadioY.get()) divisionsY = int(self.w.divisionsRadioX.get()) pt1, pt2, pt3, pt4, dimensions = selectedBox pt1X, pt1Y = pt1 # bottom left pt2X, pt2Y = pt2 # top left pt3X, pt3Y = pt3 # top right pt4X, pt4Y = pt4 # bottom right width, height = dimensions italicAngle = 0 if self.w.useItalic.get(): italicAngle = g.getParent().info.italicAngle or 0 g.prepareUndo() #if self.w.viewX.get(): g.addGuide((pt1X, pt1Y), 90 + italicAngle) g.addGuide((pt3X, pt3Y), 90 + italicAngle) #if self.w.viewY.get(): g.addGuide((pt1X, pt1Y), 0) g.addGuide((pt3X, pt3Y), 0) g.performUndo() def updateView(self, sender=None): UpdateCurrentGlyphView()
#import outlineTestPen #reload(outlineTestPen) from outlineTestPen import OutlineTestPen from lib.tools.defaults import getDefault options = { "extremum_calculate_badness": True, "fractional_ignore_point_zero": True, "extremum_ignore_badness_below": 0, "smooth_connection_max_distance": 4, "collinear_vectors_max_distance": 2, "semi_hv_vectors_min_distance": 30, "zero_handles_max_distance": 0, "grid_length": getDefault('glyphViewRoundValues'), } def run_test(font, glyphnames): selection = [] otp = OutlineTestPen(CurrentFont(), options) for n in glyphnames: otp.errors = [] g = font[n] g.drawPoints(otp) if otp.errors: selection.append(g.name) font.selection = selection font = CurrentFont() glyphnames = CurrentFont().keys()
def update_charset_selection(self): if env == "robofont": self.charsets = getDefault("charsets") else: self.charsets = {} self.w.charset_selection.setItems(sorted(self.charsets.keys()))
MASTER_COLOR = (45 / 255., 90 / 255., 150 / 255.) SUB_COLOR = (180 / 255., 240 / 255., 170 / 255.) BLACK_COLOR = (0, 0, 0) # glyph lib key PLUGIN_KEY = 'broadNib' bodySizeCaption = 9 # component heights CheckBoxHeight = 18 TextBoxHeight = 14 EditTextHeight = 19 SquareButtonHeight = 19 # colors LIGHT_YELLOW = getDefault('glyphViewPreviewBackgroundColor') ### Extra functions def robofabRect(glyph, x, y, width, height): """custom rect routine robofab-flavour code, this is used for expansion""" x1, y1 = x, y - height / 2. x2, y2 = x + width / 2., y x3, y3 = x, y + height / 2. x4, y4 = x - width / 2., y pen = glyph.getPen() pen.moveTo((x1, y1)) pen.lineTo((x2, y2)) pen.lineTo((x3, y3)) pen.lineTo((x4, y4))