Пример #1
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()
Пример #2
0
    def draw(self, origin, view):
        u"""Like "rolled pasteboard" galleys can draw themselves, if the Composer decides to keep
        them in tact, instead of select, pick & choose elements, until the are all
        part of a page. In that case the w/h must have been set by the Composer to fit the
        containing page."""
        p = pointOffset(self.oPoint, origin)
        p = self._applyScale(p)    
        px, py, _ = self._applyAlignment(p) # Ignore z-axis for now.

        if self.drawBefore is not None: # Call if defined
            self.drawBefore(self, p, view)

        setFillColor(self.OLD_PAPER_COLOR) # Color of old paper: #F8ECC2
        gw, gh = self.getSize()
        rect(px, py, gw, gh)
        gy = 0
        for element in self.elements:
            # @@@ Find space and do more composition
            element.draw((px, py + gy), view)
            gy += element.h

        if self.drawAfter is not None: # Call if defined
            self.drawAfter(self, p, view)

        self._restoreScale()
        view.drawElementMetaInfo(self, origin)
Пример #3
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.

        save()
        sh = 1.0 * self.h / self.ih
        transform((1, 0, 0, 1, px, py))
        scale(sh)
        if self.pathFilter is not None:
            self.pathFilter(self, self.glyph.path)
        if self.css('fill') != NO_COLOR or self.css('stroke') != NO_COLOR:
            setFillColor(self.css('fill'))
            print(self.css('strokeWidth') or 1), sh
            setStrokeColor(self.css('stroke', NO_COLOR),
                           (self.css('strokeWidth') or 20))
            fill(0)
            stroke(1, 0, 0)
            strokeWidth(20)
            drawPath(self.glyph.path)
        restore()

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

        # Draw optional bounding box.
        #self.drawFrame(origin, view)

        self._restoreScale()
        view.drawElementMetaInfo(
            self, origin)  # Depends on css flag 'showElementInfo'
Пример #4
0
def drawGlyphPath(font, glyphName, x, y, s=0.1, fillColor=0, strokeColor=None, strokeWidth=0):
    glyph = font[glyphName]
    save()
    setFillColor(fillColor)
    setStrokeColor(strokeColor, strokeWidth)
    transform((1, 0, 0, 1, x - glyph.width/2*s, y))
    scale(s)
    drawPath(glyph.path)
    restore()
Пример #5
0
    def drawPages(self, pageSelection=None):
        u"""Draw the selected pages. pageSelection is an optional set of y-pageNumbers to draw."""
        doc = self.parent

        w, h, _ = doc.getMaxPageSizes(pageSelection)
        w2 = 2 * w  # Make spread width
        for pn, pages in doc.getSortedPages():
            #if pageSelection is not None and not page.y in pageSelection:
            #    continue
            # Create a new DrawBot viewport page to draw template + page, if not already done.
            # In case the document is oversized, then make all pages the size of the document, so the
            # pages can draw their crop-marks. Otherwise make DrawBot pages of the size of each page.
            # Size depends on the size of the larges pages + optional decument padding.
            page = pages[
                0]  # TODO: Make it work if there as multiple pages on the same page number.
            pw, ph = w, h  # Copy from main (w, h), since they may be altered.
            if self.pl > self.MIN_PADDING and self.pt > self.MIN_PADDING and self.pb > self.MIN_PADDING and self.pr > self.MIN_PADDING:
                pw += self.pl + self.pr
                ph += self.pt + self.pb
                if self.originTop:
                    origin = self.pl, self.pt, 0
                else:
                    origin = self.pl, self.pb, 0
            else:
                pw = page.w  # No padding defined, follow the size of the page.
                ph = page.h
                origin = (0, 0, 0)
            pw2 = 2 * pw

            if (pn % 2 == 0):  # Is even?
                newPage(
                    pw2, ph
                )  #  Make page in DrawBot of self size, actual page may be smaller if showing cropmarks.
                # View may have defined a background
                if self.style.get('fill') is not None:
                    setFillColor(self.style['fill'])
                    rect(0, 0, pw2, ph)
            else:  # Odd, shift origin to right
                origin = origin[0] + pw, origin[1], origin[2]

            if self.drawBefore is not None:  # Call if defined
                self.drawBefore(page, origin, self)

            self.drawPageFrame(page, origin)

            # Use the (docW, docH) as offset, in case cropmarks need to be displayed.
            page.draw(origin, self)

            if self.drawAfter is not None:  # Call if defined
                self.drawAfter(page, origin, self)

            # Self.infoElements now may have collected elements needed info to be drawn, after all drawing is done.
            # So the info boxes don't get covered by regular page content.
            for e in self.elementsNeedingInfo.values():
                self._drawElementsNeedingInfo()
Пример #6
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))
        """
Пример #7
0
    def drawElementOrigin(self, e, origin):
        px, py, _ = pointOffset(e.oPoint, origin)
        S = self.css('viewInfoOriginMarkerSize', 4)
        if self.showElementOrigin:
            # Draw origin of the element
            setFillColor(
                (0.5, 0.5, 0.5, 0.1)
            )  # Transparant fill, so we can see the marker on dark backgrounds.
            setStrokeColor(0, 0.25)
            oval(px - S, py - S, 2 * S, 2 * S)
            line((px - S, py), (px + S, py))
            line((px, py - S), (px, py + S))

        if self.showElementDimensions:
            fs = newFS(point2S(e.point3D),
                       style=dict(font=self.css('viewInfoFont'),
                                  fontSize=self.css('viewInfoFontSize'),
                                  leading=self.css('viewInfoLeading'),
                                  textFill=0.1))
            w, h = textSize(fs)
            text(fs, (px - w / 2, py + S * 1.5))
Пример #8
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.

        self.drawFrame(p, view)  # Draw optional frame or borders.

        if self.drawBefore is not None:  # Call if defined
            self.drawBefore(self, p, view)

        setFillColor(self.css('fill', NO_COLOR))
        setStrokeColor(self.css('stroke', NO_COLOR), self.css('strokeWidth'))
        oval(px, py, self.w, self.h)

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

        if self.drawAfter is not None:  # Call if defined
            self.drawAfter(self, p, view)

        self._restoreScale()
        view.drawElementMetaInfo(self, origin)
Пример #9
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.
Пример #10
0
    def draw(self, origin, view):

        p = pointOffset(self.oPoint, origin)
        p = self._applyScale(p)    
        px, py, _ = self._applyAlignment(p) # Ignore z-axis for now.
        sIndent = self.css('indent')
        sTailIndent = self.css('tailIndent')
        w = self.w - sIndent - sTailIndent
 
        if self.drawBefore is not None: # Call if defined
            self.drawBefore(self, p, view)

        setFillColor(None)
        setStrokeColor(self.css('stroke', NO_COLOR), self.css('strokeWidth'))
        line((px + sIndent, py), (px + w, py))

        # If there are child elements, draw them over the text.
        self._drawElements(origin)

        if self.drawAfter is not None: # Call if defined
            self.drawAfter(self, p, view)

        self._restoreScale()
        view.drawElementMetaInfo(self, origin)
Пример #11
0
    def _drawElementsNeedingInfo(self):
        for e, origin in self.elementsNeedingInfo.values():
            p = pointOffset(e.oPoint, origin)
            p = e._applyScale(p)
            px, py, _ = e._applyAlignment(p)  # Ignore z-axis for now.
            if self.showElementInfo:
                # Draw box with element info.
                fs = newFS(e.getElementInfoString(),
                           style=dict(font=self.css('viewInfoFont'),
                                      fontSize=self.css('viewInfoFontSize'),
                                      leading=self.css('viewInfoLeading'),
                                      textFill=0.1))
                tw, th = textSize(fs)
                Pd = 4  # Padding in box and shadow offset.
                tpx = px - Pd / 2  # Make info box outdent the element. Keeping shadow on the element top left corner.
                tpy = py + e.h - th - Pd
                # Tiny shadow
                setFillColor((0.3, 0.3, 0.3, 0.5))
                setStrokeColor(None)
                rect(tpx + Pd / 2, tpy, tw + 2 * Pd, th + 1.5 * Pd)
                # Frame
                setFillColor(self.css('viewInfoFill'))
                setStrokeColor(0.3, 0.25)
                rect(tpx, tpy, tw + 2.5 * Pd, th + 1.5 * Pd)
                text(fs, (tpx + Pd, tpy + th))
                e._restoreScale()

            if self.showElementDimensions:
                # TODO: Make separate arrow functio and better positions
                # Draw width and height measures
                setFillColor(None)
                setStrokeColor(0, 0.25)
                S = self.css('viewInfoOriginMarkerSize', 4)
                x1, y1, x2, y2 = px + e.left, py + e.bottom, e.right, e.top

                # Horizontal measure
                line((x1, y1 - 0.5 * S), (x1, y1 - 3.5 * S))
                line((x2, y1 - 0.5 * S), (x2, y1 - 3.5 * S))
                line((x1, y1 - 2 * S), (x2, y1 - 2 * S))
                # Arrow heads
                line((x1, y1 - 2 * S), (x1 + S, y1 - 1.5 * S))
                line((x1, y1 - 2 * S), (x1 + S, y1 - 2.5 * S))
                line((x2, y1 - 2 * S), (x2 - S, y1 - 1.5 * S))
                line((x2, y1 - 2 * S), (x2 - S, y1 - 2.5 * S))

                fs = newFS(asFormatted(x2 - x1),
                           style=dict(font=self.css('viewInfoFont'),
                                      fontSize=self.css('viewInfoFontSize'),
                                      leading=self.css('viewInfoLeading'),
                                      textFill=0.1))
                tw, th = textSize(fs)
                text(fs, ((x2 + x1) / 2 - tw / 2, y1 - 1.5 * S))

                # Vertical measure
                line((x2 + 0.5 * S, y1), (x2 + 3.5 * S, y1))
                line((x2 + 0.5 * S, y2), (x2 + 3.5 * S, y2))
                line((x2 + 2 * S, y1), (x2 + 2 * S, y2))
                # Arrow heads
                line((x2 + 2 * S, y2), (x2 + 2.5 * S, y2 - S))
                line((x2 + 2 * S, y2), (x2 + 1.5 * S, y2 - S))
                line((x2 + 2 * S, y1), (x2 + 2.5 * S, y1 + S))
                line((x2 + 2 * S, y1), (x2 + 1.5 * S, y1 + S))

                fs = newFS(asFormatted(y2 - y1),
                           style=dict(font=self.css('viewInfoFont'),
                                      fontSize=self.css('viewInfoFontSize'),
                                      leading=self.css('viewInfoLeading'),
                                      textFill=0.1))
                tw, th = textSize(fs)
                text(fs, (x2 + 2 * S - tw / 2, (y2 + y1) / 2))
Пример #12
0
    def drawArrow(self,
                  e,
                  xs,
                  ys,
                  xt,
                  yt,
                  onText=1,
                  startMarker=False,
                  endMarker=False,
                  fms=None,
                  fmf=None,
                  fill=None,
                  stroke=None,
                  strokeWidth=None):
        u"""Draw curved arrow marker between the two points.
        TODO: Add drawing of real arrow-heads, rotated in the right direction."""
        if fms is None:
            fms = self.css('viewFlowMarkerSize')
        if fmf is None:
            fmf or self.css('viewFlowCurvatureFactor')

        if stroke is None:
            if onText == 1:
                stroke = self.css('viewFlowConnectionStroke2', NO_COLOR)
            else:
                stroke = self.css('viewFlowConnectionStroke1', NO_COLOR)
        if strokeWidth is None:
            strokeWidth = self.css('viewFlowConnectionStrokeWidth', 0.5)

        setStrokeColor(stroke, strokeWidth)
        if startMarker:
            if fill is None:
                fill = self.css('viewFlowMarkerFill', NO_COLOR)
            setFillColor(fill)
            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(stroke)
        setStrokeColor(None)
        moveTo((xt, yt))
        lineTo((ax1, ay1))
        lineTo((ax2, ay2))
        closePath()
        drawPath()

        if endMarker:
            setFillColor(self.css('viewFlowMarkerFill', NO_COLOR))
            oval(xt - fms, yt - fms, 2 * fms, 2 * fms)