def _drawGlyphMarker(self, axisName, mx, my, glyphName, fontSize, location, strokeW=2): # Middle circle context.fill(1) context.stroke(0.7) context.strokeWidth(strokeW) context.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 = context.newString(axisName, style=dict(font=variableFont.installedName, fontSize=fontSize / 4, textFill=0)) tw, th = context.textSize(fs) context.text( fs, (mx - tw / 2, my - fontSize / 2 * self.R - th * 2 / 3)) glyphPathScale = fontSize / self.font.info.unitsPerEm context.drawGlyphPath(variableFont, glyphName, mx, my - fontSize / 3, s=glyphPathScale, fillColor=0)
def drawSpiral(): mx = W/2+X my = H/2+Y runs = False c.newPath() c.moveTo((mx, my)) for n in range(0, int(N), 4): dx1 = n*Sx*D dy1 = n*Sy*D dx2 = (n+1)*Sx*D dy2 = (n+1)*Sy*D dx3 = (n+2)*Sx*D dy3 = (n+2)*Sy*D dx4 = (n+3)*Sx*D dy4 = (n+3)*Sy*D #dx5 = (n+4)*Sx*D #dy5 = (n+4)*Sy*D if not runs: c.moveTo((mx, my)) else: c.curveTo((mx-dx1*Exy, my-dy1), (mx-dx1, my-dy1*Exy), (mx-dx1, my)) c.curveTo((mx-dx2, my+dy2*Exy), (mx-dx2*Exy, my+dy2), (mx, my+dy2)) c.curveTo((mx+dx3*Exy, my+dy3), (mx+dx3, my+dy3*Exy), (mx+dx3, my)) c.curveTo((mx+dx4, my-dy4*Exy), (mx+dx4*Exy, my-dy4), (mx, my-dy4)) runs = True c.fill(None) c.stroke(0) c.drawPath()
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): context.newPage(w, h) context.fill(0) context.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): context.newPage(w, h) context.fill(0) context.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 drawSierpinskiSquare(px, py, w, maxW): if w < 1: return for x in range(3): for y in range(3): if x == 1 and y == 1: context.fill(max(0, 0.75 - w/100)) context.rect(px+w, py+w, w, w) elif px <= maxW and py <= maxW: drawSierpinskiSquare(px+x*w, py+y*w, w/3, maxW)
def drawLayers(fss): # Draw this layer in a couple of frame _, h = fss[0].size() h += padding for n in range(frameLength): context.newPage(W, h) context.fill( (backgroundColor[0], backgroundColor[1], backgroundColor[2])) context.rect(0, 0, W, h) for fs in fss: context.text(fs, (2 * padding, -padding))
def makeRunningLeds(s, w, h, px, py, speed=1): context.newPage(w, h) context.fill(0) context.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 drawString(s, px, py, fontName, color=None, gridColor=None): if fontName in FONTS: fontName = FONTS[fontName] context.font(fontName) context.fontSize(FS) context.stroke(None) if color is not None: r, g, b, t = color context.fill((r, g, b, t)) else: context.fill(color or 0) context.text(s, (px, py))
def drawSierpinskiSquare(px, py, w, maxW): if w < 1: return for x in range(3): for y in range(3): if x == 1 and y == 1: c = max(0, 0.5 - 0.5 * w / W) context.fill((random(), c, c)) #print x, y, w, 0.5*w/W context.rect(px + w, py + w, w, w) elif px <= maxW and py <= maxW: drawSierpinskiSquare(px + x * w, py + y * w, w / 3.0, maxW)
def drawLayers(fss1, fss2): # Draw this layer in a couple of frame context.newPage(W, H) context.frameDuration(fd) context.fill((backgroundColor[0], backgroundColor[1], backgroundColor[2])) context.rect(0, 0, W, H) y = 3 * padding offsetY = -100 for fs in fss1: context.text(fs, (2 * padding, y + offsetY + 310)) for fs in fss2: context.text(fs, (2.35 * padding, y + offsetY + 5))
def pathFilter(e, path, view): r = 24 for x in range(0, e.w * 4, 30): for y in range(0, e.h * 2, 30): # Use the glyph to query for color at this position. if e.glyph.onBlack((x, y)): context.fill((random(), random(), random())) # Color as one tuple, in context API context.oval(x - r / 2, y - r / 2, r, r) else: context.fill((0, 1, 0)) # Color as one tuple, in context API context.rect(x - r / 4, y - r / 4, r / 2, r / 2)
def drawLayers(fss, fontSize): # Draw this layer in a couple of frame offsetX = 0 offsetY = -20 _, h = fss[0].size() h += M context.newPage(W, h) context.fill(Background_Color) context.rect(0, 0, W, h) for fs in fss: context.text(fs, (M + offsetX, M + offsetY)) offsetX += Layer_Offset_X offsetY += Layer_Offset_Y
def drawLayers(layers): # Draw this layer in a couple of frame # Calculate the pixel size. 100 units on 1000 Em. #pixelSize = x = M y = 0 _, h = layers[0]['text'].size() h += M / 2 context.newPage(W, h) context.fill(Background_Color) context.rect(0, 0, W, h) for layerIndex, layer in sorted(layers.items()): context.text(layer['text'], (x, y)) x += layer['offsetX'] y += layer['offsetY']
def drawLayers(fss, frame, dx, dy, doNewPage): # Draw this layer in a couple of frame if doNewPage: context.newPage(W, H) context.fill(0) context.rect(0, 0, W, H) context.frameDuration(fd) #context.fill(backgroundColor[0],backgroundColor[1],backgroundColor[2]) #context.rect(0, 0, W, H) y = 2*padding + dy for fsSingle, fsDouble in fss: if frame < frames/2: fs = fsSingle else: fs = fsDouble context.text(fs, (dx*2*padding, y))
def makeAnimation(): axes = vMasterFont.axes print 'Variable A X E S' for axisName, (minValue, defaultValue, maxValue) in vMasterFont.axes.items(): print axisName, 'minValue', minValue, 'defaultValue', defaultValue, 'maxValue', maxValue location = getDefaultLocation(axes) if TERMINAL_VALUES_S[TerminalValue] != 'None': location[TERMINALS[TerminalShape]] = TERMINAL_VALUES[TerminalValue] if SKELETON_VALUES[SkeletonValue] != 'None': location[SKELETONS[SkeletonShape]] = SKELETON_VALUES[SkeletonValue] if BLEND_VALUES[BlendValue] != 'None': location[BLENDS[BlendShape]] = BLEND_VALUES[BlendValue] location['wmx2'] = WEIGHT_VALUES[WeightValue - 2] #for sequence in getProofSequences(): # for location in getLocations(axes, sequence): # Expand into a sequence of locations. # newPage(W, H) context.fill(1) context.rect(0, 0, W, H) context.save() textColor = 0 for gIndex, glyph in enumerate(TEXT): # Only works by glyph name. drawGlyphPath(vMasterFont.ttFont, glyph, S * 40 + S * gIndex * 6 * 9, S * 22, location=location, s=S * 0.04, fillColor=textColor) drawGlyphPath(vMasterFont.ttFont, glyph, S * 40 + S * gIndex * 6 * 9, S * 22, location=location, s=S * 0.04, fillColor=textColor) # TODO To be extended PageBot #drawGlyphPaths(vMasterFont, TEXT, x=S*40 + S*gIndex*6*9, y=S*22, location=location, fontSize=S*0.04, fillColor=textColor) context.restore() context.fill(0) context.fontSize(24)
def drawPageFrame(w): c.fill(1) c.stroke(0) c.newPath() c.moveTo((PADDING, H - PADDING)) c.lineTo((PADDING + w, H - PADDING)) c.lineTo((PADDING + w, H / 2 + PADDING)) c.curveTo((PADDING + w / 2, H / 2 + PADDING), (PADDING + w / 2, H / 2 + PADDING - M / 2), (PADDING, H / 2 + PADDING - M / 2)) c.closePath() c.drawPath() c.fill(None) c.stroke(0.5) c.strokeWidth(4) leading = 14 for n in range(10): c.line( (PADDING + M, H - 5 * PADDING - n * leading), (PADDING + w - M - LINE_ENDINGS[n], H - 5 * PADDING - n * leading))
def _drawGlyphMarker(self, mx, my, glyphName, markerSize, location, strokeW=2): # Middle circle c.fill(1) c.stroke(0) c.strokeWidth(strokeW) c.oval(mx - markerSize / 2, my - markerSize / 2, markerSize, markerSize) glyphPathScale = markerSize / self.font.info.unitsPerEm * 3 / 4 drawGlyphPath(self.font.ttFont, glyphName, mx, my - markerSize / 4, location, s=glyphPathScale, fillColor=0)
def _drawGlyphMarker(self, mx, my, glyphName, fontSize, location, strokeW=2): # Middle circle c.fill(1) c.stroke(0) c.strokeWidth(strokeW) c.oval(mx - fontSize * self.R, my - fontSize * self.R, fontSize * 2 * self.R, fontSize * 2 * self.R) glyphPathScale = fontSize / self.font.info.unitsPerEm drawGlyphPath(self.font.ttFont, glyphName, mx, my - fontSize / 4, location, s=glyphPathScale, fillColor=0)
def draw(w): u""" Draw 3 lines of text: the boundaries of with the width axis and the interpolated width from the slider value. If the slider goes of the extremes, then the middle line stops at the boundary width. """ d = fitVariableWidth(f, HEADLINE, w, HEADLINE_SIZE, condensedLocation, wideLocation) c.newPage(W, H) c.fill(1) c.rect(0, 0, W, H) c.text(d['condensedFs'], (PADDING, 50)) c.text(d['fs'], (PADDING, 100)) c.text(d['wideFs'], (PADDING, 150)) c.fill(None) c.stroke(0) c.line((PADDING, PADDING), (PADDING, H-PADDING)) c.line((PADDING+d['condensedWidth'], PADDING), (PADDING+d['condensedWidth'], H-PADDING)) c.line((PADDING+d['width'], PADDING), (PADDING+d['width'], H-PADDING)) c.line((PADDING+d['wideWidth'], PADDING), (PADDING+d['wideWidth'], H-PADDING)) c.stroke(None) c.fill(0) c.text('%d %0.2f' % (round(d['condensedWidth']), d['condensedLocation']['wdth']), (PADDING + d['condensedWidth'] + 5, PADDING)) c.text('%d %0.2f' % (round(d['width']), d['location']['wdth']), (PADDING + d['width'] + 5, PADDING)) c.text('%d %0.2f' % (round(d['wideWidth']), d['wideLocation']['wdth']), (PADDING + d['wideWidth'] + 5, PADDING)) c.stroke(1, 0, 0) c.line((PADDING+w, PADDING), (PADDING+w, H-PADDING)) c.stroke(None) c.fill(1, 0, 0) c.text('Column %d' % w, (PADDING+w+5, H-PADDING-5))
def draw(self, page, x, y): u"""Draw the circle info-graphic, showing most info about the variation font as can be interpreted from the file.""" c.fill(0.9) c.stroke(None) mx = x + self.w / 2 my = y + self.h / 2 # Gray circle that defines the area of c.oval(x, y, self.w, self.h) # Draw axis spikes first, so we can cover them by the circle markers. axes = self.font.axes fontSize = self.style.get('fontSize', self.DEFAULT_FONT_SIZE) # Draw name of the font c.fill(0) c.text( c.newString(self.font.info.familyName, style=dict(font=self.style['labelFont'], fontSize=self.style['axisNameFontSize'])), (x - fontSize / 2, y + self.h + fontSize / 2)) # Draw spokes c.fill(None) c.stroke(0) c.strokeWidth(1) c.newPath() for axisName, angle in self.angles.items(): markerX, markerY = self._angle2XY(angle, self.w / 2) c.moveTo((mx, my)) c.lineTo((mx + markerX, my + markerY)) c.drawPath() # Draw default glyph marker in middle. glyphName = self.glyphNames[0] defaultLocation = {} self._drawGlyphMarker(mx, my, glyphName, fontSize, defaultLocation, strokeW=3) # Draw DeltaLocation circles. for axisName, (minValue, defaultValue, maxValue) in axes.items(): angle = self.angles[axisName] # Outside maxValue location = {axisName: maxValue} markerX, markerY = self._angle2XY(angle, self.w / 2) self._drawGlyphMarker(mx + markerX, my + markerY, glyphName, fontSize / 2, location) # Interpolated DeltaLocation circles. location = { axisName: minValue + (maxValue - minValue) * INTERPOLATION } markerX, markerY = self._angle2XY(angle, self.w / 4) self._drawGlyphMarker(mx + markerX * INTERPOLATION * 2, my + markerY * INTERPOLATION * 2, glyphName, fontSize / 2, location) # Draw axis names and DeltaLocation values if self.showAxisNames: for axisName, (minValue, defaultValue, maxValue) in axes.items(): angle = self.angles[axisName] location = {axisName: maxValue} valueFontSize = self.style.get('valueFontSize', 12) axisNameFontSize = self.style.get('axisNameFontSize', 12) markerX, markerY = self._angle2XY(angle, self.w / 2) fs = c.newString( makeAxisName(axisName), style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=axisNameFontSize, fill=self.style.get('axisNameColor', 0))) tw, th = c.textSize(fs) c.fill(0.7, 0.7, 0.7, 0.6) c.stroke(None) c.rect(mx + markerX - tw / 2 - 4, my + markerY - axisNameFontSize / 2 - th * 1.5 - 4, tw + 8, th) c.text(fs, (mx + markerX - tw / 2, my + markerY - axisNameFontSize / 2 - th * 1.5)) # DeltaLocation master value if maxValue < 10: sMaxValue = '%0.2f' % maxValue else: sMaxValue = ` int(round(maxValue)) ` fs = c.newString( sMaxValue, style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=valueFontSize, fill=self.style.get('axisValueColor', 0))) tw, th = c.textSize(fs) c.fill(0.7, 0.7, 0.7, 0.6) c.stroke(None) c.rect(mx + markerX - tw / 2 - 4, my + markerY + valueFontSize / 2 + th * 1.5 - 4, tw + 8, th) c.text(fs, (mx + markerX - tw / 2, my + markerY + valueFontSize / 2 + th * 1.5)) # DeltaLocation value interpolationValue = minValue + (maxValue - minValue) * INTERPOLATION if interpolationValue < 10: sValue = '%0.2f' % interpolationValue else: sValue = ` int(round(interpolationValue)) ` fs = c.newString( sValue, style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=valueFontSize, fill=self.style.get('axisValueColor', 0))) tw, th = c.textSize(fs) c.fill(0.7, 0.7, 0.7, 0.6) c.stroke(None) c.rect( mx + markerX * INTERPOLATION - tw / 2 - 4, my + markerY * INTERPOLATION + valueFontSize / 2 + th * 1.5 - 4, tw + 8, th) c.text( fs, (mx + markerX * INTERPOLATION - tw / 2, my + markerY * INTERPOLATION + valueFontSize / 2 + th * 1.5)) # DeltaLocation value if minValue < 10: sValue = '%0.2f' % minValue else: sValue = ` int(round(minValue)) ` fs = c.newString( sValue, style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=valueFontSize, fill=self.style.get('axisValueColor', 0))) tw, th = c.textSize(fs) c.fill(0.7, 0.7, 0.7, 0.6) c.stroke(None) minM = 0.2 c.rect(mx + markerX * minM - tw / 2 - 4, my + markerY * minM + th * 0.5 - 4, tw + 8, th) c.text(fs, (mx + markerX * minM - tw / 2, my + markerY * minM + th * 0.5))
def drawFontLabel(p, varFamily, f, fIndex=None, fAxis=None): x, y = p print f.info.styleName, f.info.weightClass, f.info.widthClass glyphH = f[GLYPH] if not glyphH.width: print glyphH, 'No width' return s = 0.05 * 1000 / f.info.unitsPerEm leading = 2048 / f.info.unitsPerEm stroke(None) fill(0) save() translate(x - glyphH.width / 2 * s, y - leading - 50) scale(s) drawPath(glyphH.path) restore() y -= leading + 50 save() pathLabel = '-'.join(path2Name(f.path).split('-')[1:]) #label = path2Name(f.path) if fAxis is not None: label = '@' + fAxis elif fIndex is None: label = '' else: label = '#%d ' % fIndex label += '%s\n(%s)\n%d' % (pathLabel.replace('.ttf', '').replace( '_', '\n').replace('-', '\n'), f.info.styleName, f.info.weightClass) fs = FormattedString(label, fontSize=10, align='center') tw, th = textSize(fs) text(fs, (x - tw / 2, y - 14)) restore() y -= leading + th - 22 # Draw marker on actual position of H.stem and H.weight as green dot stemValues = f.analyzer.stems.keys() if stemValues: # Cannot find H-stem, skip this marker stem = min(stemValues) # XOPQ (counter) + H.stem == H.width - H.stem - H.lsb - H.rsb width = glyphH.width - stem - glyphH.leftMargin - glyphH.rightMargin c.fill((0, 0.5, 0)) c.stroke(None) R = 16 weightLoc, widthLoc = stem, width / 2 c.oval(weightLoc - R / 2, widthLoc - R / 2, R, R) if fAxis is not None: label = '@' + fAxis elif fIndex is None: label = '' else: label = '#%d\n' % fIndex bs = c.newString(label + ('S:%d\nW:%d\n%d' % (weightLoc, widthLoc, f.info.weightClass)), style=dict(fontSize=10, xTextAlign='center', textFill=0)) tw, th = c.textSize(bs) c.text(bs, (weightLoc - tw / 2, widthLoc - 24)) if varFamily.originFont is f: # If one of these is the guessed origin font, then draw marker c.fill(None) c.stroke((0, 0.5, 0), 2) # Stroke color and width R = 23 c.oval(weightLoc - R / 2, widthLoc - R / 2, R, R) else: pass
# P A G E B O T # # Copyright (c) 2016+ Buro Petr van Blokland + Claudia Mens & Font Bureau # www.pagebot.io # Licensed under MIT conditions # # Supporting usage of DrawBot, www.drawbot.com # Supporting usage of Flat, https://github.com/xxyxyz/flat # ----------------------------------------------------------------------------- # from pagebot.contexts import defaultContext as c c.newPage(1000, 1000) fs = c.newString("b", style=dict(lineHeight=74, font="Times", fontSize=38)) fs += c.newString("hello world ", style=dict(font="Helvetica", fontSize=10, lineHeight=12)) fs += c.newString("hi agian " * 10) r = (10, 10, 200, 200) c.textBox(fs, r) c.fill(None) c.stroke(1, 0, 0) c.rect(*r) positions = c.textBoxBaseLines(fs, r) s = 2 for x, y in positions: c.oval(x - s, y - s, s * 2, s * 2)
# This script shows the behavior of FormattedStrings in DrawBot Context. # Tracking is added after the glyphs, so the measured width of a tracked # string is wider that it looks. # To safely measure the real width of the string, the width of one "track" # needs to be subtracted. from pagebot.contexts import defaultContext as context # Create a new page w, h = 400, 100 context.newPage(w, h) # Draw vertical line in the middle of the page as reference. context.fill(None) context.strokeWeight = 0.5 context.stroke((0, 0, 0.4)) context.line((w / 2, 0), (w / 2, h)) TRACKING = 1 FONT_SIZE = 14 TRACKED_SPACE = FONT_SIZE * TRACKING # New Babel string, probably DrawBot FormattedString flavor. bs = context.newString('TRACKEDSTRING', style=dict(font='Verdana', fontSize=FONT_SIZE, rTracking=TRACKING)) # Call DrawBot textSize to determine the size of the string # including the tracking tw, th = bs.size()
def drawBackground(self): c.fill(1) c.rect(0, 0, W, H)
def draw(self, orgX, orgY): if not self.show: return w = self.w # Width of the icon h = self.ih # Height of the icon e = self.E * self.scale # Ear size l = self.L * self.scale # Line x = self.x + orgX y = self.y + orgY path = c.newPath() c.moveTo((0, 0)) c.lineTo((0, h)) c.lineTo((w - e, h)) c.lineTo((w, h - e)) c.lineTo((w, 0)) c.lineTo((0, 0)) c.closePath() c.moveTo((w - e, h)) c.lineTo((w - e, h - e)) c.lineTo((w, h - e)) c.saveGraphicState() c.fill(1) c.stroke(0) c.strokeWidth = self.line c.moveTo((x, y)) c.drawPath(path) labelSize = e fs = c.newString(self.char, style=dict(font=self.f.installedName, textFill=0, fontSize=h * 2 / 3)) tw, th = c.textSize(fs) c.text(fs, (w / 2 - tw / 2, h / 2 - th / 3.2)) if self.title: fs = c.newString(self.title, style=dict(font=self.labelFont.installedName, textFill=0, rTracking=self.LABEL_RTRACKING, fontSize=labelSize)) tw, th = c.textSize(fs) c.text(fs, (w / 2 - tw / 2, self.ih + th / 2)) y = -self.LABEL_RLEADING * labelSize if self.name: fs = c.newString(self.name, style=dict(font=self.labelFont.installedName, textFill=0, rTracking=self.LABEL_RTRACKING, fontSize=labelSize)) tw, th = c.textSize(fs) c.text(fs, (w / 2 - tw / 2, y)) y -= self.LABEL_RLEADING * labelSize if self.label: fs = c.newString(self.label, style=dict(font=self.labelFont.installedName, textFill=0, rTracking=self.LABEL_RTRACKING, fontSize=labelSize)) tw, th = c.textSize(fs) c.text(fs, (w / 2 - tw / 2, y)) c.restoreGraphicState()
def draw(self): # Try to use TYPETR-Bitcount. Only is instsalled in the system. # See samples at https://bitcount.typenetwork.com # Order a license at: https://store.typenetwork.com/foundry/typetr/fonts/bitcount USE_BITCOUNT = True LETTERS = 'ABCEFGHIJKLMNOPQRSTUVWXYZ' Frames = 80 W = H = 500 IMAGE_PATH = '_export/HorizonWorld.gif' if not USE_BITCOUNT or not 'BitcountMonoDouble-RegularCircle' in context.installedFonts( ): fontNames = ['Georgia-Bold', 'Georgia'] else: fontNames = [] for fontName in installedFonts(): if 'BitcountMono' in fontName and not 'Italic' in fontName: fontNames.append(fontName) letters = [] for n in range(10): c = choice(LETTERS) x = 0 y = 15 z = 20 + int(random() * 500) x = 1 / z + random() * 100 - 100 cc = random() * 0.8 + 0.1, random() * 0.1, random() * 0.8 * 0.1 f = choice(fontNames) letters.append((c, f, x, y, z, cc)) for n in range(Frames): context.newPage(W, H) context.fill(0.8) context.rect(0, 0, W, H) for c, f, x, y, z, (r, g, b) in letters: #y = y/z context.fill( (r, g, b) ) # Needs tuple, instead of separate r, g, b as in DrawBot context.font(f) context.stroke(None) fSize = min(200, 40000 / z) context.fontSize(fSize) context.text(c, (x + 250, y + 250 - fSize / 2)) context.fill(None) context.strokeWidth(0.5) context.stroke(0.5) context.line((0, 250), (500, 250)) context.fill( (1, 1, 1, 0.4) ) # Needs tuple, instead of separate r, g, b as in DrawBot context.rect(0, 0, W, H / 2 - 1) for n in range(0, 500, 10): context.fill(None) context.stroke(1) y = W / 2 - 2 - n * 0.4 lineThickness = (random() * 3 + 0.5) * (H / 2 - y) / 10 context.strokeWidth(lineThickness) context.line((0, y - lineThickness / 2), (W, y - lineThickness / 2)) context.saveImage(IMAGE_PATH)
def buildCoverPages1(w, h, v): M = 10 # Page 66 context.newPage(w, h) context.fill(0.1) context.rect(0, 0, w, h) c1 = (0.2, 0.7, 1) c2 = 0.8 y = h - M # Title of cover, make it fit in with and add shadow coverTitleStyle = dict(font='Upgrade-Hairline', fontSize=100, textFill=c1) bs = context.newString('THE', style=coverTitleStyle, w=w - M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= bh - by + M / 2 coverTitleStyle = dict(font='Upgrade-Thin', fontSize=100, textFill=c1) bs = context.newString('LONGEST', style=coverTitleStyle, w=w - 1.5 * M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= bh - by + M / 2 # Title of cover, make it fit in with and add shadow coverTitleStyle = dict(font='Upgrade-ExtraLight', fontSize=100, textFill=c1, rTracking=0.05) bs = context.newString('MELLIFLUOUSLY', style=coverTitleStyle, w=w - 1.5 * M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= bh - by + M / 2 coverTitleStyle = dict(font='Upgrade-Light', fontSize=100, textFill=c1, rTracking=0.07) bs = context.newString('supercalifragilisticexpialidociously'.upper(), style=coverTitleStyle, w=w - 2 * M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= bh - by + M / 2 coverTitleStyle = dict(font='Upgrade-Book', fontSize=100, textFill=c1, rTracking=0.07) bs = context.newString( 'pneumonoultramicroscopicsilicovolcanoconiosis'.upper(), style=coverTitleStyle, w=w - 2 * M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= bh - by + M / 2 coverTitleStyle = dict(font='Upgrade-Light', fontSize=100, textFill=c1) bs = context.newString('INTERMIXED', style=coverTitleStyle, w=w - 1.5 * M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= bh - by + 2 * M # Title of cover, make it fit in with and add shadow coverTitleStyle = dict(font='Upgrade-Light', fontSize=100, textFill=c2) bs = context.newString('MATTHEW', style=coverTitleStyle, w=w - 1.5 * M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= bh - by + M / 2 # Title of cover, make it fit in with and add shadow coverTitleStyle = dict(font='Upgrade-Light', fontSize=100, textFill=c2) bs = context.newString('DOW', style=coverTitleStyle, w=w - M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by))
def buildCoverPages2(w, h, v): M = 30 for pn in range(v): # Page 66 context.newPage(w, h) context.fill(0.1) context.rect(0, 0, w, h) c1 = (0.2, 0.7, 1) c2 = 0.8 y = h - M # Title of cover, make it fit in with and add shadow coverTitleStyle = dict(font='Upgrade-Book', fontSize=100, textFill=1, rTracking=0.2, openTypeFeatures=dict(smcp=True)) bs = context.newString('One Lightyear Equals', style=coverTitleStyle, w=w - 2 * M) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2, y - bh + by)) y -= 100 styleColors = ('Upgrade-UltraBlack', 'Upgrade-ExtraBlack', 'Upgrade-Black', 'Upgrade-Semibold', 'Upgrade-Medium', 'Upgrade-Regular', 'Upgrade-Book', 'Upgrade-Light', 'Upgrade-ExtraLight', 'Upgrade-Thin', 'Upgrade-Hairline') if v == 1: R = 22 else: R = math.sin(math.radians(pn * 360 / v)) * 16 for index, name in enumerate(styleColors): coverTitleStyle = dict(font=name, fontSize=100, textFill=list(c1) + [index / len(styleColors)], rTracking=0.2, rLeading=0.9, openTypeFeatures=dict(tnum=True)) bs = context.newString('9460\n7304\n7258\n0800\n512', style=coverTitleStyle, w=w - M / 2) bx, by, bw, bh = bs.bounds() context.text(bs, (w / 2 - (bw + bx) / 2 + (random() * R - R / 2), -by + 1.5 * M + (random() * R - R / 2))) coverTitleStyle = dict(font='Upgrade-ExtraLight', fontSize=100, textFill=c1, rTracking=0.05, rLeading=0.9) bs = context.newString('mm', style=coverTitleStyle, w=w / 5) bx, by, bw, bh = bs.bounds() context.text(bs, (w * 4 / 6 + M, -by + 3.2 * M)) coverTitleStyle = dict(font='Upgrade-Regular', fontSize=100, textFill=c2, rTracking=0.2, rLeading=1.2, openTypeFeatures=dict(smcp=True)) bs = context.newString('Design\nDesign\nSpace', style=coverTitleStyle, w=w / 5) bx, by, bw, bh = bs.bounds() context.text(bs, (w * 4 / 6 + M, -by + 0.75 * M))
# P A G E B O T # # Copyright (c) 2016+ Buro Petr van Blokland + Claudia Mens & Font Bureau # www.pagebot.io # Licensed under MIT conditions # # Supporting usage of DrawBot, www.drawbot.com # Supporting usage of Flat, https://github.com/xxyxyz/flat # ----------------------------------------------------------------------------- # from random import random from pagebot.contexts import defaultContext as context for p in range(20): context.newPage(1000, 1000) for n in range(50): context.fill((random(), 0, random(), 0.5 + random() * 0.2)) ch = random() x = 20 + random() * 800 y = 20 + random() * 800 if ch < 0.2: context.oval(x, y, 80, 80) elif ch < 0.4: context.rect(x, y, 80, 80) else: bs = context.newString('Hello world on %d,%d' % (x, y), style=dict(fontSize=24)) context.text(bs, (x, y)) context.saveImage('_export/OurNiceDrawing.pdf')
newPage(1000, 1000) font = Font('/Library/Fonts/Georgia.ttf') print font.analyzer print font.analyzer.name glyphH = font['ampersand'] gaH = glyphH.analyzer print gaH print 'H width:', gaH.width, gaH.glyph.width, glyphH.width print 'H bounding box:', gaH.boundingBox # X position of vertical lines also includes sides of serifs. print 'x-position of verticals:', sorted(gaH.verticals.keys()) # Y position of horizontal lines print 'y-position of horizontals:', sorted(gaH.horizontals.keys()) c.stroke(0) c.fill(None) print gaH.glyph.leftMargin x = y = 100 s = 0.25 c.drawPath(glyphH.path, (x, y), s) # Draw markers on the glyph points c.fill((1, 0, 0)) c.stroke(None) for p in glyphH.points: r = {True:5, False:3}[p.onCurve] c.rect(x+p.x*s-r/2, x+p.y*s-r/2, r, r) #c.rect(x, y, 100, 100) # Draw flattened path next to it on H-width distance. c.fill(None) c.stroke(0)
if w < fixedWidth: c.text(d['condensedFs'], (PADDING + M, y - PADDING - M)) elif w < maxWidth: c.text(dFixed['fs'], (PADDING + M, y - PADDING - M)) else: c.text(d['wideFs'], (PADDING + M, y - PADDING - M)) if INTERACTIVE: #dict(name='ElementOrigin', ui='CheckBox', args=dict(value=False)), c.Variable([ dict(name='Width', ui='Slider', args=dict(minValue=PADDING, value=200, maxValue=W - 2 * PADDING)) ], globals()) draw(Width) else: pageFrame = None angle = 0 while angle < 360: c.newPage(W, H) c.fill(0.8) c.rect(0, 0, W, H) dx = sin(radians(angle)) * 0.5 + 0.5 w = W / 2 + (W - 2 * PADDING - W / 2) * dx draw(w, H - PADDING, True) draw(w, (H - PADDING) / 2, False) angle += 360 / FRAMES c.saveImage('_export/fitVariableColumns.gif')