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 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 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 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, 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))
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)
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))