示例#1
0
 def shadow(self, eShadow):
     """Set the graphics state for shadow if parameters are set."""
     if eShadow is not None and eShadow.offset is not None:
         if eShadow.color.isCmyk:
             self.b.shadow(
                 upt(eShadow.offset),  # Convert units to values
                 blur=upt(eShadow.blur),
                 color=color(eShadow.color).cmyk)
         else:
             self.b.shadow(upt(eShadow.offset),
                           blur=upt(eShadow.blur),
                           color=color(eShadow.color).rgb)
示例#2
0
 def setShadow(self, eShadow):
     """Sets the InDesign graphics state for shadow if all parameters are
     set."""
     if eShadow is not None and eShadow.offset is not None:
         if eShadow.color.isCmyk:
             self.b.shadow(upt(eShadow.offset),
                           blur=upt(eShadow.blur),
                           color=eShadow.color.cmyk)
         else:
             self.b.shadow(upt(eShadow.offset),
                           blur=upt(eShadow.blur),
                           color=eShadow.color.rgb)
示例#3
0
 def _get_h(self):
     u = None
     if not self._h: # Width is undefined
         iwpt = upt(self.iw)
         if self._w and iwpt:
             u = self.ih * upt(self._w / iwpt)  # Width is lead, calculate height.
         else:
             u = self.ih # Undefined and without parent, answer original image width.
     else:
         base = dict(base=self.parentH, em=self.em) # In case relative units, use the right kind of base.
         u = units(self._h, base=base) # Height is lead and defined as not 0 or None.
     return u
示例#4
0
    def line(self, p1, p2):
        """Draw a line from p1 to p2. This method is using the core BezierPath
        as path to draw on. For a more rich ennvironment use
        PageBotPath(context).

        >>> from pagebot.contexts.drawbotcontext import DrawBotContext
        >>> context = DrawBotContext()
        >>> context.line(pt(100, 100), pt(200, 200))
        >>> context.line((100, 100), (200, 200))
        """
        p1pt = upt(point2D(p1))
        p2pt = upt(point2D(p2))
        self.b.line(p1pt, p2pt) # Render tuple of units point
示例#5
0
    def line(self, p1, p2):
        """Draw a line from p1 to p2. This method is using the BezierPath
        as path to draw on.

        >>> from pagebot import getContext
        >>> context = getContext()
        >>> context.newPage(420, 420)
        >>> context.line(pt(100, 100), pt(200, 200))
        >>> context.line((100, 100), (200, 200))
        """
        p1pt = upt(point2D(p1))
        p2pt = upt(point2D(p2))
        self.b.line(p1pt, p2pt)  # Render tuple of units point
示例#6
0
    def gradient(self, gradient, origin, w, h):
        """Define the gradient call to match the size of element e., Gradient
        position is from the origin of the page, so we need the current origin
        of e."""
        b = self.b
        start = origin[0] + gradient.start[0] * w, origin[1] + gradient.start[1] * h
        end = origin[0] + gradient.end[0] * w, origin[1] + gradient.end[1] * h

        if gradient.linear:
            if (gradient.colors[0]).isCmyk:
                colors = [color(c).cmyk for c in gradient.colors]
                b.cmykLinearGradient(startPoint=upt(start), endPoint=upt(end),
                    colors=colors, locations=gradient.locations)
            else:
                colors = [color(c).rgb for c in gradient.colors]
                b.linearGradient(startPoint=upt(start), endPoint=upt(end),
                    colors=colors, locations=gradient.locations)
        else: # Gradient must be radial.
            if color(gradient.colors[0]).isCmyk:
                colors = [color(c).cmyk for c in gradient.colors]
                b.cmykRadialGradient(startPoint=upt(start), endPoint=upt(end),
                    colors=colors, locations=gradient.locations,
                    startRadius=gradient.startRadius, endRadius=gradient.endRadius)
            else:
                colors = [color(c).rgb for c in gradient.colors]
                b.radialGradient(startPoint=upt(start), endPoint=upt(end),
                    colors=colors, locations=gradient.locations,
                    startRadius=gradient.startRadius, endRadius=gradient.endRadius)
示例#7
0
 def textBox(self, sOrBs, r):
     """Draw the sOrBs text string, can be a str or BabelString, including a
     DrawBot FormattedString in rectangle r."""
     if not isinstance(sOrBs, str):
         sOrBs = sOrBs.s  # Assume here is's a BabelString with a FormattedString inside.
     x, y, w, h = r
     t = self._drawing.text(sOrBs,
                            insert=point2D(upt(x, y)),
                            stroke=self._svgStroke,
                            stroke_width=upt(self._strokeWidth),
                            fill=self._svgFill,
                            font_size=upt(self._fontSize),
                            font_family=self._font)
     self._drawing.add(t)
示例#8
0
    def translatePoint(self, p):
        """Simpler function to translate a point based on origin coordinates
        (`self._ox` and `self._oy`).

        TODO: merge with getTransformed.
        """
        x, y = point2D(upt(p))
        x = self._ox + x
        '''Because the origin is at the bottom, like in DrawBot and as opposed
        to Flat, we need to subtract all vertical coordinates from the page
        height before an object gets placed. In case of (bounding) boxes, we
        also need to subtract the box height.'''
        y = self.height - (self._oy + y)
        return upt(x, y)
示例#9
0
 def circle(self, x, y, r):
     """Draw an circle in square, with radius r and (x,y) as middle."""
     xpt, ypt, rpt = upt(x, y, r)
     shape = self._getShape()
     if shape is not None:
         self.ensure_page()
         self.page.place(shape.circle(xpt, ypt, rpt))
示例#10
0
 def text(self, sOrBs, p):
     """Draw the sOrBs text string, can be a str or BabelString, including a
     DrawBot FormattedString at position p."""
     if not isinstance(sOrBs, str):
         sOrBs = sOrBs.s  # Assume here is's a BabelString with a FormattedString inside.
     ppt = point2D(upt(p))
     self.b.text(sOrBs, ppt)  # Render point units to value tuple
示例#11
0
    def font(self, font, fontSize=None):
        """Set the current font, in case it is not defined in a formatted
        string. Font can be a Font instance, or a full font file path, or an
        abbreveation that can be found by family or by findFont.

        >>> from pagebot.fonttoolbox.objects.font import findFont
        >>> from pagebot.fonttoolbox.fontpaths import *
        >>> from pagebot.paths import DEFAULT_FONT_PATH
        >>> pbFonts = getPageBotFontPaths()
        >>> print(len(pbFonts))
        57
        >>> font = findFont('Roboto-Regular')
        >>> print(font)
        <Font Roboto-Regular>
        >>> context = FlatContext()
        >>> print(context)
        <FlatContext>
        >>> context.font(font.path)
        >>> context._font.endswith('/Roboto-Regular.ttf')
        True
        >>> context.font('OtherFont', 12) # Font does not exists, font path is set to DEFAULT_FONT_PATH
        >>> context._font == DEFAULT_FONT_PATH
        True
        >>> context._fontSize # Renders to pt-unit
        12
        """
        from pagebot.fonttoolbox.fontpaths import getFontPathOfFont

        self._font = getFontPathOfFont(font) # Convert name or path to font path.
        if fontSize is not None:
            self._fontSize = upt(fontSize)
示例#12
0
    def roundedRect(self, x, y, w, h, offset=25):
        """Draw a rectangle in the canvas. This method is using the Bézier path
        as path to draw on.

        TODO: move to elements.

        >>> from pagebot import getContext
        >>> context = getContext()
        >>> context.roundedRect(pt(0), pt(0), pt(100), pt(100))
        >>> context.roundedRect(0, 0, 100, 100)
        """
        xPt, yPt, wPt, hPt, offsetPt = upt(x, y, w, h, offset)
        path = self.newPath()
        path.moveTo((xPt + offsetPt, yPt))
        path.lineTo((xPt + wPt - offsetPt, yPt))
        path.curveTo((xPt + wPt, yPt), (xPt + wPt, yPt),
                     (xPt + wPt, yPt + offsetPt))
        path.lineTo((xPt + wPt, yPt + hPt - offsetPt))
        path.curveTo((xPt + wPt, yPt + hPt), (xPt + wPt, yPt + hPt),
                     (xPt + wPt - offsetPt, yPt + hPt))
        path.lineTo((xPt + offsetPt, yPt + hPt))
        path.curveTo((xPt, yPt + hPt), (xPt, yPt + hPt),
                     (xPt, yPt + hPt - offsetPt))
        path.lineTo((xPt, yPt + offsetPt))
        path.curveTo((xPt, yPt), (xPt, yPt), (xPt + offsetPt, yPt))
        self.closePath()
        self.drawPath(path)
示例#13
0
 def _get_w(self):
     """Get the intended width and calculate the new scale, validating the
     width to the image minimum width and the height to the image minimum height.
     If not self._h is defined, then the proportion is recalculated, depending on
     the ratio of the image."""
     u = None
     if not self._w: # Width is undefined
         ihpt = upt(self.ih)
         if self._h and ihpt:
             u = self.iw * upt(self._h / ihpt)  # Height is lead, calculate width.
         else:
             u = self.iw # Undefined and without parent, answer original image width.
     else:
         base = dict(base=self.parentW, em=self.em) # In case relative units, use the right kind of base.
         u = units(self._w, base=base) # Width is lead and defined as not 0 or None.
     return u
示例#14
0
 def saveScaledCache(self, view):
     """If the self.saveScaled is True and the reduction scale is inside the range,
     then create a new cached image file, if it does not already exist. Scaling images in
     the DrawBot context is a fast operation, so always worthwhile to creating PNG from
     large export PDF files.
     In case the source is a PDF, then use self.index to request for the page.
     """
     if self.path is None or not self.saveScaled:
         return
     if not self.iw or not self.ih: # Make sure not zero, to avoid division
         print('Image.saveScaledCache: %dx%d zero image size' % (self.iw, self.ih))
         return
     extension = path2Extension(self.path)
     resolutionFactor = self.resolutionFactors.get(extension, 1)
     # Translate the extension to the related type of output.
     exportExtension = CACHE_EXTENSIONS.get(extension, extension)
     resW = self.w * resolutionFactor
     resH = self.h * resolutionFactor
     sx, sy = upt(resW / self.iw, resH / self.ih)
     if not self.saveScaled and 0.8 <= sx and 0.8 <= sy: # If no real scale reduction, then skip. Never enlarge.
         return
     # Scale the image the cache does not exist already.
     # A new path is answers for the scaled image file. Reset the (self.iw, self.ih)
     self.path = self.context.scaleImage(
         path=self.path, w=resW, h=resH, index=self.index,
         showImageLoresMarker=self.showImageLoresMarker or view.showImageLoresMarker,
         exportExtension=exportExtension
     )
示例#15
0
    def textBox(self, sOrBs, r=None, clipPath=None, align=None):
        """Draw the sOrBs text string, can be a str or BabelString, including a
        DrawBot FormattedString in rectangle r.

        NOTE: signature differs from DrawBot.

        >>> from pagebot.toolbox.units import pt
        >>> from pagebot.contexts.drawbotcontext import DrawBotContext
        >>> context = DrawBotContext()
        >>> context.textBox('ABC', (10, 10, 200, 200))
        """
        if hasattr(sOrBs, 's'):
            sOrBs = sOrBs.s # Assume here is's a BabelString with a FormattedString inside.
        else:
            sOrBs = str(sOrBs) # Otherwise convert to string if it is not already

        if clipPath is not None:
            box = clipPath.bp
            self.b.textBox(sOrBs, clipPath.bp) # Render rectangle units to value tuple
        elif isinstance(r, (tuple, list)):
            # Render rectangle units to value tuple
            box = upt(r)
        else:
            raise ValueError('%s.textBox has no box or clipPath defined' % self.__class__.__name__)
        self.b.textBox(sOrBs, box, align=None)
示例#16
0
    def getBaselines(self, bs, w=None, h=None):
        """Answers the dictionary of baseline positions, relative
        to the firstline. If @h is defined, the clip on the height.


        See also doctests/string*.txt.
        """
        if h is None:
            h = XXXL

        baselines = {}

        if w is not None:
            lines = self.getTextLines(bs, w, h=h)
        else:
            lines = bs.lines

        if lines:
            y = lines[0].y

        for lineInfo in lines:
            if lineInfo.y - y > h:
                break
            baselines[upt(lineInfo.y - y)] = lineInfo

        return baselines
示例#17
0
    def text(self, bs, p):
        """Place the babelstring instance at position p. The position can be
        any 2D or 3D points tuple. Currently the z-axis is ignored. The
        FlatContext version of the BabelString should contain
        Flat.text.

        NOTE:in the Flat model the position is an attribute of the string,
        therefore strings cannot be reused to be displayed on multiple
        positions.

        >>> context = FlatContext()
        >>> style = dict(font='Roboto-Regular', fontSize=pt(12))
        >>> bs = context.newString('ABC', style=style)
        >>> bs.__class__.__name__
        'FlatString'
        >>> context.newDocument(1000, 1000)
        >>> context.newPage()
        >>> context.text(bs, (100, 100))

        """
        if not isinstance(bs, FlatString):
            if isinstance(bs, str):
                bs = self.newString(bs)
            else:
                print('wrong type %s' % type(s))
                # TODO: raise error.

        assert self.page is not None, 'FlatString.text: self.page is not set.'
        placedText = self.page.place(bs.s)
        xpt, ypt = point2D(upt(p))
        placedText.position(xpt, ypt) # Render unit tuple to value tuple
示例#18
0
    def roundedRect(self, x, y, w, h, offset=25):
        """Draw a rectangle in the canvas. This method is using the core BezierPath
        as path to draw on. For a more rich environment use PageBotPath(context)
        instead.

        TODO: move to elements.

        >>> context = PdfLibContext()
        >>> context.roundedRect(pt(0), pt(0), pt(100), pt(100))
        >>> context.roundedRect(0, 0, 100, 100)
        """
        if 0:
            xPt, yPt, wPt, hPt, offsetPt = upt(x, y, w, h, offset)
            path = self.newPath()
            path.moveTo((xPt+offsetPt, yPt))
            path.lineTo((xPt+wPt-offsetPt, yPt))
            path.curveTo((xPt+wPt, yPt), (xPt+wPt, yPt), (xPt+wPt, yPt+offsetPt))
            path.lineTo((xPt+wPt, yPt+hPt-offsetPt))
            path.curveTo((xPt+wPt, yPt+hPt), (xPt+wPt, yPt+hPt), (xPt+wPt-offsetPt, yPt+hPt))
            path.lineTo((xPt+offsetPt, yPt+hPt))
            path.curveTo((xPt, yPt+hPt), (xPt, yPt+hPt), (xPt, yPt+hPt-offsetPt))
            path.lineTo((xPt, yPt+offsetPt))
            path.curveTo((xPt, yPt), (xPt, yPt), (xPt+offsetPt, yPt))
            self.closePath()
            self.drawPath(path)
示例#19
0
    def text(self, bs, p):
        """Place the babelstring instance at position p. The position can be
        any 2D or 3D points tuple. Currently the z-axis is ignored. The
        FlatContext version of the BabelString is supposed to contain
        Flat.text. Note that in the Flat model, the positions is an attribute
        of the string, so strings cannot be reused to show on multiple
        positions.

        >>> context = FlatContext()
        >>> style = dict(font='Roboto-Regular', fontSize=pt(12))
        >>> bs = context.newString('ABC', style=style)
        >>> bs.__class__.__name__
        'FlatString'
        >>> context.newDocument(1000, 1000)
        >>> context.newPage()
        >>> context.text(bs, (100, 100))

        """
        assert isinstance(
            bs, FlatString
        ), 'FlatString.text: bs not of type %s' % FlatString.__name__
        assert self.page is not None, 'FlatString.text: self.page is not set.'
        placedText = self.page.place(bs.s)
        xpt, ypt = point2D(upt(p))
        placedText.position(xpt, ypt)  # Render unit tuple to value tuple
示例#20
0
    def addPoint(self,
                 point,
                 segmentType=None,
                 smooth=False,
                 name=None,
                 identifier=None,
                 **kwargs):
        msg = '%s.addPoint: Point "%s" is not a tuple or a Point' % (
            self.__class__.__name__, point)
        assert isinstance(point, (list, tuple, BaseBezierPoint)), msg
        if isinstance(point, (list, tuple)):
            px, py = upt(point2D(point))
        else:
            px = point.x
            py = point.y
            segmentType = segmentType or point.segmentType
            smooth = smooth or point.smooth
            identifier = identifier or point.identifier

        self.bp.addPoint((px, py),
                         segmentType=segmentType,
                         smooth=smooth,
                         name=name,
                         identifier=identifier,
                         **kwargs)
示例#21
0
    def line(self, p1, p2):
        """Draw a line from p1 to p2.

        >>> path = '~/SvgContext_line.svg'
        >>> context = SvgContext()
        >>> context.stroke((1, 0, 0.5), 30)
        >>> context.line((0, 100), (300, 300))
        >>> context.stroke((0.6, 0.1, 0.5), 20)
        >>> context.line((300, 150), (200, 100))
        >>> context.saveDocument(path)
        >>> #r = os.system('open %s' % path)
        """
        line = self._drawing.line(upt((self._ox+p1[0]), (self._oy+p1[1])), upt((self._ox+p2[0]), (self._oy+p2[1])),
                                  stroke_width=upt(self._strokeWidth),
                                  stroke=color(self._stroke).css)
        self._drawing.add(line)
示例#22
0
    def build(self, view, origin=ORIGIN, **kwargs):
        """Default drawing method just drawing the frame. Probably will be
        redefined by inheriting element classes."""
        p = pointOffset(self.origin, origin)
        p = self._applyScale(view, p)
        px, py, _ = p = self._applyAlignment(p) # Ignore z-axis for now.
        pt, pr, pb, pl = self.padding
        self._applyRotation(view, p)
        self.buildFrame(view, p) # Draw optional frame or borders.

        # Let the view draw frame info for debugging, in case view.showFrame == True
        # and self.isPage or if self.showFrame. Mark that we are drawing background here.
        view.drawPageMetaInfoBackground(self, p)

        if self.clipPath is not None:
            # If there is a clipPath defined, use it.
            clipPath = self.clipPath
        else:
            # Otherwise use self.box as clipRect when drawing the child elements.
            clipPath = self.context.newPath()
            # move to a point
            clipPath.moveTo(upt(px+pl, py+pb))
            # line to points of the clip rect.
            clipPath.lineTo(upt(px+pl, py+pb+self.ph))
            clipPath.lineTo(upt(px+pl+self.pw, py+pr+self.ph))
            clipPath.lineTo(upt(px+pl+self.pw, py+pb))
            clipPath.lineTo(upt(px+pl, py+pb))
            # close the path
            clipPath.closePath()

        #self.context.fill((0, 1, 0))
        #self.context.drawPath(clipPath)
        self.context.save()
        # set the path as a clipping path
        #self.context.clipPath(clipPath)
        # Build the child elements. Default this is the ImageData instance, but there
        # may be other elemnents added too in any particular order.
        self.buildChildElements(view, p)
        self.context.restore()

        # Let the view draw frame info for debugging, in case view.showFrame == True
        # and self.isPage or if self.showFrame. Mark that we are drawing foreground here.
        view.drawPageMetaInfo(self, p)
        self._restoreRotation(view, p)
        self._restoreScale(view)
        view.drawElementInfo(self, origin) # Depends on flag 'view.showElementInfo'
示例#23
0
 def stroke(self, c, strokeWidth=None):
     c = color(c)
     if c is noColor:
         self._fill = 'none'
     else:
         r, g, b = c.rgb
         self._fill = self.b.rgb(100*r, 100*g, 100*b, '%')
     self._strokeWidth = upt(strokeWidth or pt(1))
示例#24
0
    def textBox(self, bs, r):
        """
        ...

        FIXME: Not using width and height here?"""
        xpt, ypt, _, _ = upt(r)
        placedText = self.page.place(bs.s)
        placedText.position(xpt, ypt)
示例#25
0
    def font(self, fontName, fontSize=None):
        # FIXME: fontSize?
        self.b.font(fontName)

        # Also renders fontSize unit to value.
        if fontSize is not None:
            fspt = upt(fontSize)
            self.b.fontSize(fspt)
示例#26
0
    def arcTo(self, pt1, pt2, radius):
        """Arc from one point to an other point with a given radius.

        >>> from pagebot.toolbox.units import p
        >>> from pagebot.contexts import getContext
        >>> context = getContext()
        >>> path = PageBotPath(context=context)
        >>> path.moveTo((0, 0))
        >>> p1 = pt(100), p(6)
        >>> p2 = p(10), pt(200)
        >>> r = pt(300)
        >>> path.arcTo(p1, p2, r)
        >>> path.closePath()
        """
        pt1 = upt(point2D(pt1))
        pt2 = upt(point2D(pt2))
        ptRadius = upt(radius or DEFAULT_WIDTH / 2)
        self.bp.arcTo(pt1, pt2, ptRadius)
示例#27
0
    def circle(self, x, y, r):
        """Circle draws a DrawBot oval with (x,y) as middle point and radius r.

        >>> from pagebot.toolbox.color import color, blackColor
        >>> path = '~/SvgContext_circle.svg'
        >>> context = SvgContext()
        >>> context.fill(color(r=1, g=0, b=0.5))
        >>> context.circle(pt(0), pt(100), pt(300))
        >>> context.stroke(blackColor, pt(20))
        >>> context.fill(color(r=0.6, g=0.1, b=0.5))
        >>> context.circle(pt(300), pt(150), pt(200))
        >>> context.saveDocument(path)
        >>> #r = os.system('open %s' % path)
        """
        circle = self._drawing.circle(center=upt((self._ox+x+r), (self._oy+y+r)), r=upt(r),
                                      stroke_width=upt(self._strokeWidth),
                                      stroke=color(self._stroke).css, fill=color(self._fill).css)
        self._drawing.add(circle)
示例#28
0
 def circle(self, x, y, r):
     u"""Circle draws a DrawBot oval with (x,y) as middle point and radius r.
     >>> context = DrawBotContext()
     >>> context.circle(pt(100), pt(200), pt(50))
     >>> context.circle(100, 200, 50)
     """
     xpt, ypt, rpt = upt(x, y, r)
     self.b.oval(xpt - rpt, ypt - rpt, rpt * 2,
                 rpt * 2)  # Render the unit values
示例#29
0
    def rect(self, x, y, w, h):
        """Draw a rectangle in the canvas.

        >>> context = DrawBotContext()
        >>> context.rect(pt(0), pt(0), pt(100), pt(100))
        >>> context.rect(0, 0, 100, 100)
        """
        xpt, ypt, wpt, hpt = upt(x, y, w, h)
        self.b.rect(xpt, ypt, wpt, hpt)  # Render units to points for DrawBot.
示例#30
0
    def fontSize(self, fontSize):
        """Set the font size in the context.

        >>> from pagebot.toolbox.units import pt
        >>> context = DrawBotContext()
        >>> context.fontSize(pt(12))
        """
        fspt = upt(fontSize)
        self.b.fontSize(fspt)  # Render fontSize unit to value