def Variable(self, variables, workSpace): """ Build small UI for variables in a script. The `workSpace` is usually `globals()` as you want to insert the variable in the current workspace. It is required that `workSpace` is a `dict` object. .. image:: assets/variables.png .. showcode:: /../examples/variables.py """ document = AppKit.NSDocumentController.sharedDocumentController( ).currentDocument() if not document: raise DrawBotError("There is no document open") controller = document.vanillaWindowController try: controller._variableController.buildUI(variables) controller._variableController.show() except: controller._variableController = VariableController( variables, controller.runCode, document) data = controller._variableController.get() for v, value in data.items(): workSpace[v] = value
def size(self, width, height=None): """ Set the width and height of the canvas. Without calling `size()` the default drawing board is 1000 by 1000 points. Alternatively `size('A4')` with a supported papersizes or `size('screen')` setting the current screen size as size, can be used. Afterwards the functions `width()` and `height()` can be used for calculations. It is advised to use `size()` always at the top of the script and not use `size()` in a multiple page document use `newPage(w, h)` to set the correct dimentions directly. .. showcode:: /../examples/size.py All supported papersizes: 10x14, 10x14Landscape, A0, A0Landscape, A1, A1Landscape, A2, A2Landscape, A3, A3Landscape, A4, A4Landscape, A4Small, A4SmallLandscape, A5, A5Landscape, B4, B4Landscape, B5, B5Landscape, Executive, ExecutiveLandscape, Folio, FolioLandscape, Ledger, LedgerLandscape, Legal, LegalLandscape, Letter, LetterLandscape, LetterSmall, LetterSmallLandscape, Quarto, QuartoLandscape, Statement, StatementLandscape, Tabloid, TabloidLandscape. """ if width in _paperSizes: width, height = _paperSizes[width] if width == "screen": width, height = AppKit.NSScreen.mainScreen().frame().size if height is None: width, height = width self._width = width self._height = height if not self._instructionsStack: self.newPage(width, height) else: raise DrawBotError( "It is advised to use 'size()' at the top of a script.")
def saveImage(self, paths, multipage=None): """ Save or export the canvas to a specified format. The argument `paths` can either be a single path or a list of paths. The file extension is important because it will determine the format in which the image will be exported. All supported file extensions: `pdf`, `svg`, `png`, `jpg`, `jpeg`, `tiff`, `tif`, `gif`, `bmp` and `mov`. * A `pdf` can be multipage. If `multipage` is `False` only the current page is saved. * A `mov` will use each page as a frame. * A `gif` can be animated when there are multiple pages and it will use each page as a frame. * All images and `svg` formats will only save the current page. If `multipage` is `True` all pages are saved to disk (a page index will be added to the file name). .. showcode:: /../examples/saveImage.py """ if isinstance(paths, (str, unicode)): paths = [paths] for path in paths: path = optimizePath(path) dirName = os.path.dirname(path) if not os.path.exists(dirName): raise DrawBotError("Folder '%s' doesn't exists" % dirName) base, ext = os.path.splitext(path) ext = ext.lower()[1:] context = getContextForFileExt(ext) self._drawInContext(context) context.saveImage(path, multipage)
def _tryInstallFontFromFontName(self, fontName): # check if the fontName is actually a path if os.path.exists(fontName): fontPath = os.path.abspath(fontName) ext = os.path.splitext(fontPath)[1] if ext.lower() in [".otf", ".ttf", ".ttc"]: fontName = self.installFont(fontPath) else: raise DrawBotError("Font '%s' is not .ttf, .otf or .ttc." % fontPath) return fontName
def lineDash(self, *value): """ Set a line dash with any given amount of lenghts. Uneven lenghts will have a visible stroke, even lenghts will be invisible. .. showcode:: /../examples/lineDash.py """ if not value: raise DrawBotError("lineDash must be a list of dashes or None") if isinstance(value[0], (list, tuple)): value = value[0] self._addInstruction("lineDash", value)
def fallbackFont(self, fontName): """ Set a fallback font, this is used whenever a glyph is not available in the current font. :: fallbackFont("Times") """ fontName = fontName.encode("ascii", "ignore") dummyFont = AppKit.NSFont.fontWithName_size_(fontName, 10) if dummyFont is None: raise DrawBotError("Fallback font '%s' is not available" % fontName) self._dummyContext.fallbackFont(fontName) self._addInstruction("fallbackFont", fontName)
def blendMode(self, operation): """ Set a blend mode. Available operations are: `normal`, `multiply`, `screen`, `overlay`, `darken`, `lighten`, `colorDodge`, `colorBurn`, `softLight`, `hardLight`, `difference`, `exclusion`, `hue`, `saturation`, `color`, `luminosity`, `clear`, `copy`, `sourceIn`, `sourceOut`, `sourceAtop`, `destinationOver`, `destinationIn`, `destinationOut`, `destinationAtop`, `xOR`, `plusDarker` and `plusLighter`, .. showcode:: /../examples/blendMode.py """ if operation not in self._dummyContext._blendModeMap.keys(): raise DrawBotError( "blend mode must be %s" % (", ".join(self._dummyContext._blendModeMap.keys()))) self._addInstruction("blendMode", operation)
def imageSize(self, path, pageNumber=None): """ Return the `width` and `height` of an image. .. showcode:: /../examples/imageSize.py """ if isinstance(path, self._imageClass): path = path._nsImage() if isinstance(path, AppKit.NSImage): rep = path.TIFFRepresentation() _isPDF = False else: if isinstance(path, (str, unicode)): path = optimizePath(path) if path.startswith("http"): url = AppKit.NSURL.URLWithString_(path) else: if not os.path.exists(path): raise DrawBotError("Image does not exist") url = AppKit.NSURL.fileURLWithPath_(path) _isPDF, pdfDocument = isPDF(url) # check if the file is an .eps _isEPS, epsRep = isEPS(url) # check if the file is an .gif _isGIF, gifRep = isGIF(url) if _isEPS: _isPDF = True rep = epsRep elif _isGIF and pageNumber is not None: rep = gifTools.gifFrameAtIndex(url, pageNumber - 1) elif _isPDF and pageNumber is not None: page = pdfDocument.pageAtIndex_(pageNumber - 1) # this is probably not the fastest method... rep = AppKit.NSImage.alloc().initWithData_( page.dataRepresentation()) else: rep = AppKit.NSImageRep.imageRepWithContentsOfURL_(url) if _isPDF: w, h = rep.size() elif _isGIF: w, h = rep.size() else: w, h = rep.pixelsWide(), rep.pixelsHigh() return w, h
def downloadCurrentVersion(): """ Download the current version (dmg) and mount it """ path = "http://static.typemytype.com/drawBot/DrawBot.dmg" try: # download and mount cmds = ["hdiutil", "attach", "-plist", path] popen = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = popen.communicate() if popen.returncode != 0: raise DrawBotError("Mounting failed") output = plistlib.readPlistFromString(out) dmgPath = None for item in output["system-entities"]: if "mount-point" in item: dmgPath = item["mount-point"] break AppKit.NSWorkspace.sharedWorkspace().openFile_(dmgPath) except: print "Something went wrong while downloading %s" % path
If the text overflows the rectangle, the overflowed text is returned. The default alignment is `left`. .. showcode:: /../examples/textBox.py """ if isinstance(txt, (str, unicode)): try: txt = txt.decode("utf-8") except UnicodeEncodeError: pass if align is None: align = "left" elif align not in self._dummyContext._textAlignMap.keys(): raise DrawBotError( "align must be %s" % (", ".join(self._dummyContext._textAlignMap.keys()))) self._requiresNewFirstPage = True self._addInstruction("textBox", txt, (x, y, w, h), align) return self._dummyContext.clippedText(txt, (x, y, w, h), align) def textbox(self, txt, x, y, w, h, align=None): _deprecatedWarningLowercase("textbox(%s, (%s, %s, %s, %s), align=%s)" % (txt, x, y, y, w, align)) self.textbox(txt, (x, y, w, h), align) _formattedStringClass = FormattedString def FormattedString(self, *args, **kwargs): """ Return a string object that can handle text formatting.