Exemplo n.º 1
0
 def _center_transform(self, transform):
     ''''
     Works like setupTransform of a version of java nodebox
     http://dev.nodebox.net/browser/nodebox-java/branches/rewrite/src/java/net/nodebox/graphics/Grob.java
     '''
     dx, dy = self._get_center()
     t = cairo.Matrix()
     t.translate(dx, dy)
     t = transform * t
     t.translate(-dx, -dy)
     return t
Exemplo n.º 2
0
        def _render(cairo_ctx):
            """
            At the moment this is based on cairo.

            TODO: Need to work out how to move the cairo specific
                  bits somewhere else.
            """
            # Go to initial point (CORNER or CENTER):
            transform = self._call_transform_mode(self._transform)

            if fillcolor is None and strokecolor is None:
                # Fixes _bug_FillStrokeNofillNostroke.bot
                return

            cairo_ctx.set_matrix(transform)
            # Run the path commands on the cairo context:
            self._traverse(cairo_ctx)
            # Matrix affects stroke, so we need to reset it:
            cairo_ctx.set_matrix(cairo.Matrix())

            if fillcolor is not None and strokecolor is not None:
                if strokecolor[3] < 1:
                    # Draw onto intermediate surface so that stroke
                    # does not overlay fill
                    cairo_ctx.push_group()

                    cairo_ctx.set_source_rgba(*fillcolor)
                    cairo_ctx.fill_preserve()

                    e = cairo_ctx.stroke_extents()
                    cairo_ctx.set_source_rgba(*strokecolor)
                    cairo_ctx.set_operator(cairo.OPERATOR_SOURCE)
                    cairo_ctx.set_line_width(strokewidth)
                    cairo_ctx.stroke()

                    cairo_ctx.pop_group_to_source()
                    cairo_ctx.paint()
                else:
                    # Fast path if no alpha in stroke
                    cairo_ctx.set_source_rgba(*fillcolor)
                    cairo_ctx.fill_preserve()

                    cairo_ctx.set_source_rgba(*strokecolor)
                    cairo_ctx.set_line_width(strokewidth)
                    cairo_ctx.stroke()
            elif fillcolor is not None:
                cairo_ctx.set_source_rgba(*fillcolor)
                cairo_ctx.fill()
            elif strokecolor is not None:
                cairo_ctx.set_source_rgba(*strokecolor)
                cairo_ctx.set_line_width(strokewidth)
                cairo_ctx.stroke()
Exemplo n.º 3
0
 def endpath(self, draw=True):
     if self._path is None:
         raise ShoebotError(_("No current path. Use beginpath() first."))
     p = self._path
     if self._autoclosepath is True:
         self._path.closepath()
     if draw:
         p.draw()
     else:
         # keep the transform so we don't lose it
         self._path.transform = cairo.Matrix(*self._canvas.transform)
     self._path = None
     return p
Exemplo n.º 4
0
 def set_matrix(self, transform=None):
     if transform is None:
         pass
     elif isinstance(transform, Transform):
         self.append(transform)
     elif isinstance(transform, (list, tuple)):
         matrix = tuple(transform)
         t = cairo.Matrix(*matrix)
         self.append(t)
     elif isinstance(transform, cairo.Matrix):
         self.append(transform)
     else:
         raise ValueError(_("Transform: Don't know how to handle transform %s.") % transform)
Exemplo n.º 5
0
        def _render(cairo_ctx):
            """
            At the moment this is based on cairo.

            TODO: Need to work out how to move the cairo specific
                  bits somewhere else.
            """
            # Go to initial point (CORNER or CENTER):
            transform = self._call_transform_mode(self._transform)

            if fillcolor is None and strokecolor is None:
                # Fixes _bug_FillStrokeNofillNostroke.bot
                return

            cairo_ctx.set_matrix(transform)
            # Run the path commands on the cairo context:
            self._traverse(cairo_ctx)
            # Matrix affects stroke, so we need to reset it:
            cairo_ctx.set_matrix(cairo.Matrix())

            if blendmode:
                cairo_ctx.set_operator(BLENDMODES[blendmode])

            if fillcolor:
                cairo_ctx.set_source_rgba(*fillcolor)
                if fillrule:
                    cairo_ctx.set_fill_rule(fillrule)
                if not strokecolor:
                    cairo_ctx.fill()
                else:
                    cairo_ctx.fill_preserve()
            if strokecolor:
                cairo_ctx.set_source_rgba(*strokecolor)
                cairo_ctx.set_line_width(strokewidth)
                if strokedash:
                    cairo_ctx.set_dash(strokedash, dashoffset)
                if strokecap:
                    # this is needed because strokecap and strokejoin have a ROUND
                    # option which is a different value for each
                    cairo_ctx.set_line_cap(STROKE_CAPS[strokecap])
                if strokejoin:
                    cairo_ctx.set_line_join(STROKE_JOINS[strokejoin])
                cairo_ctx.stroke()

            if blendmode:
                # reset blend mode
                cairo_ctx.set_operator(cairo.OPERATOR_OVER)
Exemplo n.º 6
0
 def __init__(self, bot):
     # Takes bot rather than canvas for compatibility with libraries - e.g. the colors library
     self._canvas = canvas = bot._canvas
     self._bot = bot
     self._set_mode(canvas.mode)
     self._transform = cairo.Matrix(*canvas.transform)
Exemplo n.º 7
0
    def get_matrix_with_center(self, x, y, mode):
        m = cairo.Matrix()
        centerx = x
        centery = y
        m_archived = []

        for trans in self.stack:
            if isinstance(trans, cairo.Matrix):
                # multiply matrix
                m *= trans
            elif isinstance(trans, tuple) and trans[0] in TRANSFORMS:
                # parse transform command
                cmd = trans[0]
                args = trans[1:]
                t = cairo.Matrix()

                if cmd == "translate":
                    xt = args[0]
                    yt = args[1]
                    m.translate(xt, yt)
                elif cmd == "rotate":
                    if mode == "corner":
                        # apply existing transform to cornerpoint
                        deltax, deltay = m.transform_point(0, 0)
                        a = args[0]
                        ct = cos(a)
                        st = sin(a)
                        m *= cairo.Matrix(
                            ct,
                            st,
                            -st,
                            ct,
                            deltax - (ct * deltax) + (st * deltay),
                            deltay - (st * deltax) - (ct * deltay),
                        )
                    elif mode == "center":
                        # apply existing transform to centerpoint
                        deltax, deltay = m.transform_point(centerx, centery)
                        a = args[0]
                        ct = cos(a)
                        st = sin(a)
                        m *= cairo.Matrix(
                            ct,
                            st,
                            -st,
                            ct,
                            deltax - (ct * deltax) + (st * deltay),
                            deltay - (st * deltax) - (ct * deltay),
                        )
                elif cmd == "scale":
                    if mode == "corner":
                        t.scale(args[0], args[1])
                        m *= t
                    elif mode == "center":
                        # apply existing transform to centerpoint
                        deltax, deltay = m.transform_point(centerx, centery)
                        x, y = args
                        m1 = cairo.Matrix()
                        m2 = cairo.Matrix()
                        m1.translate(-deltax, -deltay)
                        m2.translate(deltax, deltay)
                        m *= m1
                        m *= cairo.Matrix(x, 0, 0, y, 0, 0)
                        m *= m2

                elif cmd == "skew":
                    if mode == "corner":
                        x, y = args
                        ## TODO: x and y should be the tangent of an angle
                        t *= cairo.Matrix(1, 0, x, 1, 0, 0)
                        t *= cairo.Matrix(1, y, 0, 1, 0, 0)
                        m *= t
                    elif mode == "center":
                        # apply existing transform to centerpoint
                        deltax, deltay = m.transform_point(centerx, centery)
                        x, y = args
                        m1 = cairo.Matrix()
                        m2 = cairo.Matrix()
                        m1.translate(-deltax, -deltay)
                        m2.translate(deltax, deltay)
                        t *= m
                        t *= m1
                        t *= cairo.Matrix(1, 0, x, 1, 0, 0)
                        t *= cairo.Matrix(1, y, 0, 1, 0, 0)
                        t *= m2
                        m = t
                elif cmd == "push":
                    m_archived.append(m)
                elif cmd == "pop":
                    m = m_archived.pop()

        return m
Exemplo n.º 8
0
 def skew(self, x=1, y=0):
     # TODO bring back transform mixin
     t = self._canvas.transform
     t *= cairo.Matrix(1, 0, x, 1, 0, 0)
     t *= cairo.Matrix(1, y, 0, 1, 0, 0)
     self._canvas.transform = t