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 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 _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 _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 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)
# 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')
M = 20 # Page margin context.newDocument(w=W, h=H) for p in range(PAGES): context.newPage(W, H) for n in range(RECTS): # Compatible to DrawBot: color values between (0, 1) red, green, blue = random(), random(), random() #a = 0.5 + random()*0.5 #context.fill((red, green, blue, a)) context.fill((red, green, blue)) ch = random() x = M + random() * (W - 2 * M - R) # Only in available space y = M + random() * (H - 2 * M - R) if ch < 0.2: context.oval(x, y, R, R) elif ch < 0.4: context.rect(x, y, R, R) else: # Make formatted Flat flavor BabelString instance. bs = context.newString('Hello world on %d,%d' % (x, y), style=dict(font=FONTNAME, fontSize=10)) context.text(bs, (x, y)) #context.saveImage('_export/HelloCircleSquare.gif') # PDF does not support alpha colors. #context.saveDocument('_export/HelloCircleSquare.pdf') # Does not support alpha colors #context.saveDocument('_export/HelloCircleSquare.jpg') context.saveDocument(EXPORT_PATH)
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) # Calculate sorted relative angle pairs. xAngles = {} # X-ref, key is angle, value is list of axisName for axisName in axes: angle = globals()[axisName] if not angle in xAngles: # Ignore overlapping xAngles[angle] = axisName #print xAngles sortedAngles = sorted(xAngles) anglePairs = [] a1 = None for a2 in sortedAngles: if a1 is not None: if abs(a2 - a1) < 35: anglePairs.append((a1, a2)) a1 = a2 # 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['titleFontSize'])), (x - fontSize / 2, y + self.h + fontSize / 4)) # Draw spokes c.fill(None) c.stroke(0.7) c.strokeWidth(1) # Gray on full circle c.newPath() for axisName, angle in self.angles.items(): markerX, markerY = self._angle2XY(angle, self.w / 2) c.moveTo((mx - markerX, my - markerY)) c.lineTo((mx + markerX, my + markerY)) c.drawPath() # Black on range of axis. c.stroke(0) 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() # Pair combinations if anglePairs: c.newPath() for a1, a2 in anglePairs: markerX1, markerY1 = self._angle2XY(a1, self.w / 2) markerX2, markerY2 = self._angle2XY(a2, self.w / 2) c.moveTo((mx + markerX1, my + markerY1)) c.lineTo((mx + markerX2, my + markerY2)) c.moveTo((mx + markerX1 * INTERPOLATION, my + markerY1 * INTERPOLATION)) c.lineTo((mx + markerX2 * INTERPOLATION, my + markerY2 * INTERPOLATION)) c.stroke(0, 0, 1) c.fill(None) 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) # If there are any pairs, draw the interpolation between them #if anglePairs: # for a1, a2 in anglePairs: # axis1 = # helper function: def makeAxisName(axisName): if not axisName in ('wght', 'wdth', 'opsz'): return axisName.upper() return axisName # 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 - 8, tw + 8, th) c.text(fs, (mx + markerX * minM - tw / 2, my + markerY * minM - 4))
from pagebot.contexts import defaultContext as c for p in range(10): c.newPage(1000, 1000) for n in range(50): c.fill((random(), 0, random(), 0.5 + random() * 0.2)) ch = random() x = 20 + random() * 800 y = 20 + random() * 800 if ch < 0.2: c.oval(x, y, 80, 80) elif ch < 0.4: c.rect(x, y, 80, 80) else: c.fontSize(24) c.text('Hello world on %d,%d' % (x, y), (x, y)) c.saveImage('_export/HelloCircleSquare.gif')
def _drawFontCircle(self, px, py): fontSize = self.css('fontSize', self.DEFAULT_FONT_SIZE) markerSize = fontSize * self.R # Calculate the max square size w = self.w - markerSize h = self.h - markerSize context.fill(0.9) context.stroke(None) mx = px + self.pw / 2 my = py + self.ph / 2 # Gray circle that defines the area of the axis extremes. context.oval(px + markerSize / 2, py + markerSize / 2, w, h) # Draw axis spikes first, so we can cover them by the circle markers. axes = self.font.axes # Draw default glyph circle marker in middle. glyphName = self.glyphNames[0] #varLocation = getVarLocation(self.font, self.location) # Show neutral, unless a location is requested varLocation = self.location # = getVarLocation(self.font, self.location) # Show neutral, unless a location is requested self._drawGlyphMarker(None, mx, my, glyphName, fontSize, varLocation, strokeW=3) # Draw angle = 0 for axisName, (minValue, defaultValue, maxValue) in axes.items(): # Draw needles, depending on the axis values and the status of self.location if self.draw3D: needleStart = 0.40 # Just enough overlap with edge of neutral circle marker else: needleStart = 2 / 3 # Start at edge of neutral circle marker rStart = fontSize rEnd = w / 2 if self.location is not None and axisName in self.location: rEnd = rStart + (rEnd - rStart) * self.location[axisName] rStart = fontSize * needleStart #print rStart, rEnd startX, startY = self._angle2XY(angle, rStart) endX, endY = self._angle2XY(angle, rEnd) if (w / 2 + rStart) - rEnd - fontSize > fontSize: startX1, startY1 = self._angle2XY(angle - 180, fontSize / 2) endX1, endY1 = self._angle2XY(angle - 180, (w / 2 + rStart) - rEnd - fontSize) else: startX1 = None context.stroke(None) context.fill(0.3) context.oval(mx + startX - 2, my + startY - 2, 4, 4) context.fill(None) context.stroke(0) context.strokeWidth(1) context.newPath() context.moveTo((mx + startX, my + startY)) context.lineTo((mx + endX, my + endY)) if startX1 is not None: context.moveTo((mx + startX1, my + startY1)) context.lineTo((mx + endX1, my + endY1)) context.drawPath() # Show the glyph shape as it is at the max location of the axis. location = {axisName: maxValue} self._drawGlyphMarker(axisName, mx + endX, my + endY, glyphName, fontSize, location) angle += 360 / len(axes)
context.transform((1, 0, 0, 1, 0, 150)) context.fill(None) context.stroke((0, 0, 0), 20) context.drawPath(glyph.path) context.line((0, 0), (1000, 0)) for index, p in enumerate(glyph.points): if p.onCurve: fs = context.newString('index', style=dict(fill=1, stroke=None, font='Verdana', fontSize=18)) tw, th = context.textSize(fs) context.fill(0) context.stroke(0) context.oval(p.x - 10, p.y - 10, 20, 20) context.text(fs, (p.x - tw / 2, p.y - th / 4)) else: bs = context.newString('index', style=dict(fill=(1, 1, 0), stroke=None, font='Verdana', fontSize=18)) tw, th = context.textSize(bs) context.fill(0.4) context.stroke((0.4, 0.4, 0.4, 0.9)) context.oval(p.x - 10, p.y - 10, 20, 20) context.text(fs, (p.x - tw / 2, p.y - th / 4)) #c.stroke(None) #c.fill(1, 0, 0) #for s in glyph.segments:
align='left', fontSize=fittingSize, lineHeight=fittingSize)) fs += fittingWord c.newPage(W+G*2, H + G*2) myTextBox = c.TextBox(fs, G, G, W, H) myTextBox.draw() myTextBox._drawFrame() myTextBox._drawBaselines(showIndex=True, showY=True, showLeading=True) for pattern in myTextBox.findPattern('Find'): #print pattern px = pattern.x py = pattern.y print pattern print px, py[1] c.stroke(1, 0, 0) c.fill(None) c.oval(px-10, py[1]-10, 20, 20) # Bitcount measures, pixels are 1/10 of Em for yy in range(-3,10): c.stroke(1, 0, 0) c.fill(None) y = (myTextBox.y + myTextBox.h + yy*fittingSize/10 - myTextBox.baseLines[-1][1]) c.line((myTextBox.x, y), (myTextBox.x + myTextBox.w, y)) c.saveImage('_export/testTextLineTextRun.pdf')
def _drawFontCircle(self, px, py): context = self.context # Get context from the parent doc. context.fill(0.9) context.stroke(None) mx = px + self.w / 2 my = py + self.h / 2 # Gray circle that defines the area of context.oval(px, py, 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 bs = context.newString(self.font.info.familyName, style=dict( font=self.style['labelFont'], fontSize=self.style['axisNameFontSize'], textFill=0)) context.text(bs, (px - fontSize / 2, py + self.h + fontSize / 2)) # Draw spokes context.fill(None) context.stroke(0) context.strokeWidth(1) context.newPath() for axisName, angle in self.angles.items(): markerX, markerY = self._angle2XY(angle, self.w / 2) context.moveTo((mx, my)) context.lineTo((mx + markerX, my + markerY)) context.drawPath() # Draw default glyph marker in middle. defaultLocation = {} self._drawGlyphIcon(mx, my, self.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._drawGlyphIcon(mx + markerX, my + markerY, self.glyphName, fontSize / 2, location) # Interpolated DeltaLocation circles. location = { axisName: minValue + (maxValue - minValue) * self.INTERPOLATION } markerX, markerY = self._angle2XY(angle, self.w / 4) self._drawGlyphIcon(mx + markerX * self.INTERPOLATION * 2, my + markerY * self.INTERPOLATION * 2, self.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) bs = context.newString( self.makeAxisName(axisName), style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=axisNameFontSize, fill=self.style.get('axisNameColor', 0))) tw, th = context.textSize(bs) context.fill((0.7, 0.7, 0.7, 0.6)) context.stroke(None) context.rect( mx + markerX - tw / 2 - 4, my + markerY - axisNameFontSize / 2 - th * 1.5 - 4, tw + 8, th) context.text(bs, (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)) ` bs = context.newString( sMaxValue, style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=valueFontSize, fill=self.style.get('axisValueColor', 0))) tw, th = context.textSize(bs) context.fill((0.7, 0.7, 0.7, 0.6)) context.stroke(None) context.rect(mx + markerX - tw / 2 - 4, my + markerY + valueFontSize / 2 + th * 1.5 - 4, tw + 8, th) context.text(bs, (mx + markerX - tw / 2, my + markerY + valueFontSize / 2 + th * 1.5)) # DeltaLocation value interpolationValue = minValue + (maxValue - minValue) * self.INTERPOLATION if interpolationValue < 10: sValue = '%0.2f' % interpolationValue else: sValue = ` int(round(interpolationValue)) ` bs = context.newString( sValue, style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=valueFontSize, fill=self.style.get('axisValueColor', 0))) tw, th = context.textSize(bs) context.fill((0.7, 0.7, 0.7, 0.6)) context.stroke(None) context.rect( mx + markerX * self.INTERPOLATION - tw / 2 - 4, my + markerY * self.INTERPOLATION + valueFontSize / 2 + th * 1.5 - 4, tw + 8, th) context.text(bs, (mx + markerX * self.INTERPOLATION - tw / 2, my + markerY * self.INTERPOLATION + valueFontSize / 2 + th * 1.5)) # DeltaLocation value if minValue < 10: sValue = '%0.2f' % minValue else: sValue = ` int(round(minValue)) ` bs = context.newString( sValue, style=dict(font=self.style.get('labelFont', 'Verdana'), fontSize=valueFontSize, fill=self.style.get('axisValueColor', 0))) tw, th = context.textSize(bs) context.fill((0.7, 0.7, 0.7, 0.6)) context.stroke(None) minM = 0.2 context.rect(mx + markerX * minM - tw / 2 - 4, my + markerY * minM + th * 0.5 - 4, tw + 8, th) context.text(bs, (mx + markerX * minM - tw / 2, my + markerY * minM + th * 0.5))
print 'List of APoints of the glyph:', g.points # Get the 4th APoint instance, that has reference back to the glyph.points[p.index] p = g.points[3] # This is the point we got. print 'glyph.points[3]:', p.x, p.y, 'Glyph:', p.glyph.name, 'Index:', p.index # Change the point position. In DrawBot this works interactive while holding cmd-drag in selected d. d = -80 p.x += d p.y += d p.onCurve = False # Now the glyph is dirty print 'Changed point:', p, 'Glyph is dirty:', g.dirty # Update the cached data, such as glyph.points, glyph.path g.update() print 'Now it is clean. Glyph is dirty:', g.dirty # Draw the changed path c.fill(None) c.stroke(0, 1) c.drawPath(g.path, (0, 0), s) # Draw the position of the points c.stroke((1, 0, 0), 2) c.fill(None) for p in g.points: if p.onCurve: R = 16 else: R = 6 c.oval(p.x * s - R / 2, p.y * s - R / 2, R, R) c.saveImage(EXPORT_PATH)