def draw(self): self.xFactor = self.targetXheight / currentXheight drawBot.newDrawing() drawBot.newPage("LetterLandscape") pageWidth = drawBot.width() drawBot.fill(0, 0, 0, 0.5) drawBot.stroke(0, 0, 0, 1) drawBot.rect(.5 * dpi, .5 * dpi, pageWidth - (1 * dpi), self.targetXheight) drawBot.translate(0.5 * dpi, .5 * dpi) drawBot.scale(self.xFactor) for g in self.text: pen = CocoaPen(f) f[g].draw(pen) drawBot.drawPath(pen.path) drawBot.translate(f[g].width, 0) pdf = drawBot.pdfImage() # set the pdf data in the canvas self.w.canvas.setPDFDocument(pdf)
def export(self, path): """Draw a page and export the document into the _export folder. Note that in this version, we still generate the document page just before it is exported. Not Page instances are stored in the Document yet. >>> doc = Document() >>> doc.export('_export/Document-export.jpg') # Exporting the JPG """ # Make sure that the _export folder exists, as it does not standard # dowload from Github, nor it is committed to Github. if path.startswith(EXPORT_DIR) and not os.path.exists(EXPORT_DIR): os.mkdir(EXPORT_DIR) # Now let DrawBot do its work, creating the page canvas, filling it # black, add the title text and then saving it. drawBot.newPage(self.w, self.h) # For now to have something visible, draw a gray rectangle filling the page. drawBot.fill(0.2) # Set fill color at 20% dark gray. drawBot.rect(0, 0, self.w, self.h) # Draw the rectangle for the entire page. # Create a Formatted String for white text with the specified font/fontSize. fs = drawBot.FormattedString('My specimen', font='Georgia', fontSize=80, fill=1) # Draw the FormattedString on this fixed position: x from left and y from top. drawBot.text(fs, (50, self.h - 100)) # Save the drawn DrawBot page into the _export folder, using `path` as file name. # File in the _export folder are ignored by Git, so they don't upload. drawBot.saveImage(path)
def test_newPage_empty_implicit_first_page(self): drawBot.newDrawing() drawBot.rect(100, 100, 200, 200) drawBot.newPage() self.assertEqual(drawBot.width(), 1000) self.assertEqual(drawBot.height(), 1000) self.assertEqual(drawBot.pageCount(), 2)
def test_newPage_empty_implicit_first_page(self): drawBot.newDrawing() drawBot.rect(100, 100, 200, 200) drawBot.newPage() self.assertEqual(drawBot.width(), 1000) self.assertEqual(drawBot.height(), 1000) self.assertEqual(drawBot.pageCount(), 2)
def test_instructionStack(self): expected = [ "reset None", "newPage 200 200", "save", "clipPath moveTo 5.0 5.0 lineTo 15.0 5.0 lineTo 15.0 15.0 lineTo 5.0 15.0 closePath", "restore", "image Image Object 10 10 0.5 None", "blendMode saturation", "transform 1 0 0 1 10 10", "drawPath moveTo 10.0 10.0 lineTo 110.0 10.0 lineTo 110.0 110.0 lineTo 10.0 110.0 closePath", "textBox foo bar 72.48291015625 84.0 55.0341796875 26.0 center", "frameDuration 10", "saveImage * {'myExtraAgrument': True}" ] with StdOutCollector() as output: import drawBot drawBot.newDrawing() drawBot.size(200, 200) drawBot.save() path = drawBot.BezierPath() path.rect(5, 5, 10, 10) drawBot.clipPath(path) drawBot.restore() im = drawBot.ImageObject() with im: drawBot.size(20, 20) drawBot.rect(5, 5, 10, 10) drawBot.image(im, (10, 10), alpha=.5) drawBot.blendMode("saturation") drawBot.translate(10, 10) drawBot.rect(10, 10, 100, 100) drawBot.text("foo bar", (100, 100), align="center") drawBot.frameDuration(10) drawBot.saveImage("*", myExtraAgrument=True) drawBot.endDrawing() self.assertEqual(output.lines(), expected)
def makeFlash(s, w, h, px, py, color1=None, color2=None, flashSpeed=4): if color1 is None: r1, g1, b1 = 1, 0, 0 else: r1, g1, b1 = color1 if color2 is None: r2, g2, b2 = 0.2, 0, 0 else: r2, g2, b2 = color2 for n in range(flashSpeed): newPage(w, h) fill(0) rect(0, 0, w, h) drawString(s, px, py, 'PropSingleBold', (r1, g1, b1, 0.2)) drawString(s, px, py, 'PropSingleMedium', (r1, g1, b1, 0.5)) if HIGHLIGHT: drawString(s, px, py, 'PropSingle', (r1 * 0.9, g1 * 0.9, b1 * 0.9, 1)) drawString(s, px - 1, py + 1, 'PropSingleLight', (r1, g1, b1, 1)) else: drawString(s, px, py, 'PropSingle', (r1, g1, b1, 1)) for n in range(flashSpeed): newPage(w, h) fill(0) rect(0, 0, w, h) drawString(s, px, py, 'PropSingleBold', (r2, g2, b2, 0.2)) drawString(s, px, py, 'PropSingleMedium', (r2, g2, b2, 0.5)) if HIGHLIGHT: drawString(s, px, py, 'PropSingle', (r2 * 0.9, g2 * 0.9, b2 * 0.9, 1)) drawString(s, px - 1, py + 1, 'PropSingleLight', (r2, g2, b2, 1)) else: drawString(s, px, py, 'PropSingle', (r2, g2, b2, 1))
def draw(self, origin, view): u"""Like "rolled pasteboard" galleys can draw themselves, if the Composer decides to keep them in tact, instead of select, pick & choose elements, until the are all part of a page. In that case the w/h must have been set by the Composer to fit the containing page.""" p = pointOffset(self.oPoint, origin) p = self._applyScale(p) px, py, _ = self._applyAlignment(p) # Ignore z-axis for now. if self.drawBefore is not None: # Call if defined self.drawBefore(self, p, view) setFillColor(self.OLD_PAPER_COLOR) # Color of old paper: #F8ECC2 gw, gh = self.getSize() rect(px, py, gw, gh) gy = 0 for element in self.elements: # @@@ Find space and do more composition element.draw((px, py + gy), view) gy += element.h if self.drawAfter is not None: # Call if defined self.drawAfter(self, p, view) self._restoreScale() view.drawElementMetaInfo(self, origin)
def drawMissingElementRect(self, e, origin): u"""When designing templates and pages, this will draw a filled rectangle on the element bounding box (if self.css('missingElementFill' is defined) and a cross, indicating that this element has missing content (as in unused image frames). Only draw if self.css('showGrid') is True.""" if self.showMissingElementRect: p = pointOffset(e.point, origin) p = e._applyOrigin(p) p = e._applyScale(p) px, py, _ = e._applyAlignment(p) # Ignore z-axis for now. self.setShadow() sMissingElementFill = self.css('viewMissingElementFill', NO_COLOR) if sMissingElementFill is not NO_COLOR: setFillColor(sMissingElementFill) setStrokeColor(None) rect(px, py, self.w, self.h) # Draw crossed rectangle. setFillColor(None) setStrokeColor(0, 0.5) rect(px, py, self.w, self.h) newPath() moveTo((px, py)) lineTo((px + self.w, py + self.h)) moveTo((px + self.w, py)) lineTo((px, py + self.h)) drawPath() self.resetShadow() e._restoreScale()
def drawCurrentGlyph(self): db.newDrawing() db.translate(100, 100) db.scale(0.8) db.fill(None) db.stroke(0.2, 0.3, 1) db.rect(0, 0, 1000, 1000) db.stroke(None) db.translate( 0, 120 ) # Baseline at 120 from the bottom of the Ideographic Em Square db.fill(0, 1, 0, 0.3) db.stroke(0) db.lineJoin("round") dcSelection = set(self.w.deepComponentList.getSelection()) aeSelection = set(self.w.atomicElementList.getSelection()) if self._currentGlyphOutline is not None: drawOutline(self._currentGlyphOutline) if self._currentGlyphComponents: for dcIndex, (dcName, atomicElements) in enumerate( self._currentGlyphComponents ): for aeIndex, (aeName, atomicOutline) in enumerate(atomicElements): if dcIndex in dcSelection: if aeIndex in aeSelection: db.fill(1, 0, 0, 0.3) else: db.fill(0, 0, 1, 0.3) else: db.fill(0, 0.3) drawOutline(atomicOutline) db.endDrawing()
def makeTestICNSDrawing(self, formats): drawBot.newDrawing() for i, size in enumerate(formats): drawBot.newPage(size, size) f = i / (len(formats) + 1) drawBot.fill(f, f, 1 - f) drawBot.rect(0, 0, size, size)
def draw_spiral(size: float): points = generate_points(size) draw.fill(0, 0, 0, 1) draw.rect(0, 0, size, size) for i in range(len(points) - 1): draw_square(points[i], points[i + 1])
def drawPageFrame(self, page, origin): u"""Draw the page frame if the the flag is on and if there ie padding enough to show other meta info. Otherwise the padding is truncated to 0: no use to draw the frame.""" if self.showPageFrame: # Different from base View, no check on padding. fill(None) stroke(0.5) strokeWidth(0.5) rect(origin[0], origin[1], page.w, page.h)
def draw_sierpinski(side, limit=10): c_x, c_y = RESOLUTION[0] / 2, RESOLUTION[1] / 2 adj = RESOLUTION[1] / 7.5 desp = sqrt(3 / 4) * side draw.fill(BLACK[0], BLACK[1], BLACK[2], BLACK[3]) draw.rect(0, 0, RESOLUTION[0], RESOLUTION[1]) draw_sierpinski_r(c_x - side / 2, c_y + desp / 2 - adj, c_x + side / 2, c_y + desp / 2 - adj, c_x, c_y - desp / 2 - adj, limit)
def page_with_lines(width, height, x_lines, y_lines, mult, dur, color=False): drawBot.newPage(width*mult, height*mult) drawBot.frameDuration(dur) drawBot.fill(1, 1, 1) drawBot.rect(0, 0, width*mult, height*mult) if color: draw_colors(x_lines, y_lines, width, height, mult) draw_lines(x_lines, y_lines, mult)
def draw(self, saving=False, saveTo=None, fmt="pdf", layers=[], fill=None): savingToFont = isinstance(fmt, defcon.Font) if saving: db.newDrawing() self.saving = True else: self.saving = False db.newPage(*self.animation.dimensions) self.page = Rect.page() self.bps = {} for l in layers: self.bps[l] = RichBezier() with db.savedState(): if fill and not saveTo: with db.savedState(): db.fill(*fill) db.rect(*self.page) self.layers = layers self.animation.fn(self) self.layers = None if self.animation.burn: box = self.page.take(64, Edge.MinY).take(120, Edge.MaxX).offset(-24, 24) db.fontSize(20) db.lineHeight(20) db.font("Menlo-Bold") db.fill(0, 0.8) db.rect(*box.inset(-14, -14).offset(0, 2)) db.fill(1) db.textBox("{:07.2f}\n{:04d}\n{:%H:%M:%S}".format( self.time, self.i, datetime.datetime.now()), box, align="center") for k, bez in self.bps.items(): with db.savedState(): db.fill(*bez.fill) db.drawPath(bez.bp) if saving: if savingToFont: for k, bez in self.bps.items(): g = defcon.Glyph() g.name = "frame_" + str(self.i) g.unicode = self.i + 48 # to get to 0 g.width = self.animation.dimensions[0] bez.bp.drawToPen(g.getPen()) fmt.insertGlyph(g) else: db.saveImage(f"{saveTo}/{self.i}.{fmt}") db.endDrawing() self.saving = False
def draw(self, sender): db.newDrawing() db.newPage(300, 300) fill(random(), random(), random()) db.rect(0, 0, 50, 50) self.pdf = db.pdfImage() self.w.drawView.setPDFDocument(self.pdf)
def test_linkURL_svg(self): expectedPath = os.path.join(testDataDir, "expected_svgLinkURL.svg") drawBot.newDrawing() drawBot.newPage(200, 200) drawBot.rect(10, 10, 20, 20) drawBot.linkURL("http://drawbot.com", (10, 10, 20, 20)) with TempFile(suffix=".svg") as tmp: drawBot.saveImage(tmp.path) self.assertEqual(readData(tmp.path), readData(expectedPath), "Files %r and %s are not the same" % (tmp.path, expectedPath))
def draw(self, page, x, y): fillColor = self.style.get('fill') if fillColor is not None: setFillColor(fillColor) setStrokColor(None) stroke(0.8) strokeWidth(0.5) fill(None) rect(x, y, self.w, self.h) if len(self.dimensions) == 1: raise ValueError('Not supporting 1 axis now') if len(self.dimensions) > 2: raise ValueError('Not supporting >2 axis now') axisNames = sorted(self.dimensions.keys()) axisX = axisNames[0] sizeX = self.dimensions[axisX] axisY = axisNames[1] sizeY = self.dimensions[axisY] stepX = self.w / (sizeX + 1) stepY = self.h / (sizeY + 1) """Add more parametric layout behavior here.""" RANGE = 1000 for indexX in range(sizeX + 1): for indexY in range(sizeY + 1): ox = 30 oy = 25 px = ox + x + indexX * stepX py = oy + y + indexY * stepY self.location[axisX] = indexX * RANGE / sizeX self.location[axisY] = indexY * RANGE / sizeY glyphPathScale = self.fontSize / self.font.info.unitsPerEm drawGlyphPath(self.font.ttFont, self.glyphNames[0], px, py, self.location, s=glyphPathScale, fillColor=(0, 0, 0)) fs = FormattedString('%s %d\n%s %d' % (axisX, indexX * RANGE / sizeX, axisY, indexY * RANGE / sizeY), fontSize=6, fill=0) w, h = fs.size() page.text( fs, px - stepX / 4, py - 16) # Bit of hack, we need the width of the glyph here. fs = FormattedString('Other axes: %s' % self.location, fontSize=6, fill=0) w, h = fs.size() page.text(fs, x, y - 16)
def drawPageFrame(self, page, origin): u"""Draw the page frame if the the flag is on and if there ie padding enough to show other meta info. Otherwise the padding is truncated to 0: no use to draw the frame.""" if self.showPageFrame and \ self.pl > self.MIN_PADDING and self.pr > self.MIN_PADDING and \ self.pt > self.MIN_PADDING and self.pb > self.MIN_PADDING: fill(None) stroke(0, 0, 1) strokeWidth(0.5) rect(origin[0], origin[1], page.w, page.h)
def backgroundSquares(canvasWidth, canvasHeight): squareSize = 50 buffer = 0.2 base_color = hls_to_rgb(random.random(), 0.5, 1) for x in range(0, canvasWidth, squareSize): for y in range(0, canvasHeight, squareSize): db.fill(base_color[0] + (random.random() * buffer), base_color[1] + (random.random() * buffer), base_color[2] + (random.random() * buffer), 0.3) db.rect(x, y, squareSize, squareSize)
def makeTestAnimation(self, numFrames=25, pageWidth=500, pageHeight=500): randomSeed(0) drawBot.newDrawing() for i in range(numFrames): drawBot.newPage(pageWidth, pageHeight) drawBot.frameDuration(1/25) drawBot.fill(1) drawBot.rect(0, 0, pageWidth, pageHeight) drawBot.fill(0) drawBot.rect(random.randint(0, 100), random.randint(0, 100), 400, 400)
def drawPages(self, pageSelection=None): u"""Draw the selected pages. pageSelection is an optional set of y-pageNumbers to draw.""" doc = self.parent w, h, _ = doc.getMaxPageSizes(pageSelection) w2 = 2 * w # Make spread width for pn, pages in doc.getSortedPages(): #if pageSelection is not None and not page.y in pageSelection: # continue # Create a new DrawBot viewport page to draw template + page, if not already done. # In case the document is oversized, then make all pages the size of the document, so the # pages can draw their crop-marks. Otherwise make DrawBot pages of the size of each page. # Size depends on the size of the larges pages + optional decument padding. page = pages[ 0] # TODO: Make it work if there as multiple pages on the same page number. pw, ph = w, h # Copy from main (w, h), since they may be altered. if self.pl > self.MIN_PADDING and self.pt > self.MIN_PADDING and self.pb > self.MIN_PADDING and self.pr > self.MIN_PADDING: pw += self.pl + self.pr ph += self.pt + self.pb if self.originTop: origin = self.pl, self.pt, 0 else: origin = self.pl, self.pb, 0 else: pw = page.w # No padding defined, follow the size of the page. ph = page.h origin = (0, 0, 0) pw2 = 2 * pw if (pn % 2 == 0): # Is even? newPage( pw2, ph ) # Make page in DrawBot of self size, actual page may be smaller if showing cropmarks. # View may have defined a background if self.style.get('fill') is not None: setFillColor(self.style['fill']) rect(0, 0, pw2, ph) else: # Odd, shift origin to right origin = origin[0] + pw, origin[1], origin[2] if self.drawBefore is not None: # Call if defined self.drawBefore(page, origin, self) self.drawPageFrame(page, origin) # Use the (docW, docH) as offset, in case cropmarks need to be displayed. page.draw(origin, self) if self.drawAfter is not None: # Call if defined self.drawAfter(page, origin, self) # Self.infoElements now may have collected elements needed info to be drawn, after all drawing is done. # So the info boxes don't get covered by regular page content. for e in self.elementsNeedingInfo.values(): self._drawElementsNeedingInfo()
def kerningHeatMap(kerning, glyphNames, isFirstVertical): corrections = [kerning[pair] for pair in product(glyphNames, repeat=2)] corrections.sort() minCorrection, maxCorrection = abs(corrections[0]), abs(corrections[-1]) if minCorrection < maxCorrection: reference = maxCorrection else: reference = minCorrection for jj, glyphY in enumerate(glyphNames): # vertical captions with savedState(): translate(-CELL_SIZE, jj * CELL_SIZE) typeQualities() text(f'{glyphY}', (CELL_SIZE * .5, CELL_SIZE * .2), align='center') # drawing the row for ii, glyphX in enumerate(glyphNames): pair = (glyphY, glyphX) if isFirstVertical else (glyphX, glyphY) correction = kerning[pair] with savedState(): translate(ii * CELL_SIZE, jj * CELL_SIZE) # horizontal captions if jj == 0: typeQualities() text(f'{glyphX}', (CELL_SIZE * .5, -CELL_SIZE * .8), align='center') # draw the cells factor = .5 + .5 * abs(correction) / reference if correction == 0: rectClr = BLACK typeClr = WHITE elif correction < 0: rectClr = lerpRGB(WHITE, RED, factor) typeClr = WHITE else: rectClr = lerpRGB(WHITE, GREEN, factor) typeClr = BLACK shapeQualities(rectClr) rect(0, 0, CELL_SIZE, CELL_SIZE) if correction != 0: corrStr = f'{abs(correction)}' # just a check for body size if textSize(corrStr)[0] > CELL_SIZE: print(f'[WARNING] {pair} text is too big!') typeQualities(clr=typeClr) text(corrStr, (CELL_SIZE * .5, CELL_SIZE * .2), align='center')
def drawCell(glyphName, cellWidth, cellHeight, cellLegendSize): # Cell outline db.fill(None) db.stroke(0) db.strokeWidth(0.25) db.rect(0, 0, cellWidth, cellHeight) charArea = cellWidth / 3.5 fontSize = charArea * 0.7 charStartingOffset = (cellWidth * 0.5) - (charArea * 1.5) # Glyph sample for iH, aH in enumerate(angles): for iV, aV in enumerate(reversed(angles)): locStr = "%s %s" % (aH, aV) f = instances[locStr] if glyphName in f: g = f[glyphName] with db.savedState(): db.translate(charStartingOffset, charStartingOffset ) # Center the nine glyphs in the cell db.translate( iH * charArea, iV * charArea) # Move to the current glyph in the cell db.translate(charArea * 0.5, 0) # Offset to center glyph in cell db.translate(0, cellLegendSize * 3) # Leave room for the legend # Draw db.fill(0) db.stroke(None) db.scale(fontSize / 1000) drawGlyph(g) # Legend db.fill(None) db.stroke(0) db.strokeWidth(0.25) db.lineCap("round") db.line((cellLegendSize, cellLegendSize * 3), (cellWidth - cellLegendSize, cellLegendSize * 3)) unicodeValueStr = "" if g.unicode: unicodeValueStr = hex(g.unicode) legendText = "%s\n%s" % (g.name, unicodeValueStr) fs = db.FormattedString(legendText, font="Tilt Neon", fontSize=cellLegendSize, tracking=1, lineHeight=cellLegendSize) db.text(fs, (cellLegendSize, cellLegendSize * 1.7))
def makeRunningLeds(s, w, h, px, py, speed=1): newPage(w, h) fill(0) rect(0, 0, w, h) drawString(s, px, py, 'PropSingleBoldItalic', (0.3, 0, 0, 1)) drawString(s, px, py, 'PropSingleMediumItalic', (0.6, 0.0, 0, 1)) if HIGHLIGHT: drawString(s, px, py, 'PropSingleItalic', (0.8, 0, 0, 1)) drawString(s, px - 1, py + 1, 'PropSingleLightItalic', (1, 0, 0, 1)) else: drawString(s, px, py, 'PropSingleItalic', (1, 0, 0, 1))
def draw(self, pages: list, export=False): if not pages: return tbs = self.w.customPages.page.textBoxList.getSelection() db.newDrawing() for page in pages: if page is None: continue db.newPage(*page.size) db.save() db.fill(*page.backgroundColor) db.rect(0, 0, *page.size) db.restore() for i, textbox in enumerate(page.textBoxes): db.save() db.translate(*textbox.position[:2]) if not export: db.save() db.fill(None) if i in tbs: db.stroke(1, 0, 0, 1) if not textbox.text: db.fill(.5, .5, .5, .5) db.rect(0, 0, *textbox.position[2:]) db.restore() if textbox.type == "Text": db.save() db.fill(*textbox.color) db.tracking(textbox.tracking) db.font(textbox.font, textbox.fontSize) db.textBox(textbox.text, (0, 0, *textbox.position[2:]), textbox.align) db.restore() elif textbox.type == "UfoText": db.save() db.fill(*textbox.color) s = textbox.fontSize / 1000 db.scale(s, s) for pos, glyph in textbox.glyphs: db.save() db.translate(*pos) if export: glyph.round() db.drawGlyph(glyph) db.restore() db.restore() db.restore() pdfData = db.pdfImage() self.w.customPages.canvas.setPDFDocument(pdfData)
def draw_board(board: array) -> array: n = board.shape[0] square_size = BOARD_SIZE / n draw.newPage(BOARD_SIZE, BOARD_SIZE) draw.frameDuration(FRAME_DURATION) for i in range(n): for j in range(n): if board[i,j] == 0: draw.fill(0, 0, 0, 1) else: draw.fill(255, 255, 255, 1) draw.rect(square_size * j, square_size * i, square_size, square_size)
def draw_textile(mtx, tate_color, yoko_color, grid_size=10): for i in range(mtx.shape[0]): for j in range(mtx.shape[1]): if mtx[i][j] == 1: db.stroke(*tate_color) db.fill(*tate_color) elif mtx[i][j] == 0: db.stroke(*yoko_color) db.fill(*yoko_color) db.rect(i * grid_size, j * grid_size, grid_size, grid_size)
def drawWeight(weight, text): db.newDrawing() self.designFrameViewer.draw() db.newPage(FRAMEX, FRAMEY) db.textBox(user, (0, FRAMEY - 85, FRAMEX, 55), align='center') db.textBox(text, (0, FRAMEY - 105, FRAMEX, 55), align='center') s = .11 tx, ty = (FRAMEX / s - 1000 * 4) * .5, 1000 * 5.8 db.save() db.scale(s, s) db.translate(tx, ty) db.fontSize(60) print(weight) for i, glyph in enumerate(weight): drawDesignFrame() if glyph[0].markColor: db.fill(*glyph[0].markColor) else: db.fill(*INPROGRESS) db.rect(0, 900, 250, 100) db.fill(0, 0, 0, 1) db.stroke(None) db.textBox(glyph[0].name, (0, 900, 1000, 100), align="center") db.fill(0, 0, 0, 1) db.stroke(None) for c in glyph: db.drawGlyph(c) if (i + 1) % 4: db.translate(1000, 0) else: db.translate(-1000 * 3, -1200) db.restore() pdfData = db.pdfImage() now = datetime.datetime.now() if not self.RCJKI.currentFont.mysql: outputPath = os.path.join( self.RCJKI.currentFont.fontPath, "Proofing", user, '%s_%s_%s.pdf' % (date, str(pageIndex).zfill(2), text)) else: outputPath = os.path.join( mysqlpath, '%s_%s_%s.pdf' % (date, str(pageIndex).zfill(2), text)) # os.rename(outputPath, outputPath[:-3]+'ai') files.makepath(outputPath) db.saveImage(outputPath) os.rename(outputPath, outputPath[:-3] + "ai")
def draw(x_lines, y_lines, width, height, out_fn): mult = 10 drawBot.newDrawing() drawBot.newPage(width * mult, height * mult) drawBot.fill(1, 1, 1) drawBot.rect(0, 0, width * mult, height * mult) draw_colors(x_lines, y_lines, width, height, mult) draw_lines(x_lines, y_lines, mult) drawBot.saveImage(out_fn) drawBot.endDrawing()
def draw(txt="a", variations={}, caption=""): db.newPage(w * scale, h * scale) db.scale(scale) db.fill(*BACKCOL) db.rect(0, 0, w, h) txt = db.FormattedString(txt, font="Handjet-Regular", fontSize=500, fontVariations=variations) db.fill(*TEXTCOL) db.stroke(None) path = db.BezierPath() path.text(txt, (w / 2, 95), align="center") db.drawPath(path) txt = db.FormattedString(caption, font="AdapterMonoPE-Regular", fontSize=11, fill=TEXTCOL) db.text(txt, (w / 2, 40), align="center")
def test_instructionStack(self): expected = [ "reset None", "newPage 200 200", "save", "clipPath moveTo 5.0 5.0 lineTo 15.0 5.0 lineTo 15.0 15.0 lineTo 5.0 15.0 closePath", "restore", "image Image Object 10 10 0.5 None", "blendMode saturation", "transform 1 0 0 1 10 10", "drawPath moveTo 10.0 10.0 lineTo 110.0 10.0 lineTo 110.0 110.0 lineTo 10.0 110.0 closePath", "textBox foo bar 82.48291015625 84.0 35.0341796875 26.0 center", "frameDuration 10", "saveImage * {'myExtraAgrument': True}" ] with StdOutCollector() as output: import drawBot drawBot.newDrawing() drawBot.size(200, 200) drawBot.save() path = drawBot.BezierPath() path.rect(5, 5, 10, 10) drawBot.clipPath(path) drawBot.restore() im = drawBot.ImageObject() with im: drawBot.size(20, 20) drawBot.rect(5, 5, 10, 10) drawBot.image(im, (10, 10), alpha=.5) drawBot.blendMode("saturation") drawBot.translate(10, 10) drawBot.rect(10, 10, 100, 100) drawBot.text("foo bar", (100, 100), align="center") drawBot.frameDuration(10) drawBot.saveImage("*", myExtraAgrument=True) drawBot.endDrawing() self.assertEqual(output.lines(), expected)
import drawBot drawBot.newDrawing() drawBot.size(200, 200) def rotateScale(r, s, center): drawBot.rotate(r, center=center) drawBot.scale(s, center=center) testData = [ ((25, 25, 50, 50), drawBot.rotate, (20,), (25, 25)), ((125, 25, 50, 50), drawBot.skew, (10, 10), (175, 25)), ((25, 125, 50, 50), drawBot.scale, (1.2, 1.4), (25, 175)), ((125, 125, 50, 50), rotateScale, (20, 0.8), (175, 175)), ] for r, op, args, center in testData: drawBot.fill(0) drawBot.rect(*r) with drawBot.savedState(): drawBot.fill(1, 0, 0, 0.5) op(*args, center=center) drawBot.rect(*r)
import drawBot drawBot.size(200, 200) for i in range(14): f = i / 14.0 drawBot.fill(f, 1 - f, 0) drawBot.rect(10, 10, 50, 50) drawBot.translate(10, 10)
import drawBot drawBot.size(200, 200) drawBot.cmykRadialGradient( (0, 0), # startPoint (200, 200), # endPoint [(1, 0, 0, 1), (0, 0, 1, 0), (0, 1, 0, .2)], # colors [0, .2, 1], # locations 0, # startRadius 200 # endRadius ) drawBot.rect(0, 0, 200, 200)
import drawBot drawBot.size(200, 200) drawBot.stroke(0, 0, 1) drawBot.strokeWidth(5) with drawBot.savedState(): drawBot.fill(1, 0, 0) drawBot.translate(100, 100) drawBot.rect(0, 0, 100, 100) drawBot.rect(0, 0, 100, 100) with drawBot.savedState(): drawBot.fill(0, 1, 0) drawBot.translate(100, 0) drawBot.rect(0, 0, 100, 100) drawBot.rect(0, 100, 100, 100)
import drawBot drawBot.size(100, 100) drawBot.fill(.5, .5) drawBot.oval(0, 0, 100, 100) for x in range(10): for y in range(10): drawBot.fill(x / 10, 1 - y / 10, y / 10, y / 20 + .5) drawBot.rect(x*10, y*10, 10, 10)
import drawBot drawBot.size(100, 100) for x in range(10): for y in range(10): drawBot.cmykFill(x / 10, 1 - y / 10, y / 10, 0) drawBot.rect(x*10, y*10, 5, 10) drawBot.cmykFill(x / 10, 1 - y / 10, y / 10, 0.2) drawBot.rect(x*10 + 5, y*10, 5, 5) drawBot.cmykFill(x / 10, 1 - y / 10, y / 10, 0, 0.55) drawBot.rect(x*10 + 5, y*10 + 5, 5, 5)