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 drawLetters(self): xFactor = self.xHeightTarget / xHeightCurrent descenderTarget = descender * xFactor pageWidth = drawBot.width() pageHeight = drawBot.height() if self.descBox == 1: drawBot.stroke(1,0,0, 1) drawBot.line((margin, pageHeight-margin-self.xHeightTarget+descenderTarget),(pageWidth-dpi, pageHeight-margin-self.xHeightTarget+descenderTarget)) elif self.descBox == 0: drawBot.stroke(0,0,0,0) drawBot.fill(0,0,0, 1) drawBot.stroke(0,0,0, 0) drawBot.translate(margin, pageHeight-margin-self.xHeightTarget) drawBot.scale(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() self.w.canvas.setPDFDocument(pdf)
def drawGlyph(self): color = self.colorScheme.colorsRGB['glyph'] drawBot.save() drawBot.fontSize(self.captionSize) drawBot.font(self.captionFont) for char in self.txt: uni = ord(char) glyphName = UV2AGL.get(uni) # interpolate g1 = self.font[glyphName].getLayer('regular') g2 = self.font[glyphName].getLayer('bold') glyph = RGlyph() glyph.name = g1.name glyph.unicode = g1.unicode glyph.interpolate(self.interpolationFactor, g1, g2) # contours drawBot.fill(*color) B = drawBot.BezierPath() for contour in glyph.contours: contour.draw(B) drawBot.drawPath(B) # advance width if self.glyphWidthDraw: drawBot.save() drawBot.strokeWidth(self.glyphWidthStrokeWidth) drawBot.stroke(*color) drawBot.line((0, self.yBottom), (0, self.yTop)) drawBot.restore() # glyph data if self.glyphDataDraw: h = self.captionSize * 1.5 m = 40 w = glyph.width - m * 2 drawBot.save() drawBot.stroke(None) drawBot.fill(*color) y = self.yTop - h drawBot.textBox(glyph.name, (m, y, w, h)) drawBot.textBox(str(glyph.unicode), (m, y, w, h), align='right') y = self.yBottom drawBot.textBox(str(int(glyph.width)), (m, y, w, h), align='center') drawBot.restore() # done glyph drawBot.translate(glyph.width, 0) # last margin if self.glyphWidthDraw: drawBot.strokeWidth(self.glyphWidthStrokeWidth) drawBot.stroke(*color) drawBot.line((0, self.yBottom), (0, self.yTop)) # done drawBot.restore()
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 drawInfo(self): color = self.colorScheme.colorsRGB['info'] drawBot.save() # font info if self.infoValuesDraw: drawBot.fill(*color) drawBot.fontSize(self.captionSizeLarge) h = self.captionSizeLarge * 2 y = self.yTop txt = '%s %s' % (self.font.info.familyName, self.font.info.styleName) drawBot.textBox(txt, (0, y, self.textLength, h)) # blue zones # for i, y in enumerate(self.font.info.postscriptBlueValues): # if not i % 2: # yNext = self.font.info.postscriptBlueValues[i+1] # h = yNext - y # drawBot.fill(*color + (0.35,)) # drawBot.rect(0, y, self.textLength, h) # vertical dimensions yValues = set([ 0, self.font.info.xHeight, self.font.info.capHeight, self.font.info.descender, self.font.info.ascender, ]) drawBot.font(self.captionFont) drawBot.fontSize(self.captionSize) for y in yValues: # draw guide drawBot.stroke(*color) drawBot.strokeWidth(self.infoStrokeWidth) if not self.infoLineDash: drawBot.lineDash(None) else: drawBot.lineDash(*self.infoLineDash) drawBot.line((0, y), (self.textLength, y)) # draw y value if self.infoValuesDraw: w = 300 m = 50 drawBot.save() drawBot.stroke(None) drawBot.fill(*color) drawBot.textBox(str(int(y)), (-w-m, y-self.captionSize*0.5, w, self.captionSize*1.2), align='right') drawBot.restore() # done drawBot.restore()
def createPlaceholder(wdt, hgt, locationOnDisk): dB.newDrawing() dB.newPage(wdt, hgt) dB.fill(.5) dB.rect(0, 0, dB.width(), dB.height()) dB.stroke(1) dB.strokeWidth(10) dB.line((0, 0), (dB.width(), dB.height())) dB.line((0, dB.height()), (dB.width(), 0)) dB.saveImage(f'{locationOnDisk}') dB.endDrawing()
def cross(x, y, d, r=1, g=0, b=0, a=1): """ >>> cross(100, 100, 5, r=0.5, g=0.3, b=0.2, a=0.4) """ x0 = x - d y0 = y - d x1 = x + d y1 = y + d x2 = x + d y2 = y - d x3 = x - d y3 = y + d context.stroke(r, g, b) line((x0, y0), (x1, y1)) line((x2, y2), (x3, y3))
def drawGuideline(self): color = self.colorScheme.colorsRGB['guideline'] drawBot.save() drawBot.stroke(*color) drawBot.strokeWidth(self.guidelineStrokeWidth) drawBot.font(self.captionFont) drawBot.fontSize(self.captionSize) for guide in self.font.guidelines: drawBot.line((0, guide.y), (self.textLength, guide.y)) if self.guidelineValuesDraw: w = 300 m = 50 drawBot.save() drawBot.stroke(None) drawBot.fill(*color) drawBot.textBox(str(int(guide.y)), (-(w + m), guide.y - self.captionSize * 0.5, w, self.captionSize * 1.2), align='right') drawBot.restore() drawBot.restore()
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 drawAnchor(self): r = self.anchorSize * 0.5 color = self.colorScheme.colorsRGB['anchor'] drawBot.save() drawBot.strokeWidth(self.anchorStrokeWidth) drawBot.stroke(*color) drawBot.fill(None) for char in self.txt: uni = ord(char) glyphName = UV2AGL.get(uni) glyph = self.font[glyphName] if len(glyph.anchors): for anchor in glyph.anchors: x, y = anchor.x, anchor.y drawBot.oval(x-r, y-r, r*2, r*2) drawBot.line((x-r, anchor.y), (x+r, anchor.y)) drawBot.line((anchor.x, y-r), (anchor.x, y+r)) drawBot.translate(glyph.width, 0) drawBot.restore()
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 drawBPoint(self): r1 = self.bPointSize * 0.5 r2 = self.pointSize * 0.5 color = self.colorScheme.colorsRGB['bPoint'] drawBot.save() for char in self.txt: uni = ord(char) glyphName = UV2AGL.get(uni) # interpolate g1 = self.font[glyphName].getLayer('regular') g2 = self.font[glyphName].getLayer('bold') glyph = RGlyph() glyph.name = g1.name glyph.unicode = g1.unicode glyph.interpolate(self.interpolationFactor, g1, g2) for c in glyph.contours: for pt in c.bPoints: x, y = pt.anchor xIn, yIn = pt.bcpIn xOut, yOut = pt.bcpOut drawBot.fill(*color) drawBot.stroke(None) drawBot.oval(x - r1, y - r1, r1 * 2, r1 * 2) if not self.layers['point']: drawBot.oval(x + xIn - r2, y + yIn - r2, r2 * 2, r2 * 2) drawBot.oval(x + xOut - r2, y + yOut - r2, r2 * 2, r2 * 2) drawBot.fill(None) drawBot.stroke(*color) drawBot.strokeWidth(5) drawBot.line((x, y), (x + xIn, y + yIn)) drawBot.line((x, y), (x + xOut, y + yOut)) drawBot.translate(glyph.width, 0) drawBot.restore()
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
# explicitly to be skipped if cmd.startswith('G21') or cmd.startswith('G4') or cmd.startswith( 'M') or cmd.startswith('G92'): continue # rapid move elif cmd.startswith('G0'): thisPt = Point(extractValue('X', cmd), extractValue('Y', cmd)) prevPt = thisPt # straight line elif cmd.startswith('G1'): thisPt = Point(extractValue('X', cmd), extractValue('Y', cmd)) stroke(*ALTERNATE_COLORS[colorSwitch]) line(prevPt, thisPt) colorSwitch = not colorSwitch prevPt = thisPt # clockwise arc elif cmd.startswith('G2') or cmd.startswith('G3'): stroke(*ALTERNATE_COLORS[colorSwitch]) endPt = Point(extractValue('X', cmd), extractValue('Y', cmd)) ii = extractValue('I', cmd) jj = extractValue('J', cmd) centerPt = Point(prevPt.x + ii, prevPt.y + jj) radius = distance(centerPt, endPt) if cmd.startswith('G2'): isClockwise = True else:
def _drawElementsNeedingInfo(self): for e, origin in self.elementsNeedingInfo.values(): p = pointOffset(e.oPoint, origin) p = e._applyScale(p) px, py, _ = e._applyAlignment(p) # Ignore z-axis for now. if self.showElementInfo: # Draw box with element info. fs = newFS(e.getElementInfoString(), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) tw, th = textSize(fs) Pd = 4 # Padding in box and shadow offset. tpx = px - Pd / 2 # Make info box outdent the element. Keeping shadow on the element top left corner. tpy = py + e.h - th - Pd # Tiny shadow setFillColor((0.3, 0.3, 0.3, 0.5)) setStrokeColor(None) rect(tpx + Pd / 2, tpy, tw + 2 * Pd, th + 1.5 * Pd) # Frame setFillColor(self.css('viewInfoFill')) setStrokeColor(0.3, 0.25) rect(tpx, tpy, tw + 2.5 * Pd, th + 1.5 * Pd) text(fs, (tpx + Pd, tpy + th)) e._restoreScale() if self.showElementDimensions: # TODO: Make separate arrow functio and better positions # Draw width and height measures setFillColor(None) setStrokeColor(0, 0.25) S = self.css('viewInfoOriginMarkerSize', 4) x1, y1, x2, y2 = px + e.left, py + e.bottom, e.right, e.top # Horizontal measure line((x1, y1 - 0.5 * S), (x1, y1 - 3.5 * S)) line((x2, y1 - 0.5 * S), (x2, y1 - 3.5 * S)) line((x1, y1 - 2 * S), (x2, y1 - 2 * S)) # Arrow heads line((x1, y1 - 2 * S), (x1 + S, y1 - 1.5 * S)) line((x1, y1 - 2 * S), (x1 + S, y1 - 2.5 * S)) line((x2, y1 - 2 * S), (x2 - S, y1 - 1.5 * S)) line((x2, y1 - 2 * S), (x2 - S, y1 - 2.5 * S)) fs = newFS(asFormatted(x2 - x1), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) tw, th = textSize(fs) text(fs, ((x2 + x1) / 2 - tw / 2, y1 - 1.5 * S)) # Vertical measure line((x2 + 0.5 * S, y1), (x2 + 3.5 * S, y1)) line((x2 + 0.5 * S, y2), (x2 + 3.5 * S, y2)) line((x2 + 2 * S, y1), (x2 + 2 * S, y2)) # Arrow heads line((x2 + 2 * S, y2), (x2 + 2.5 * S, y2 - S)) line((x2 + 2 * S, y2), (x2 + 1.5 * S, y2 - S)) line((x2 + 2 * S, y1), (x2 + 2.5 * S, y1 + S)) line((x2 + 2 * S, y1), (x2 + 1.5 * S, y1 + S)) fs = newFS(asFormatted(y2 - y1), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) tw, th = textSize(fs) text(fs, (x2 + 2 * S - tw / 2, (y2 + y1) / 2))
def new(layer, totalPages): d.newPage(paperSize) w, h = d.width(), d.height() m = l.associatedFontMaster() d.font(".SF Compact Text", 10) d.text("%s %s" % (layer.parent.name, layer.name), (margin, margin)) d.text("%s/%s" % (d.pageCount(), totalPages - 1), (w - margin, margin), align="right") ma, md, mx, mc = m.ascender, m.descender, m.xHeight, m.capHeight zones = [az.position + az.size for az in m.alignmentZones] + [ma, md] boundsTop, boundsBtm = max(zones), min(zones) sf = float(h - margin * 3) / (boundsTop - boundsBtm) #scalefactor d.scale(sf) wNew = w / sf # scaled paper size d.translate((margin / sf), -boundsBtm + (margin * 2) / sf) # drawing metrics lines d.stroke(0, 0, 0, 0.5) d.strokeWidth(0.5 / sf) d.fill(None) lw = layer.width d.rect(0, md, lw, ma - md) d.line((0, mc), (lw, mc)) # x-height d.line((0, mx), (lw, mx)) # x-height d.line((0, 0), (lw, 0)) # baseline # alignment zones d.stroke(None) d.fill(0.7, 0.3, 0, 0.1) for az in m.alignmentZones: d.rect(0, az.position, lw, az.size) # drawing nodes offcurves = [] smooths = [] sharps = [] for p in layer.paths: smooths += [n for n in p.nodes if n.connection == GSSMOOTH] sharps += [ n for n in p.nodes if n.type != OFFCURVE and n.connection != GSSMOOTH ] offcurves += [n for n in p.nodes if n.type == OFFCURVE] d.stroke(0, 0, 0, 0.2) for n in p.nodes: if n.type == OFFCURVE: if n.nextNode.type != OFFCURVE: d.line((n.x, n.y), (n.nextNode.x, n.nextNode.y)) elif n.prevNode.type != OFFCURVE: d.line((n.prevNode.x, n.prevNode.y), (n.x, n.y)) d.stroke(None) nodeSize = 3 / sf hf = nodeSize / 2 #half d.fill(0, 0, 1, 0.5) for n in sharps: d.rect(n.x - hf, n.y - hf, nodeSize, nodeSize) d.fill(0, 0.7, 0, 0.5) for n in smooths: d.oval(n.x - hf, n.y - hf, nodeSize, nodeSize) d.fill(0, 0, 0, 0.2) for n in offcurves: d.oval(n.x - hf, n.y - hf, nodeSize, nodeSize) # drawing anchors d.stroke(None) d.fill(0.7, 0.25, 0.0, 0.75) nodeSize = 4 / sf hf = nodeSize * 0.7 for a in layer.anchors: # print(a, (ma, md, mc, mx, 0)) if a.y in (ma, md, mc, mx, 0): d.polygon((a.x - hf, a.y), (a.x, a.y - hf), (a.x + hf, a.y), (a.x, a.y + hf), close=True) else: d.oval(a.x - hf, a.y - hf, nodeSize, nodeSize) # glyph outline d.fill(0, 0, 0, 0.3) d.stroke(0, 0, 0, 1) d.drawPath(layer.completeBezierPath) return sf, ma, md
from math import sin, cos, radians if __name__ == "__main__": sys.path.insert( 0, "..") # So we can import pagebotnano003 without installing. from pagebotnano_000 import export W = H = 600 M = 10 R = W / 2 - 2 * M LINES = 50 # Number of lines to draw # Create a new page canvas of 1000 x 1000 px drawBot.newPage(W, H) # Fill page with white background drawBot.fill(1) drawBot.rect(0, 0, W, H) # No fill color drawBot.fill(None) # Set stroke color to red (r, g, b) drawBot.stroke(0, 0, 0.5) drawBot.strokeWidth(4) # Calculate the middle point of the lines mx, my = W / 2, H / 2 for n in range(LINES): angle = radians(360 / LINES) * n drawBot.line((mx, my), (mx + sin(angle) * R, my + cos(angle) * R)) # Export as png file in created _export folder (that does not sync in Github) export('_export/0022-LinesPar.png')
def draw_line(a: tuple, b: tuple) -> None: draw.stroke(random_lighter(), random_lighter(), random_lighter(), 1) draw.strokeWidth(POINT_SIZE / 10) draw.line(a, b)
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")
pbSegments = glyph._segments fill(0, 0, 0, 0.3) stroke(0, 1, 0) drawPath(glyph._path) stroke(None) fill(0) x = 500 y = 400 d = 30 if ONCURVE: stroke(0, 1, 1) p1 = (ONCURVE.x, ONCURVE.y) p = (ONCURVE.x + d, ONCURVE.y + d) line(p, p1) stroke(None) text('On-curve point', p) y -= 20 if QUADRATIC_OFFCURVE: stroke(0, 1, 1) p1 = (QUADRATIC_OFFCURVE.x, QUADRATIC_OFFCURVE.y) p = (QUADRATIC_OFFCURVE.x + d, QUADRATIC_OFFCURVE.y + d) line(p, p1) stroke(None) text('Quadratic control point', p) if CUBIC_OFFCURVE: stroke(0, 1, 1) p1 = (CUBIC_OFFCURVE[0], CUBIC_OFFCURVE[1])
def drawSegment(segment, implied, cps, verbose=False): u""" Draws a quadratic segment as a cubic Bézier curve in drawBot. Each segment starts and ends with an oncurve point with 0 ... n offcurve control points. NOTE: PageBot implementation in glyph adds the first oncurve as a separate `cp` parameter. >>> p0 = Point(100, 100, True) >>> p1 = Point(200, 100, False) >>> p2 = Point(200, 200, True) >>> segment = [p0, p1, p2] >>> drawSegment(segment) """ assert len(segment) > 1 if len(segment) == 2: # Two on curves gives a line. point = segment[-1] path.lineTo((point.x, point.y)) prevOnCurve = (point.x, point.y) if verbose: print(' * line to %d, %d' % (point.x, point.y)) elif len(segment) == 3: # Quadratic offcurve is split into two cubic offcurves. onCurve0 = segment[0] offCurve = segment[1] onCurve1 = segment[2] x0 = onCurve0.x + (offCurve.x - onCurve0.x) * F y0 = onCurve0.y + (offCurve.y - onCurve0.y) * F offCurve0 = (x0, y0) x1 = onCurve1.x - (onCurve1.x - offCurve.x) * F y1 = onCurve1.y - (onCurve1.y - offCurve.y) * F offCurve1 = (x1, y1) circle(x0, y0, r/2, color='blue') circle(x1, y1, r/2, color='blue') onCurve = (onCurve1.x, onCurve1.y) path.curveTo(offCurve0, offCurve1, onCurve) stroke(0, 0, 0, 0.4) line((onCurve0.x, onCurve0.y), offCurve0) line(offCurve1, onCurve) stroke(None) # Store these so they can be used in the infographic. cps.append(offCurve0) cps.append(offCurve1) if verbose: print(' * curve to (%s, %s, %s)' % (offCurve0, offCurve1, onCurve)) else: # Implied points are calculated and inserted. Number depends on amount # of consecutive offcurves. curve0 = segment[:2] curve1 = segment[2:] offCurve0 = segment[1] offCurve1 = segment[2] x = offCurve0.x + (offCurve1.x - offCurve0.x) * 0.5 y = offCurve0.y + (offCurve1.y - offCurve0.y) * 0.5 newOnCurve = Point(x, y, True) # Store these so they can be used in the infographic. implied.append(newOnCurve) circle(x, y, r, color='red') curve0.append(newOnCurve) curve1.insert(0, newOnCurve) if verbose: print(' * Implied point %s' % newOnCurve) # Recurse. # NOTE: PageBot implementation in glyph uses a loop instead of # recursion. drawSegment(curve0, implied, cps) drawSegment(curve1, implied, cps)
f.fontSize(40) f.font("Helvetica") f.align("left") f.append("left\n") f.align("center") f.append("center\n") f.font("Times") f.align("right") f.append("right\n") _, height = f.size() x, y = drawBot.width() * .25, 200 with drawBot.savedState(): drawBot.stroke(0) drawBot.line((x, 0), (x, 1000)) drawBot.text(f, (x, y)) y += height drawBot.text(f, (x, y), align="left") y += height drawBot.text(f, (x, y), align="center") y += height drawBot.text(f, (x, y), align="right") x, y = drawBot.width() * .75, 200 with drawBot.savedState(): drawBot.stroke(0) drawBot.line((x, 0), (x, 1000))
import drawBot drawBot.size(200, 200) drawBot.stroke(0) drawBot.strokeWidth(10) drawBot.fill(None) drawBot.line((40, 40), (40, 160)) drawBot.line((100, 40), (160, 160))
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")
def draw_lines(x_lines, y_lines, mult): tup_pairs = tup_pairs_from_lines(x_lines, y_lines, mult) drawBot.stroke(0) drawBot.strokeWidth(3) for pair in tup_pairs: drawBot.line(*pair)
def pageSetup(self): drawBot.newDrawing() drawBot.newPage("LetterLandscape") pageWidth = drawBot.width() pageHeight = drawBot.height() #drawBot.fill(0,0,0, 0.5) drawBot.stroke(0,0,0,.5) drawBot.strokeWidth(0.5) #this needs major clean up drawBot.line((margin, pageHeight-margin), (pageWidth-dpi, pageHeight-margin)) #xHeight line drawBot.line((margin, pageHeight-margin-self.xHeightTarget), (pageWidth-dpi, pageHeight-margin-self.xHeightTarget)) #baseline drawBot.line((margin, pageHeight-margin-(2.5*self.xHeightTarget)), (pageWidth-dpi, pageHeight-margin-(2.5*self.xHeightTarget))) #xHeight line drawBot.line((margin, pageHeight-margin-self.xHeightTarget-(2.5*self.xHeightTarget)), (pageWidth-dpi, pageHeight-margin-self.xHeightTarget-(2.5*self.xHeightTarget))) #baseline drawBot.line((margin, pageHeight-margin-(5*self.xHeightTarget)), (pageWidth-dpi, pageHeight-margin-(5*self.xHeightTarget))) #xHeight line drawBot.line((margin, pageHeight-margin-self.xHeightTarget-(5*self.xHeightTarget)), (pageWidth-dpi, pageHeight-margin-self.xHeightTarget-(5*self.xHeightTarget))) #baseline #drawBot.rect(margin, pageHeight-margin, pageWidth-dpi, -self.xHeightTarget) pdf = drawBot.pdfImage() # set the pdf data in the canvas self.w.canvas.setPDFDocument(pdf)
def line(self, p1, p2): drawBot.line(p1, p2)
margin = 32 # it's in 0.5 mm increment. 32 = 16 mm bodyHeightOnPaper = d.height( ) - margin * 2 # vertical size of the paper, minus top & bottom margin scale = bodyHeightOnPaper / (m.ascender - m.descender) for l in sel: d.newPage(paperSize) # get position and scale right d.translate(margin, margin) d.scale(scale) # font scaled down to paper size d.translate( 0, -m.descender) # move origin point of the paper to include descender # draw metric lines d.stroke(0, 0, 0, 1) # black d.line((0, m.ascender), (l.width, m.ascender)) # draw ascender d.line((0, m.capHeight), (l.width, m.capHeight)) # draw descender d.line((0, m.xHeight), (l.width, m.xHeight)) # draw descender d.line((0, 0), ((d.width() - margin * 2) / scale, 0)) # draw baseline, all the way to the margin d.line((0, m.descender), (l.width, m.descender)) # draw descender d.stroke(None) d.fill(1, 0, 0, 0.75) path = l.completeBezierPath # outlines including paths and components d.drawPath(path) d.newPage(paperSize) # blank page # 4 Typeset text using the glyphs file as if the instance is already installed d.newPage(paperSize)