[reportlab-users] Path.roundRect (patch)
Robin Becker
robin at reportlab.com
Mon Aug 6 11:34:35 EDT 2012
Peter,
I've implemented your gradient patch and a primitive existence test in
test_pdfgen_general.py. It works well.
I am less enthusiastic about this patch, but not for any specific reason.
First off it is not obvious which object/class should implement these shapes.
Should canvases implement the primitives, in this case the primitive path
operations moveTo/lineTo/curveTo/close and then have a more abstract class to do
the ellipses/arcs rounded rectangles etc. If we are going to move the roundRect
code into the PDFPathObject I would prefer that it should look like this
def roundRect(self, x, y, width, height, radius):
"""Draws a rectangle with rounded corners. The corners are
approximately quadrants of a circle, with the given radius."""
#use a precomputed set of factors for the bezier approximation
#to a circle. There are six relevant points on the x axis and y axis.
#sketch them and it should all make sense!
t = 0.4472 * radius
x0 = x
x1 = x0 + t
x2 = x0 + radius
x3 = x0 + width - radius
x4 = x0 + width - t
x5 = x0 + width
y0 = y
y1 = y0 + t
y2 = y0 + radius
y3 = y0 + height - radius
y4 = y0 + height - t
y5 = y0 + height
self.moveTo(x2, y0)
self.lineTo(x3, y0) #bottom row
self.curveTo(x4, y0, x5, y1, x5, y2) #bottom right
self.lineTo(x5, y3) #right edge
self.curveTo(x5, y4, x4, y5, x3, y5) #top right
self.lineTo(x2, y5) #top row
self.curveTo(x1, y5, x0, y4, x0, y3) #top left
self.lineTo(x0, y2) #left edge
self.curveTo(x0, y1, x1, y0, x2, y0) #bottom left
self.close()
ie it should re-use its own primitives; the same could be said about all the
other complex operations. However, the direct code in the canvas that used to
stuff the canvas code is now being made two levels down so the initial moveTo
that was originally
canvas._code.append('n %s m' % fp_str(x2, y0))
has now become
p = pathobject.PDFPathObject()
p.roundRect(x, y, width, height, radius)
......
pathobject.moveTo(x2, y0)
pathobject._code_append('%s m' % fp_str(x,y))
canvas._code.append(pathobject......)
so there is more overhead.
If we do this properly then presumably all of the other cases in the canvas code
which can be replaced by an equivalent pathobject alternative should also be
treated the same.
I don't think I have any objection to putting a roundRect into the
PDFPathObject, but should we be removing the faster code from Canvas?
On 04/08/2012 03:36, Peter Johnson wrote:
> I noticed that while there is a Canvas.roundRect function, there's not
> an equivalent Path.roundRect function. The attached patch (against
> SVN) moves the majority of the Canvas.roundRect() implementation into
> a new Path.roundRect(), and then reimplements the former using the
> latter.
>
> -Peter
........
--
Robin Becker
More information about the reportlab-users
mailing list