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 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 test_newPage_following(self): drawBot.newDrawing() drawBot.size(400, 500) drawBot.newPage() self.assertEqual(drawBot.width(), 400) self.assertEqual(drawBot.height(), 500) 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 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 drawHeaderFooter(postscriptFontName, fileName): p = Path(fileName) familyName = postscriptFontName.split('-')[0] typeAttributes() text(f'Project: {familyName}', (MARGIN_X1, height() - 14 * FROM_MM_TO_PT), align='left') text(f'Date: {NOW:%Y-%m-%d %H:%M}', (MARGIN_X2, height() - 14 * FROM_MM_TO_PT), align='left') text(f'Fontfile: {postscriptFontName}', (MARGIN_X3, height() - 14 * FROM_MM_TO_PT)) text(f'Characterset: {p.stem}', (MARGIN_X4, height() - 14 * FROM_MM_TO_PT)) text(f'Page {pageCount()-1:0>2d}/', (MARGIN_X5, height() - 14 * FROM_MM_TO_PT), align='right') text(f'© {NOW:%Y}' + ' ' + MY_NAME, (MARGIN_X1, MARGIN_BOTTOM / 2))
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 _initPage(self, fontStyles): db.newPage('A3Landscape') db.fontSize(BODY_SIZE_TEXT) quota = db.height() - PDF_MARGIN self._drawHeader(quota, fontStyles) db.font('LucidaGrande') quota -= TAB_LINE_HEIGHT * 2 return quota
def test_newPage_empty_multiple(self): drawBot.newDrawing() drawBot.newPage() drawBot.newPage() drawBot.newPage() self.assertEqual(drawBot.width(), 1000) self.assertEqual(drawBot.height(), 1000) self.assertEqual(drawBot.pageCount(), 3)
def startNewPage(pageWidth, pageHeight, margin, header): db.newPage(pageWidth, pageHeight) # Draw the header with db.savedState(): fs = db.FormattedString("%s Glyph Overview\n" % HEADER_STYLENAME, font="Tilt Neon", fontSize=15) fs.append("by Andy Clymer\n%s" % HEADER_URL, font="Tilt Neon", fontSize=8) db.translate(margin, db.height() - header - margin) db.textBox(fs, (0, 0, db.width() - (margin * 2), header))
def test_image(test: unittest.TestCase, path, rect=Rect(300, 300)): img = (renders / path) hash_before = hash_img(img) if img.exists(): img.unlink() test.assertEqual(img.exists(), False) with new_drawing(rect, save_to=img) as (i, r): yield (i, r) test.assertEqual(r.w, db.width()) test.assertEqual(r.h, db.height()) hash_after = hash_img(img) test.assertEqual(hash_after, hash_before) test.assertEqual(img.exists(), True)
d.rect(c.x - radius, c.y - radius, radius * 2, radius * 2) # draw anchors as circles radius = 5 d.fill(1, 0.5, 0, 1) # set orange colour for fill d.stroke(0, 0, 1, 0.5) # set semi-transparent blue for stroke d.fontSize(12) for a in l.anchors: d.oval(a.x - radius, a.y - radius, radius * 2, radius * 2) d.text(a.name, (a.x, a.y + 10)) # anchor name while I'm at it d.newPage(paperSize) # blank page # 3 The size and position were probably wrong. Let's fix that by using the font metrics. 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
def caption(name): typeQualities(12, 12) text(name, (width() / 2, height() - 20), align='center')
# from the project folder from HSLdonut import hslDonut ### Variables discs = 16 rings = 22 ringThickness = 5 holeRadius = 45 ### Instructions if __name__ == '__main__': newDrawing() newPage(952, 488) translate(width() * .27, height() * .25) save() for eachDisc in range(discs): with savedState(): scale(1, .65) hslDonut(rings, ringThickness, holeRadius, fixedValue=eachDisc / (discs - 1), isLuminosityConst=True, captions=False) translate(0, 16) restore() translate(width() * .44, 0) save()
def initPage(): newPage('A4') quota = height()-MARGIN drawHeader(quota) quota -= CELL_HGT return quota
def background(clr): fill(*clr) rect(0, 0, width(), height())
import GlyphsApp import subprocess from datetime import date today = date.today() f = Glyphs.font sf = 1000 / f.upm paperSize = "A4Landscape" annoThickness = 3 d.newDrawing() # Title page d.newPage(paperSize) margin = 20 d.font(".SF Compact Display Thin", 36) creationDate = "%s %s %s" % (today.day, today.strftime("%B"), today.year) d.text("%s\nPer-glyph Comments" % f.familyName, (margin * 3, d.height() / 2)) d.font(".SF Compact Display Regular", 10) d.text(creationDate, margin, margin) 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
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
def page(): if db: return Rect((0, 0, db.width(), db.height())) else: raise ImportError( "DrawBot was not found, so `page` cannot be called")
def page_rect() -> Rect: return Rect(db.width(), db.height())
alltxtFiles = collectFilesPaths(TXT_FOLDER, 'txt') # iterate over all fonts and text files and draw the pages for eachFontPath in allFonts: for fileName in alltxtFiles: postscriptFontName = installFont(eachFontPath) proofSet = readStringsFromFile(fileName) drawProof(proofSet, postscriptFontName) # get all pages allPages = pages() # count how many pages are available totalPages = len(allPages) # loop over allpages for page in allPages: # set the page as current context with page: # draw the total pagecount in each of them typeAttributes() text(f'{totalPages}', (270 * FROM_MM_TO_PT, height() - 14 * FROM_MM_TO_PT), align='left') projectName = postscriptFontName.split('-') saveTo = f'{PROOF_FOLDER}/{projectName[0]}-proof-{NOW:%Y-%m-%d}.pdf' saveImage(saveTo) if AUTO_OPEN: os.system(f"open -a Preview {saveTo}")
txt += "encaissasses seize cas cane ni nies naine cessasses cessas sens an aise assainissez zen scia sains cannisses sana sic sis seize cannisse assainissez encaissasses encaissiez encaissassiez encens essais aines encaissez encaissassiez casasses scies cas cas incises zinc an ans incisasse sens sise sis canna canisse saines aines cessa assainisses naissais inca encan cannes cassas anis ces encaisse nazies ac assassiniez science aisance sic sciences canne zinc naisses canines cas naine cas encaissiez se saisie assainissez cc encaissais sans incisassiez sain saisissez cessassiez se sic ceci anse ac aines ananas saisissiez nia encaissez aise zizanies saisies nain ci ai cannas nez saisi nias ananas naine ancien cc naissance" # Spacing txt += "\n" * 2 for glyphName in txt.listFontGlyphNames(): txt.appendGlyph("n", "n", glyphName, "n", "n", "space") txt.appendGlyph("e", "e", glyphName, "e", "e", "space") while txt: drawBot.newPage("A4Landscape") txt = drawBot.textBox(txt, (40, 40, drawBot.width()-80, drawBot.height()-100)) # Add the date and name of the font psName = drawBot.font(fontURL) drawBot.font("Arial") drawBot.fontSize(11) drawBot.text(psName, (40, 40)) date = datetime.today().strftime("%d/%m/%Y") drawBot.text(date,(drawBot.width()-40,40), align="right") drawBot.saveImage("specimen.pdf") drawBot.endDrawing()
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)) ### Instructions if __name__ == '__main__': newDrawing() newPage(400, 400) fill(.8) rect(0, 0, width(), height()) translate(width() / 2, height() / 2) hslDonut(rings=8, ringThickness=15, holeRadius=45, fixedValue=.75, isLuminosityConst=False) saveImage('HSL Donut L.pdf') endDrawing()
import drawBot f = CurrentFont() s = CurrentFont().selection fontName = '%s-%s' % (f.info.familyName, f.info.styleName) if s is not None: drawBot.newPage('Letter') drawBot.font(fontName) drawBot.fontSize(200) txt = str(s) for char in "[ ' ] ": txt = txt.replace(char, "") drawBot.textBox(txt, (100, 0, drawBot.width() - 60, drawBot.height() - 120), align="left") drawBot.printImage()
if not os.path.exists(localPath): continue w, h = drawBot.imageSize(path) a = compareImages(localPath, path) padding = 0 if a > 0.0012: padding = 50 pathPadding = 30 drawBot.newPage(w * 4 + padding * 2, h + padding * 2 + pathPadding) drawBot.translate(0, pathPadding) if padding: with drawBot.savedState(): drawBot.fill(None) drawBot.stroke(1, 0, 0) drawBot.strokeWidth(padding * 2) drawBot.rect(0, 0, drawBot.width(), drawBot.height()) drawBot.translate(padding, padding) drawBot.text(f"{os.path.basename(path)} - {os.path.basename(localPath)}", (10, 10 - padding - pathPadding)) drawBot.image(path, (0, 0)) drawBot.image(localPath, (w, 0)) im1 = Image.open(path) im2 = Image.open(localPath) diff = ImageChops.difference(im1, im2) with tempfile.NamedTemporaryFile("wb", suffix=".png") as f: diff.save(f, "png") imDiff = drawBot.ImageObject(f.name) drawBot.image(imDiff, (w * 2, 0))