[reportlab-users] Path.roundRect (patch)

Robin Becker robin at reportlab.com
Mon Aug 6 11:34:35 EDT 2012


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

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))

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