def hslDonut(rings, ringThickness, holeRadius, fixedValue, isLuminosityConst, captions=True): for angle in range(FULL_CIRCLE): for eachRing in range(rings): ringFactor = eachRing / (rings - 1) radius = holeRadius + eachRing * ringThickness if isLuminosityConst: rgbClr = hls_to_rgb(angle / FULL_CIRCLE, fixedValue, ringFactor) else: rgbClr = hls_to_rgb(angle / FULL_CIRCLE, ringFactor, fixedValue) lineQualities(rgbClr, ringThickness) newPath() arc((0, 0), radius, angle - .5, angle + .5, clockwise=False) drawPath() with savedState(): if angle % 10 == 0 and captions: captionRadius = radius + ringThickness rotate(angle) lineQualities(thickness=.5) line((captionRadius - 2, 0), (captionRadius + 2, 0)) typeQualities() text(f'{angle}', (radius + ringThickness + 6, 0))
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 drawHeader(quota): typeQualities(isBold=True) text('Swatch', (SWA_X, quota)) text('Name', (NAM_X, quota)) text('HLS', (HLS_X, quota), align='right') text('RGB', (RGB_X, quota), align='right') text('HEX', (HEX_X, quota))
def _drawGlyphMarker(self, axisName, mx, my, glyphName, fontSize, location, strokeW=2): # Middle circle fill(1) stroke(0.7) strokeWidth(strokeW) oval(mx - fontSize / 2 * self.R, my - fontSize / 2 * self.R, fontSize * self.R, fontSize * self.R) variableFont = getVariableFont(self.font, location) # Show axis name below circle marker? if self.showAxisNames and axisName is not None: fs = newFS(axisName, style=dict(font=variableFont.installedName, fontSize=fontSize / 4, textFill=0)) tw, th = textSize(fs) text(fs, (mx - tw / 2, my - fontSize / 2 * self.R - th * 2 / 3)) glyphPathScale = fontSize / self.font.info.unitsPerEm drawGlyphPath(variableFont, glyphName, mx, my - fontSize / 3, s=glyphPathScale, fillColor=0)
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_formattedStringURL_svg(self): expectedPath = os.path.join(testDataDir, "expected_formattedStringURL.svg") drawBot.newDrawing() drawBot.newPage(200, 200) drawBot.underline("single") drawBot.url("http://drawbot.com") drawBot.text("foo", (10, 10)) 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 _drawOverflowMarker(self, px, py, view): fs = newFS('[+]', style=dict(textFill=(1, 0, 0), font='Verdana-Bold', fontSize=8)) tw, th = textSize(fs) if self.originTop: pass else: text(fs, (px + self.w - 3 - tw, py + th / 2))
def test_export_svg_fallbackFont(self): expectedPath = os.path.join(testDataDir, "expected_svgSaveFallback.svg") drawBot.newDrawing() drawBot.newPage(100, 100) drawBot.fallbackFont("Courier") drawBot.font("Times") drawBot.text("a", (10, 10)) 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 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 _drawHeader(self, quota, fontStyles): fontTitles = {} colIndex = int(COLS['template'] / TAB_WIDTH) for eachFontStyle in fontStyles: colIndex += 1 fontTitles[eachFontStyle] = colIndex * TAB_WIDTH headers = {k: v for (k, v) in COLS.items() + fontTitles.items()} db.font('LucidaGrande-Bold') for eachTitle, eachX in headers.items(): db.text(eachTitle, (PDF_MARGIN + eachX, quota))
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 drawTwoColumnsLayout(txt, postscriptFontName): typeAttributes() text(f'{postscriptFontName} 9 pts', (MARGIN_X1, height() - 25 * FROM_MM_TO_PT)) font(postscriptFontName, FONT_SIZE_PAR_SMALL) textBox(f'{txt}', (BOX1)) typeAttributes() text(f'{postscriptFontName} 12 pts', (MARGIN_X1 * 8, height() - 25 * FROM_MM_TO_PT)) font(postscriptFontName, FONT_SIZE_PAR_MED) textBox(f'{txt}', (BOX2)) # we don't aknowledge overflow, so we return an empty string return ""
def feelingSlide(canvasWidth, canvasHeight, polarity): db.newPage(canvasWidth, canvasHeight) background_fill = polarityBackground(polarity) db.fill(*background_fill) db.frameDuration(4) db.rect(0, 0, canvasWidth, canvasHeight) background_images = os.listdir('background_images/') background_image_path = 'background_images/' + background_images[(int)( len(background_images) * random.random())] # https://forum.drawbot.com/topic/180/how-do-i-size-an-image-with-the-imageobject-or-without/4 srcWidth, srcHeight = db.imageSize(background_image_path) dstWidth, dstHeight = canvasWidth - 50, canvasHeight - 50 factorWidth = dstWidth / srcWidth factorHeight = dstHeight / srcHeight with db.savedState(): db.translate(25, 25) with db.savedState(): db.scale(factorWidth, factorHeight) db.image(background_image_path, (0, 0)) dril_feels_text = db.FormattedString() dril_feels_text.append("@dril feels", font="Calibri-Bold", fontSize=150, fill=1, align='center', stroke=background_fill, strokeWidth=0.5) db.shadow((0, 0), 50, background_fill) db.text(dril_feels_text, (canvasWidth / 2, canvasHeight - 300)) if polarity < -0.1: drils_feeling = "angry" db.font("LucidaBlackletter", 250) elif polarity < 0.25: drils_feeling = "neutral" db.font("Helvetica", 180) else: drils_feeling = "happy" db.font("Cortado", 250) db.fill(1) db.shadow((0, 0), 50, background_fill) db.text(drils_feeling, (canvasWidth / 2, 250), align='center')
def draw(gn="a", variations={}, caption=""): db.newPage(w * scale, h * scale) db.scale(scale) db.fill(*BACKCOL) db.rect(0, 0, w, h) fs = db.FormattedString() fs.font("Handjet-Regular") fs.fontSize(200) fs.appendGlyph(gn) db.fill(*TEXTCOL) db.stroke(None) path = db.BezierPath() path.text(fs, (w / 2, 145), align="center") db.drawPath(path) fs = db.FormattedString(caption, font="AdapterMonoPE-Regular", fontSize=10, fill=TEXTCOL) db.text(fs, (w / 2, 40), align="center")
def drawPageNameInfo(self, page, origin): u"""Draw additional document information, color markers, page number, date, version, etc. outside the page frame, if drawing crop marks.""" if self.showPageNameInfo: bleed = self.css('bleed') cms = self.css('viewCropMarkSize') - bleed fontSize = self.css('viewPageNameFontSize') dt = datetime.datetime.now() d = dt.strftime("%A, %d. %B %Y %I:%M%p") s = 'Page %s | %s | %s' % (page.parent.getPageNumber(page), d, page.parent.title or 'Untitled') if page.name: s += ' | ' + page.name fs = FormattedString(s, font=self.css('viewPageNameFont'), fill=0, fontSize=fontSize) text(fs, (self.pl + bleed, self.pb + page.h + cms - fontSize * 2)) # Draw on top of page.
def test_imageAntiAliasing(self): from testScripts import DrawBotTest expectedPath = os.path.join(testDataDir, "expected_imageAntiAliasing.png") drawBot.newDrawing() drawBot.size(100, 100) drawBot.fill(1, 0, 0) drawBot.oval(10, 10, 40, 80) drawBot.fill(0) drawBot.stroke(0) drawBot.line((-0.5, -0.5), (100.5, 100.5)) drawBot.line((0, 20.5), (100, 20.5)) drawBot.fontSize(20) drawBot.text("a", (62, 30)) with TempFile(suffix=".png") as tmp: drawBot.saveImage(tmp.path, antiAliasing=False) self.assertImageFilesEqual(tmp.path, expectedPath)
def test_formattedString_issue337_part3(self): # Verifying we get the correct line height on an empty string expected = [ 'reset None', 'newPage 1000 1000', 'textBox A 0 -34.0 26.8994140625 104.0 left', 'textBox B 0 -46.0 25.751953125 104.0 left', 'textBox C 0 -58.0 26.9189453125 104.0 left', 'textBox A 10 -34.0 26.8994140625 104.0 left', 'textBox 10 48.0 20.0 104.0 left', 'textBox C 10 -58.0 26.9189453125 104.0 left', 'saveImage * {}' ] with StdOutCollector() as output: drawBot.newDrawing() fs = drawBot.FormattedString("A\nB\nC\n") drawBot.text(fs, (0, 60)) fs = drawBot.FormattedString("A\n\nC\n") drawBot.text(fs, (10, 60)) drawBot.saveImage("*") drawBot.endDrawing() self.assertEqual(output.lines(), expected)
def build(self, doc): """Recursively make the pages to draw themselves in DrawBot. The build is “broadcast” to all the elements on the page. """ drawBot.newPage(self.w, self.h) # Create a new DrawBot page. for element in self.elements: # Passing on doc and this page in case an element needs more info. element.build(doc, self) # Now let DrawBot do its work, creating the page and saving it. # For now to have something visible. # Fill the page with a random dark color (< 50% for (r, g, b)) drawBot.fill(random() * 0.5, random() * 0.5, random() * 0.5) drawBot.rect(0, 0, self.w, self.h) fs = drawBot.FormattedString('My specimen\nPage %d' % self.pn, font='Georgia', fontSize=80, fill=1) drawBot.text(fs, (50, self.h - 100))
def drawElementOrigin(self, e, origin): px, py, _ = pointOffset(e.oPoint, origin) S = self.css('viewInfoOriginMarkerSize', 4) if self.showElementOrigin: # Draw origin of the element setFillColor( (0.5, 0.5, 0.5, 0.1) ) # Transparant fill, so we can see the marker on dark backgrounds. setStrokeColor(0, 0.25) oval(px - S, py - S, 2 * S, 2 * S) line((px - S, py), (px + S, py)) line((px, py - S), (px, py + S)) if self.showElementDimensions: fs = newFS(point2S(e.point3D), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) w, h = textSize(fs) text(fs, (px - w / 2, py + S * 1.5))
def test_export_SVG_mixin(self): expectedPath = os.path.join(testDataDir, "expected_svgMixin.svg") drawBot.newDrawing() drawBot.newPage(100, 100) path = drawBot.BezierPath() path.svgID = "hello" path.svgClass = "foo bar" path.svgLink = "drawbot.com" path.rect(0, 0, 20, 20) drawBot.drawPath(path) txt = drawBot.FormattedString() txt += "world" txt.svgID = "hello" txt.svgClass = "foo bar" txt.svgLink = "drawbot.com" drawBot.text(txt, (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 drawText(sf, ma, md, texts): if len(texts) != 0: try: # this depends on Glyphs versions? columnX = texts[0].parent().width + 20 / sf except: columnX = texts[0].parent.width + 20 / sf d.stroke(None) d.fill(1, 0, 0, 1) d.font(".SF Compact Text", 10 / sf) columnText = "" for i, a in enumerate(texts): x, y, wid = a.x, a.y, a.width d.text(str(i + 1), (x, y)) columnText += "%s\t%s\n\n" % (i + 1, a.text) t = d.FormattedString() t.fill(1, 0, 0, 1) t.font(".SF Compact Text", 10 / sf) t.firstLineIndent(-10 / sf) t.tabs((10, "left")) t += columnText columnW = min(250 / sf, (d.width() - margin) / sf - a.layer.bounds[1][0]) d.textBox(t, (columnX, md, columnW, ma - md))
def draw(txt="a", variations={}, caption=""): db.newPage(w * scale, h * scale) db.scale(scale) db.fill(*BACKCOL) db.stroke(None) db.rect(0, 0, w, h) fs = db.FormattedString(txt, font="Handjet-Regular", fontSize=4600, fontVariations=variations) path = db.BezierPath() path.text(fs, (w / 2, 1.58 * h), align="center") path_optim = path.copy() # remove overlaps when drawing the fill # but use the original contour when drawing the nodes path_optim.removeOverlap() path_optim.optimizePath() # draw the fill db.fill(*TEXTCOL) db.drawPath(path_optim) # draw nodes if path.contours: # drawing just the first contour is enough for s in path.contours[0]: for x, y in s: if (x, y) in path.onCurvePoints: db.fill(*NODECOL) db.stroke(*TEXTCOL) db.strokeWidth(1) db.oval(x - 4, y - 4, 8, 8) # draw caption fs = db.FormattedString(caption, font="AdapterMonoPE-Regular", fontSize=10, fill=TEXTCOL) if caption: db.text(fs, (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)
def drawBaselineGrid(self, e, origin): u"""Draw baseline grid if line color is set in the style. TODO: Make fixed values part of calculation or part of grid style. Normally px and py will be 0, but it's possible to give them a fixed offset.""" if not self.showBaselineGrid: return p = pointOffset(self.oPoint, origin) p = self._applyScale(p) px, py, _ = self._applyAlignment(p) # Ignore z-axis for now. M = 16 startY = e.css('baselineGridStart') if startY is None: startY = e.pt # Otherwise use the top padding as start Y. oy = e.h - startY #- py line = 0 # Format of line numbers. # TODO: DrawBot align and fill don't work properly now. fs = newFS( '', self, dict(font=e.css('fallbackFont', 'Verdana'), xTextAlign=RIGHT, fontSize=M / 2, stroke=None, textFill=e.css('gridStroke'))) while oy > e.pb or 0: setFillColor(None) setStrokeColor(e.css('baselineGridStroke', NO_COLOR), e.css('gridStrokeWidth')) newPath() moveTo((px + e.pl, py + oy)) lineTo((px + e.w - e.pr, py + oy)) drawPath() text(fs + repr(line), (px + e.pl - 2, py + oy - e.pl * 0.6)) text(fs + repr(line), (px + e.w - e.pr - 8, py + oy - e.pr * 0.6)) line += 1 # Increment line index. oy -= e.css('baselineGrid' ) # Next vertical line position of baseline grid.
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 at just before it is exported. Not Page instances are stored in the Document yet. """ # 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 and 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% black. drawBot.rect(0, 0, self.w, self.h) # Draw the rectangle. # Create a Formatted String in white with specified font/fontSize. fs = drawBot.FormattedString('My specimen', font='Georgia', fontSize=80, fill=1) # Draw the FormattedString on this fixed position. drawBot.text(fs, (50, self.h - 100)) # Save the drawn DrawBot page into the _export folder, using `path` as file name. drawBot.saveImage(path)
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 _drawBaselines(self, px, py, view): # Let's see if we can draw over them in exactly the same position. if not view.showTextBoxBaselines and not self.showBaselines: return fontSize = self.css('baseLineMarkerSize') indexStyle = dict(font='Verdana', fontSize=8, textFill=(0, 0, 1)) yStyle = dict(font='Verdana', fontSize=fontSize, textFill=(0, 0, 1)) leadingStyle = dict(font='Verdana', fontSize=fontSize, textFill=(1, 0, 0)) if view.showTextBoxY: fs = newFS( ` 0 `, style=indexStyle) _, th = textSize(fs) text(fs, (px + self.w + 3, py + self.h - th / 4)) stroke(0, 0, 1) strokeWidth(0.5) prevY = 0 for textLine in self.textLines: y = textLine.y # TODO: Why measures not showing? line((px, py + y), (px + self.w, py + y)) if view.showTextBoxIndex: fs = newFS( ` textLine.lineIndex `, style=indexStyle) tw, th = textSize(fs) # Calculate right alignment text(fs, (px - 3 - tw, py + y - th / 4)) if view.showTextBoxY: fs = newFS('%d' % round(y), style=yStyle) _, th = textSize(fs) text(fs, (px + self.w + 3, py + y - th / 4)) if view.showTextBoxLeading: leading = round(abs(y - prevY)) fs = newFS('%d' % leading, style=leadingStyle) _, th = textSize(fs) text(fs, (px + self.w + 3, py + prevY - leading / 2 - th / 4)) prevY = y
vertical_pigs = math.floor(CANVAS[1] / ((height + margin / 2) * scale)) horizontal_pigs = math.floor(CANVAS[0] / ((width + margin) * scale)) # for k in range(FRAMES): # db.newPage(*CANVAS) # db.frameDuration(1/FRAMES) db.save() db.scale(scale) y = -height for i in range(vertical_pigs + 2): x = -width for j in range(horizontal_pigs + 2): db.save() db.translate(x, y) pig = sh.getGlyphPath(ufo_path, random.choice(glyphs)) # db.fill(j / random.randint(10, 15), i / random.randint(20, 30), random.uniform(0.6, 0.8), 1) db.fill(j / 15, i / 20, 0.7, 1) db.drawPath(pig) db.restore() x += width + margin y += height db.restore() db.fill(1) db.font('Cooper Std Black', 150) db.text('2019', (60, 200)) db.saveImage('~/Downloads/pig.gif', imageResolution=300) db.endDrawing()
import drawBot drawBot.newPage(130, 130) drawBot.font("Times") drawBot.text("ToTAVAT.", (10, 10)) drawBot.openTypeFeatures(kern=False) drawBot.text("ToTAVAT.", (10, 30)) drawBot.openTypeFeatures(kern=True) drawBot.text("ToTAVAT.", (10, 50)) # add tracking drawBot.tracking(10) drawBot.text("ToTAVAT.", (10, 70)) drawBot.openTypeFeatures(kern=False) drawBot.text("ToTAVAT.", (10, 90)) drawBot.openTypeFeatures(kern=True) drawBot.text("ToTAVAT.", (10, 110))
def text(self, bs, p): """Using the BabelString bs.fs proporty, the BabelString us forced to answer the DrawBot.FormattedString version of the string. """ drawBot.text(bs.fs, p)
# https://github.com/typemytype/drawbot/issues/427 import drawBot drawBot.size(200, 200) fs = drawBot.FormattedString() fs.font("Lucida Grande") fs.fontSize(50) fs.appendGlyph("H") fs.appendGlyph("i") drawBot.text(fs, (30, 110)) fs = drawBot.FormattedString() fs.font("Lucida Grande") fs.fontSize(50) fs.tracking(10) fs.appendGlyph("H") fs.appendGlyph("i") drawBot.text(fs, (30, 50))
import drawBot drawBot.size(200, 200) drawBot.text("hello world", (10, 10)) drawBot.fill(1, 0, 0) drawBot.text("foo bar", (10, 30)) drawBot.fill(1, 0, 1) drawBot.stroke(0, 1, 0) drawBot.strokeWidth(4) drawBot.font("Times", 50) drawBot.text("foo bar", (10, 50)) drawBot.fill(None) drawBot.stroke(0, 1, 0) drawBot.strokeWidth(1) drawBot.line((0, 50), (drawBot.width(), 50)) drawBot.stroke(None) drawBot.fill(0, 1, 1) drawBot.fontSize(20) drawBot.text("foo bar", (drawBot.width()*.5, 100), align="right") drawBot.text("foo bar", (drawBot.width()*.5, 120), align="center") drawBot.text("foo bar", (drawBot.width()*.5, 140), align="left")