Exemple #1
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()
Exemple #2
0
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))
Exemple #3
0
 def _initialize(self):
     u"""Initialize the cached data, such as self.points, self.contour, self.components and self.path."""
     self._points = []
     self._contours = []
     self._components = []
     self._segments = []
     coordinates = self.coordinates
     components = self.components
     contours = self.contours
     flags = self.flags
     endPtsOfContours = set(self.endPtsOfContours)
     openContour = None
     openSegment = None
     currentOnCurve = None
     if coordinates or components:
         self._path = path = context.newPath(
         )  # There must be points and/or components, start path
     for index, xy in enumerate(coordinates):
         p = Point(xy, flags[index])
         if p.onCurve:
             currentOnCurve = p
         self._points.append(p)
         if not openContour:
             path.moveTo(xy)
             openContour = []
             self._contours.append(openContour)
         if not openSegment:
             openSegment = Segment()
             self._segments.append(openSegment)
         openSegment.append(p)
         openContour.append(p)
         if index in endPtsOfContours and openContour:
             # If there is an open segment, it may contain mutliple quadratics.
             # Split into cubics.
             if openSegment:
                 currentOnCurve = self._drawSegment(currentOnCurve,
                                                    openSegment, path)
             path.closePath()
             openContour = False
             openSegment = None
         elif p.onCurve:
             currentOnCurve = self._drawSegment(currentOnCurve, openSegment,
                                                path)
             openSegment = None
    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()
Exemple #6
0
    def _initialize(self):
        u"""Initializes the cached data, such as self.points, self.contour,
        self.components and self.path, as side effect of drawing the path image."""
        self._points = []
        self._points4 = [] # Same as self.points property with added 4 spacing points in TTF style.
        self._contours = []
        self._components = []
        self._segments = []
        self._boundingBox = None

        coordinates = self.coordinates # Get list from the font.
        components = self._components # No property call to avoid infinite recursion.
        flags = self.flags
        endPtsOfContours = set(self.endPtsOfContours)
        openContour = False
        openSegment = None
        currentOnCurve = None
        p0 = None

        minX = minY = sys.maxint # Store bounding box as we process the coordinate.
        maxX = maxY = -sys.maxint

        if coordinates or components:
            # TODO: Needs context for DrawBot/Flex usage
            # TODO: Separate path creation from init?
            self._path = path = context.newPath()

        for index, (x, y) in enumerate(coordinates):
            minX = min(x, minX)
            maxX = max(x, maxX)
            minY = min(y, minY)
            maxY = max(y, maxY)

            # Create APoint, to store weakref to self and index for altering the coordinate and onCurve
            p = APoint((x, y), flags[index], self, index) 
            self._points.append(p)

            if not openContour:
                path.moveTo((x, y))
                p0 = p
                currentOnCurve = p
                openContour = []
                self._contours.append(openContour)

            openContour.append(p)

            if not openSegment:
                openSegment = ASegment()
                self._segments.append(openSegment)

            openSegment.append(p)

            # If there is an open segment, it may contain multiple
            # quadratics. Split into cubics.

            if index in endPtsOfContours and openContour:
                # End of contour.
                if openSegment:
                    if not p.onCurve:
                        openSegment.append(p0)

                    currentOnCurve = self._drawSegment(currentOnCurve, openSegment, path)

                path.closePath()
                openContour = None
                openSegment = None

            elif p.onCurve:
                # Inside contour.
                currentOnCurve = self._drawSegment(currentOnCurve, openSegment, path)
                openSegment = None

        # Add spacing points, as default in TTF. No index, as they cannot be written back.
        # Instead, for writing, use self.leftMargin, self.rightMargin and self.width.
        self._points4 = self._points[:] + [
            APoint((minX, 0), self), 
            APoint((0, minY), self), 
            APoint((maxX, 0), self), 
            APoint((0, maxY), self)
        ]
        self._boundingBox = (minX, minY, maxX, maxY)
        self.dirty = False # All cleaned up.
Exemple #7
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)

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