示例#1
0
    def draw(self):
        """
        This function is what Canvas calls to draw
        """

        db.translate(400, 400)
        db.scale(self.scale)

        for letter in self.letters:
            rotateFlag = False
            glyph = self.f[letter]

            pt0 = (glyph.contours[0].points[0].x,
                   glyph.contours[0].points[0].y)
            pt1 = (glyph.contours[0].points[1].x,
                   glyph.contours[0].points[1].y)
            pt2 = (glyph.contours[0].points[-2].x,
                   glyph.contours[0].points[-2].y)
            pt3 = (glyph.contours[0].points[-1].x,
                   glyph.contours[0].points[-1].y)

            if getAngle(pt0, pt1) >= 90 or getAngle(pt0, pt1) <= -90:
                rotateFlag = True
                db.translate(0, -820)

            db.newPath()
            pen = StrokePen(glyph.getParent(), self.widthValue)
            glyph.draw(pen)
            db.drawPath()

            if rotateFlag:
                db.rotate(-90)
                db.translate(0, 0)
            else:
                db.translate(glyph.width, 0)
示例#2
0
    def drawMissingElementRect(self, e, origin):
        u"""When designing templates and pages, this will draw a filled rectangle on the element
        bounding box (if self.css('missingElementFill' is defined) and a cross, indicating
        that this element has missing content (as in unused image frames).
        Only draw if self.css('showGrid') is True."""
        if self.showMissingElementRect:

            p = pointOffset(e.point, origin)
            p = e._applyOrigin(p)
            p = e._applyScale(p)
            px, py, _ = e._applyAlignment(p)  # Ignore z-axis for now.
            self.setShadow()

            sMissingElementFill = self.css('viewMissingElementFill', NO_COLOR)
            if sMissingElementFill is not NO_COLOR:
                setFillColor(sMissingElementFill)
                setStrokeColor(None)
                rect(px, py, self.w, self.h)
            # Draw crossed rectangle.
            setFillColor(None)
            setStrokeColor(0, 0.5)
            rect(px, py, self.w, self.h)
            newPath()
            moveTo((px, py))
            lineTo((px + self.w, py + self.h))
            moveTo((px + self.w, py))
            lineTo((px, py + self.h))
            drawPath()

            self.resetShadow()
            e._restoreScale()
示例#3
0
def hslDonut(rings,
             ringThickness,
             holeRadius,
             fixedValue,
             isLuminosityConst,
             captions=True):
    for angle in range(FULL_CIRCLE):
        for eachRing in range(rings):
            ringFactor = eachRing / (rings - 1)
            radius = holeRadius + eachRing * ringThickness

            if isLuminosityConst:
                rgbClr = hls_to_rgb(angle / FULL_CIRCLE, fixedValue,
                                    ringFactor)
            else:
                rgbClr = hls_to_rgb(angle / FULL_CIRCLE, ringFactor,
                                    fixedValue)
            lineQualities(rgbClr, ringThickness)

            newPath()
            arc((0, 0), radius, angle - .5, angle + .5, clockwise=False)
            drawPath()

        with savedState():
            if angle % 10 == 0 and captions:
                captionRadius = radius + ringThickness
                rotate(angle)

                lineQualities(thickness=.5)
                line((captionRadius - 2, 0), (captionRadius + 2, 0))

                typeQualities()
                text(f'{angle}', (radius + ringThickness + 6, 0))
示例#4
0
    def drawGrid(self, e, origin):
        u"""Draw grid of lines and/or rectangles if colors are set in the style.
        Normally px and py will be 0, but it's possible to give them a fixed offset."""
        # Drawing the grid as squares.
        if not self.showGrid:
            return
        #if not self.showGridColumns or not self.showGrid:
        #    return
        p = pointOffset(e.oPoint, origin)
        p = self._applyScale(p)
        px, py, _ = e._applyAlignment(p)  # Ignore z-axis for now.

        sGridFill = e.css('viewGridFill', NO_COLOR)
        gutterW = e.gw  # Gutter width
        gutterH = e.gh  # Gutter height
        columnWidth = e.cw  # Column width
        columnHeight = e.ch  # Column height
        padL = e.pl  # Padding left
        padT = e.pt  # Padding top
        padR = e.pr  # padding right
        padB = e.pb  # padding bottom
        padW = e.pw  # Padding width
        padH = e.ph  # Padding height

        w = e.w
        h = e.h

        if e.isRight():
            ox = px + padR
        else:
            ox = px + padL
        oy = py + padB

        if self.showGrid and self.css('viewGridStroke',
                                      NO_COLOR) is not NO_COLOR:
            setFillColor(None)
            setStrokeColor(self.css('viewGridStroke', NO_COLOR),
                           self.css('viewGridStrokeWidth'))
            newPath()
            for cx, cw in e.getGridColumns():
                moveTo((ox + cx, oy))
                lineTo((ox + cx, oy + padH))
                moveTo((ox + cx + cw, oy))
                lineTo((ox + cx + cw, oy + padH))
            for cy, ch in e.getGridRows():
                moveTo((ox, oy + cy))
                lineTo((ox + padW, oy + cy))
                moveTo((ox, oy + cy + ch))
                lineTo((ox + padW, oy + cy + ch))
            drawPath()
            #text(fs+repr(index), (ox + M * 0.3, oy + M / 4))
        """
示例#5
0
    def drawCircles(self):
        """
        Draw circle at all points in pointsList
        """
        # db.blendMode("multiply")
        db.fill(1, 0, 0, 1)
        db.stroke(None)

        for point in self.pointsList:
            x, y = point
            db.newPath()
            db.oval(x - self.width / 2, y - self.width / 2, self.width,
                    self.width)
示例#6
0
    def drawPageCropMarks(self, e, origin):
        u"""If the show flag is set, then draw the cropmarks or page frame."""
        if self.showPageCropMarks:
            x, y, _ = point3D(origin)  # Ignore z-axus for now.
            w, h = e.w, e.h
            folds = self.css('folds')
            bleed = self.css('bleed') / 2  # 1/2 overlap with image bleed
            cmSize = min(self.css('viewCropMarkSize', 32), self.pl)
            cmStrokeWidth = self.css('viewCropMarkStrokeWidth')

            fill(None)
            cmykStroke(1, 1, 1, 1)
            strokeWidth(cmStrokeWidth)
            newPath()
            # Bottom left
            moveTo((x - bleed, y))
            lineTo((x - cmSize, y))
            moveTo((x, y - bleed))
            lineTo((x, y - cmSize))
            # Bottom right
            moveTo((x + w + bleed, y))
            lineTo((x + w + cmSize, y))
            moveTo((x + w, y - bleed))
            lineTo((x + w, y - cmSize))
            # Top left
            moveTo((x - bleed, y + h))
            lineTo((x - cmSize, y + h))
            moveTo((x, y + h + bleed))
            lineTo((x, y + h + cmSize))
            # Top right
            moveTo((x + w + bleed, y + h))
            lineTo((x + w + cmSize, y + h))
            moveTo((x + w, y + h + bleed))
            lineTo((x + w, y + h + cmSize))
            # Any fold lines to draw?
            if folds is not None:
                for fx, fy in folds:
                    if fx is not None:
                        moveTo((x + fx, y - bleed))
                        lineTo((x + fx, y - cmSize))
                        moveTo((x + fx, y + h + bleed))
                        lineTo((x + fx, y + h + cmSize))
                    if fy is not None:
                        moveTo((x - bleed, y + fy))
                        lineTo((x - cmSize, y + fy))
                        moveTo((x + w + bleed, y + fy))
                        lineTo((x + w + cmSize, y + fy))
            drawPath()
示例#7
0
    def draw(self, origin, view):
        p = pointOffset(self.oPoint, origin)
        p = self._applyScale(p)
        px, py, _ = p = self._applyAlignment(p)  # Ignore z-axis for now.

        setStrokeColor(self.css('stroke', NO_COLOR), self.css('strokeWidth'))
        newPath()
        moveTo((px, py))
        lineTo((px + self.w, py + self.h))
        drawPath()

        # If there are child elements, draw them over the line.
        self._drawElements(p, view)

        self._restoreScale()
        view.drawElementMetaInfo(self, origin)
示例#8
0
def drawArrow(e, view, xs, ys, xt, yt, onText=1, startMarker=False, endMarker=False):
    u"""Draw curved arrow marker between the two points.
    TODO: Add drawing of real arrow-heads, rotated in the right direction."""
    fms = e.css('flowMarkerSize')
    fmf = e.css('flowCurvatureFactor')
    if onText == 1:
        c = e.css('flowConnectionStroke2', NO_COLOR)
    else:
        c = e.css('flowConnectionStroke1', NO_COLOR)
    setStrokeColor(c, e.css('flowConnectionStrokeWidth'))
    if startMarker:
        setFillColor(e.css('flowMarkerFill', NO_COLOR))
        oval(xs - fms, ys - fms, 2 * fms, 2 * fms)
    xm = (xt + xs)/2
    ym = (yt + ys)/2
    xb1 = xm + onText * (yt - ys) * fmf
    yb1 = ym - onText * (xt - xs) * fmf
    xb2 = xm - onText * (yt - ys) * fmf
    yb2 = ym + onText * (xt - xs) * fmf
    # Arrow head position
    arrowSize = 12
    arrowAngle = 0.4
    angle = atan2(xt-xb2, yt-yb2)
    hookedAngle = radians(degrees(angle)-90)
    ax1 = xt - cos(hookedAngle+arrowAngle) * arrowSize
    ay1 = yt + sin(hookedAngle+arrowAngle) * arrowSize
    ax2 = xt - cos(hookedAngle-arrowAngle) * arrowSize
    ay2 = yt + sin(hookedAngle-arrowAngle) * arrowSize
    newPath()
    setFillColor(None)
    moveTo((xs, ys))
    curveTo((xb1, yb1), (xb2, yb2), ((ax1+ax2)/2, (ay1+ay2)/2)) # End in middle of arrow head.
    drawPath()

    #  Draw the arrow head.
    newPath()
    setFillColor(c)
    setStrokeColor(None)
    moveTo((xt, yt))
    lineTo((ax1, ay1))
    lineTo((ax2, ay2))
    closePath()
    drawPath()
    if endMarker:
        oval(xt - fms, yt - fms, 2 * fms, 2 * fms)
示例#9
0
def drawCropMarks(origin, w, h, bleed, cmSize, cmStrokeWidth, folds=None):
    u"""If the show flag is set, then draw the cropmarks or page frame."""
    x, y, _ = point3D(origin)  # Ignore z-axus for now.
    fill(None)
    cmykStroke(1, 1, 1, 1)
    strokeWidth(cmStrokeWidth)
    newPath()
    # Bottom left
    moveTo((x - bleed, y))
    lineTo((x - cmSize, y))
    moveTo((x, y - bleed))
    lineTo((x, y - cmSize))
    # Bottom right
    moveTo((x + w + bleed, y))
    lineTo((x + w + cmSize, y))
    moveTo((x + w, y - bleed))
    lineTo((x + w, y - cmSize))
    # Top left
    moveTo((x - bleed, y + h))
    lineTo((x - cmSize, y + h))
    moveTo((x, y + h + bleed))
    lineTo((x, y + h + cmSize))
    # Top right
    moveTo((x + w + bleed, y + h))
    lineTo((x + w + cmSize, y + h))
    moveTo((x + w, y + h + bleed))
    lineTo((x + w, y + h + cmSize))
    # Any fold lines to draw?
    if folds is not None:
        for fx, fy in folds:
            if fx is not None:
                moveTo((x + fx, y - bleed))
                lineTo((x + fx, y - cmSize))
                moveTo((x + fx, y + h + bleed))
                lineTo((x + fx, y + h + cmSize))
            if fy is not None:
                moveTo((x - bleed, y + fy))
                lineTo((x - cmSize, y + fy))
                moveTo((x + w + bleed, y + fy))
                lineTo((x + w + cmSize, y + fy))
    drawPath()
示例#10
0
def drawRegistrationMark(origin, cmSize, cmStrokeWidth, vertical):
    u"""Draw registration mark as position x, y."""
    x, y = origin
    if vertical:
        dx = cmSize / 2
        dy = cmSize
    else:
        dx = cmSize
        dy = cmSize / 2
    fill(None)
    cmykStroke(1, 1, 1, 1)
    strokeWidth(cmStrokeWidth)
    newPath()
    # Registration circle
    oval(x - cmSize / 4, y - cmSize / 4, cmSize / 2, cmSize / 2)
    # Registration cross, in length of direction.
    moveTo((x - dx, y))  # Horizontal line.
    lineTo((x + dx, y))
    moveTo((x, y + dy))  # Vertical line.
    lineTo((x, y - dy))
    drawPath()
示例#11
0
 def drawBaselineGrid(self, e, origin):
     u"""Draw baseline grid if line color is set in the style.
     TODO: Make fixed values part of calculation or part of grid style.
     Normally px and py will be 0, but it's possible to give them a fixed offset."""
     if not self.showBaselineGrid:
         return
     p = pointOffset(self.oPoint, origin)
     p = self._applyScale(p)
     px, py, _ = self._applyAlignment(p)  # Ignore z-axis for now.
     M = 16
     startY = e.css('baselineGridStart')
     if startY is None:
         startY = e.pt  # Otherwise use the top padding as start Y.
     oy = e.h - startY  #- py
     line = 0
     # Format of line numbers.
     # TODO: DrawBot align and fill don't work properly now.
     fs = newFS(
         '', self,
         dict(font=e.css('fallbackFont', 'Verdana'),
              xTextAlign=RIGHT,
              fontSize=M / 2,
              stroke=None,
              textFill=e.css('gridStroke')))
     while oy > e.pb or 0:
         setFillColor(None)
         setStrokeColor(e.css('baselineGridStroke', NO_COLOR),
                        e.css('gridStrokeWidth'))
         newPath()
         moveTo((px + e.pl, py + oy))
         lineTo((px + e.w - e.pr, py + oy))
         drawPath()
         text(fs + repr(line), (px + e.pl - 2, py + oy - e.pl * 0.6))
         text(fs + repr(line), (px + e.w - e.pr - 8, py + oy - e.pr * 0.6))
         line += 1  # Increment line index.
         oy -= e.css('baselineGrid'
                     )  # Next vertical line position of baseline grid.
示例#12
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."""
        fill(0.9)
        stroke(None)
        mx = x + self.w / 2
        my = y + self.h / 2

        # Gray circle that defines the area of
        oval(x, y, self.w, self.h)

        # Draw axis spikes first, so we can cover them by the circle markers.
        axes = self.font.axes
        markerSize = 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) < CONNECT:  # Max angle to connect
                    anglePairs.append((a1, a2))
            a1 = a2

        # Draw name of the font
        fill(0)
        text(
            FormattedString(self.font.info.familyName,
                            font=self.style['labelFont'],
                            fontSize=self.style['titleFontSize']),
            (x - markerSize / 2, y + self.h + markerSize / 4))

        # Draw spokes
        fill(None)
        stroke(0.7)
        strokeWidth(1)
        # Gray on full circle
        newPath()
        for axisName, angle in self.angles.items():
            markerX, markerY = self._angle2XY(angle, self.w / 2)
            moveTo((mx - markerX, my - markerY))
            lineTo((mx + markerX, my + markerY))
        drawPath()

        # Black on range of axis.
        stroke(0)
        newPath()
        for axisName, angle in self.angles.items():
            minValue, defaultValue, maxValue = axes[axisName]
            markerX, markerY = self._angle2XY(angle, self.w / 2)
            if minValue < defaultValue:
                moveTo((mx, my))
                lineTo((mx - markerX, my - markerY))
            if defaultValue < maxValue:
                moveTo((mx, my))
                lineTo((mx + markerX, my + markerY))
        drawPath()

        # Pair combinations
        if anglePairs:
            newPath()
            for a1, a2 in anglePairs:
                markerX1, markerY1 = self._angle2XY(a1, self.w / 2)
                markerX2, markerY2 = self._angle2XY(a2, self.w / 2)
                moveTo((mx + markerX1, my + markerY1))
                lineTo((mx + markerX2, my + markerY2))
                moveTo((mx + markerX1 * INTERPOLATION,
                        my + markerY1 * INTERPOLATION))
                lineTo((mx + markerX2 * INTERPOLATION,
                        my + markerY2 * INTERPOLATION))
            stroke(0, 0, 1)
            fill(None)
            drawPath()

        # Draw default glyph marker in middle.
        glyphName = self.glyphNames[0]
        defaultLocation = {}
        self._drawGlyphMarker(mx, my, glyphName, markerSize, defaultLocation)

        # http://stackoverflow.com/questions/1734745/how-to-create-circle-with-bézier-curves

        # Draw DeltaLocation circles.
        for axisName, (minValue, defaultValue, maxValue) in axes.items():
            angle = self.angles[axisName]
            if defaultValue < maxValue:
                # Outside maxValue
                location = {axisName: maxValue}
                markerX, markerY = self._angle2XY(angle, self.w / 2)
                self._drawGlyphMarker(mx + markerX, my + markerY, glyphName,
                                      markerSize, location)

                # Interpolated DeltaLocation circles.
                location = {
                    axisName:
                    defaultValue + (maxValue - defaultValue) * INTERPOLATION
                }
                markerX, markerY = self._angle2XY(angle, self.w / 4)
                self._drawGlyphMarker(mx + markerX * INTERPOLATION * 2,
                                      my + markerY * INTERPOLATION * 2,
                                      glyphName, markerSize, location)

            if minValue < defaultValue:
                # Outside minValue.
                location = {axisName: minValue}
                markerX, markerY = self._angle2XY(angle, self.w / 2)
                self._drawGlyphMarker(mx - markerX, my - markerY, glyphName,
                                      markerSize, location)

                # Interpolated DeltaLocation circles.
                location = {
                    axisName:
                    minValue + (defaultValue - minValue) * INTERPOLATION
                }
                markerX, markerY = self._angle2XY(angle, self.w / 4)
                self._drawGlyphMarker(mx - markerX * 2 * INTERPOLATION,
                                      my - markerY * 2 * INTERPOLATION,
                                      glyphName, markerSize, location)

            # If there are any pairs, draw the interpolation between them
            #if anglePairs:
            #    for a1, a2 in anglePairs:
            #        axis1 =
        # Draw axis names and DeltaLocation values
        if self.showAxisNames:
            for axisName, (minValue, defaultValue, maxValue) in axes.items():
                if minValue < defaultValue:
                    angle = self.angles[axisName]
                    valueFontSize = self.style.get('valueFontSize', 12)
                    axisNameFontSize = self.style.get('axisNameFontSize', 12)
                    markerX, markerY = self._angle2XY(angle, self.w / 2)
                    fs = FormattedString(
                        makeAxisName(axisName),
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=axisNameFontSize,
                        fill=self.style.get('axisNameColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    rect(mx - markerX - tw / 2 - 4,
                         my - markerY - axisNameFontSize / 2 - th * 1.5 - 4,
                         tw + 8, th)
                    text(fs, (mx - markerX - tw / 2,
                              my - markerY - axisNameFontSize / 2 - th * 1.5))

                    # DeltaLocation master value
                    if 0 < minValue < 10:
                        sMinValue = '%0.2f' % minValue
                    else:
                        sMinValue = ` int(round(minValue)) `
                    fs = FormattedString(
                        sMinValue,
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=valueFontSize,
                        fill=self.style.get('axisValueColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    rect(mx - markerX - tw / 2 - 4,
                         my - markerY + valueFontSize / 2 + th * 1.5 - 4,
                         tw + 8, th)
                    text(fs, (mx - markerX - tw / 2,
                              my - markerY + valueFontSize / 2 + th * 1.5))

                    # DeltaLocation value
                    interpolationValue = minValue + (defaultValue -
                                                     minValue) * INTERPOLATION
                    if 0 < interpolationValue < 10:
                        sValue = '%0.2f' % interpolationValue
                    else:
                        sValue = ` int(round(interpolationValue)) `
                    fs = FormattedString(
                        sValue,
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=valueFontSize,
                        fill=self.style.get('axisValueColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    rect(
                        mx - markerX * INTERPOLATION - tw / 2 - 4,
                        my - markerY * INTERPOLATION + valueFontSize / 2 +
                        th * 1.5 - 4, tw + 8, th)
                    text(fs, (mx - markerX * INTERPOLATION - tw / 2,
                              my - markerY * INTERPOLATION +
                              valueFontSize / 2 + th * 1.5))

                    # DeltaLocation value
                    if 0 < defaultValue < 10:
                        sValue = '%0.2f' % defaultValue
                    else:
                        sValue = ` int(round(defaultValue)) `
                    fs = FormattedString(
                        sValue,
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=valueFontSize,
                        fill=self.style.get('axisValueColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    minM = 0.15
                    rect(mx - markerX * minM - tw / 2 - 4,
                         my - markerY * minM - 8, tw + 8, th)
                    text(fs, (mx - markerX * minM - tw / 2,
                              my - markerY * minM - 4))

                if defaultValue < maxValue:
                    angle = self.angles[axisName]
                    valueFontSize = self.style.get('valueFontSize', 12)
                    axisNameFontSize = self.style.get('axisNameFontSize', 12)
                    markerX, markerY = self._angle2XY(angle, self.w / 2)
                    fs = FormattedString(
                        makeAxisName(axisName),
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=axisNameFontSize,
                        fill=self.style.get('axisNameColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    rect(mx + markerX - tw / 2 - 4,
                         my + markerY - axisNameFontSize / 2 - th * 1.5 - 4,
                         tw + 8, th)
                    text(fs, (mx + markerX - tw / 2,
                              my + markerY - axisNameFontSize / 2 - th * 1.5))

                    # DeltaLocation master value
                    if 0 < maxValue < 10:
                        sMaxValue = '%0.2f' % maxValue
                    else:
                        sMaxValue = ` int(round(maxValue)) `
                    fs = FormattedString(
                        sMaxValue,
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=valueFontSize,
                        fill=self.style.get('axisValueColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    rect(mx + markerX - tw / 2 - 4,
                         my + markerY + valueFontSize / 2 + th * 1.5 - 4,
                         tw + 8, th)
                    text(fs, (mx + markerX - tw / 2,
                              my + markerY + valueFontSize / 2 + th * 1.5))

                    # DeltaLocation value
                    interpolationValue = defaultValue + (
                        maxValue - defaultValue) * INTERPOLATION
                    if 0 < interpolationValue < 10:
                        sValue = '%0.2f' % interpolationValue
                    else:
                        sValue = ` int(round(interpolationValue)) `
                    fs = FormattedString(
                        sValue,
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=valueFontSize,
                        fill=self.style.get('axisValueColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    rect(
                        mx + markerX * INTERPOLATION - tw / 2 - 4,
                        my + markerY * INTERPOLATION + valueFontSize / 2 +
                        th * 1.5 - 4, tw + 8, th)
                    text(fs, (mx + markerX * INTERPOLATION - tw / 2,
                              my + markerY * INTERPOLATION +
                              valueFontSize / 2 + th * 1.5))

                    # DeltaLocation value
                    if defaultValue < 10:
                        sValue = '%0.2f' % defaultValue
                    else:
                        sValue = ` int(round(defaultValue)) `
                    fs = FormattedString(
                        sValue,
                        font=self.style.get('labelFont', 'Verdana'),
                        fontSize=valueFontSize,
                        fill=self.style.get('axisValueColor', 0))
                    tw, th = textSize(fs)
                    fill(0.7, 0.7, 0.7, 0.6)
                    stroke(None)
                    minM = 0.15
                    rect(mx + markerX * minM - tw / 2 - 4,
                         my + markerY * minM - 8, tw + 8, th)
                    text(fs, (mx + markerX * minM - tw / 2,
                              my + markerY * minM - 4))
示例#13
0
 def begin(self):
     ctx.newPath()
示例#14
0
    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

        fill(0.9)
        stroke(None)
        mx = px + self.pw / 2
        my = py + self.ph / 2
        # Gray circle that defines the area of the axis extremes.
        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
        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
            stroke(None)
            fill(0.3)
            oval(mx + startX - 2, my + startY - 2, 4, 4)

            fill(None)
            stroke(0)
            strokeWidth(1)
            newPath()
            moveTo((mx + startX, my + startY))
            lineTo((mx + endX, my + endY))
            if startX1 is not None:
                moveTo((mx + startX1, my + startY1))
                lineTo((mx + endX1, my + endY1))
            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)
示例#15
0
 def _moveTo(self, pt):
     db.newPath()
     self.pointsList.append(pt)
示例#16
0
import drawBot
drawBot.size(200, 200)

drawBot.newPath()
drawBot.moveTo((20, 20))
drawBot.lineTo((20, 100))
drawBot.lineTo((100, 100))
drawBot.lineTo((100, 180))
drawBot.curveTo((150, 180), (180, 150), (180, 100))
drawBot.lineTo((180, 20))
drawBot.closePath()

drawBot.moveTo((40, 40))
drawBot.lineTo((160, 40))
drawBot.curveTo((160, 65), (145, 80), (120, 80))
drawBot.lineTo((40, 80))
drawBot.closePath()

drawBot.fill(0.5, 0, 0)
drawBot.stroke(None)
drawBot.strokeWidth(10)
drawBot.drawPath()
示例#17
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."""
        fill(0.9)
        stroke(None)
        mx = x + self.w / 2
        my = y + self.h / 2

        # Gray circle that defines the area of
        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
        fill(0)
        text(
            FormattedString(self.font.info.familyName,
                            font=self.style['labelFont'],
                            fontSize=self.style['axisNameFontSize']),
            (x - fontSize / 2, y + self.h + fontSize / 2))

        # Draw spokes
        fill(None)
        stroke(0)
        strokeWidth(1)
        newPath()
        for axisName, angle in self.angles.items():
            markerX, markerY = self._angle2XY(angle, self.w / 2)
            moveTo((mx, my))
            lineTo((mx + markerX, my + markerY))
        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 = FormattedString(makeAxisName(axisName),
                                     font=self.style.get(
                                         'labelFont', 'Verdana'),
                                     fontSize=axisNameFontSize,
                                     fill=self.style.get('axisNameColor', 0))
                tw, th = textSize(fs)
                fill(0.7, 0.7, 0.7, 0.6)
                stroke(None)
                rect(mx + markerX - tw / 2 - 4,
                     my + markerY - axisNameFontSize / 2 - th * 1.5 - 4,
                     tw + 8, th)
                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 = FormattedString(sMaxValue,
                                     font=self.style.get(
                                         'labelFont', 'Verdana'),
                                     fontSize=valueFontSize,
                                     fill=self.style.get('axisValueColor', 0))
                tw, th = textSize(fs)
                fill(0.7, 0.7, 0.7, 0.6)
                stroke(None)
                rect(mx + markerX - tw / 2 - 4,
                     my + markerY + valueFontSize / 2 + th * 1.5 - 4, tw + 8,
                     th)
                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 = FormattedString(sValue,
                                     font=self.style.get(
                                         'labelFont', 'Verdana'),
                                     fontSize=valueFontSize,
                                     fill=self.style.get('axisValueColor', 0))
                tw, th = textSize(fs)
                fill(0.7, 0.7, 0.7, 0.6)
                stroke(None)
                rect(
                    mx + markerX * INTERPOLATION - tw / 2 - 4, my +
                    markerY * INTERPOLATION + valueFontSize / 2 + th * 1.5 - 4,
                    tw + 8, th)
                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 = FormattedString(sValue,
                                     font=self.style.get(
                                         'labelFont', 'Verdana'),
                                     fontSize=valueFontSize,
                                     fill=self.style.get('axisValueColor', 0))
                tw, th = textSize(fs)
                fill(0.7, 0.7, 0.7, 0.6)
                stroke(None)
                minM = 0.2
                rect(mx + markerX * minM - tw / 2 - 4,
                     my + markerY * minM + th * 0.5 - 4, tw + 8, th)
                text(fs, (mx + markerX * minM - tw / 2,
                          my + markerY * minM + th * 0.5))
            colorSwitch = not colorSwitch
            prevPt = thisPt

        # clockwise arc
        elif cmd.startswith('G2') or cmd.startswith('G3'):
            stroke(*ALTERNATE_COLORS[colorSwitch])
            endPt = Point(extractValue('X', cmd), extractValue('Y', cmd))
            ii = extractValue('I', cmd)
            jj = extractValue('J', cmd)
            centerPt = Point(prevPt.x + ii, prevPt.y + jj)
            radius = distance(centerPt, endPt)

            if cmd.startswith('G2'):
                isClockwise = True
            else:
                isClockwise = False

            newPath()
            arc(centerPt,
                radius,
                degrees(calcAngle(centerPt, prevPt)),
                degrees(calcAngle(centerPt, endPt)),
                clockwise=isClockwise)
            drawPath()

            colorSwitch = not colorSwitch
            prevPt = endPt

    saveImage('visualizeConversion.pdf')
    endDrawing()