[reportlab-users] Forms & the canvas
Ian Sparks
Ian.Sparks at etrials.com
Thu Jul 7 11:09:53 EDT 2005
This was a head-scratcher so I'm posting it here in case it helps someone else out.
Be be careful when defining PDF forms via beginForm() and endForm() that canvas operations between beginForm and endForm ignore the current canvas state.
Lets say you have a function drawBox() :
def drawBox(canv):
"""Draw an inch-square box on the canvas"""
canv.rect(5 * inch,-1 * inch,inch,-inch)
Notice that this function assumes that the origin is at the top of the page - it draws an inch from the top. That means you have to have first done the translate to move the origin :
You might be tempted to :
#Define it
canv.translate(0,11 * inch) #Make origin to left corner of letter portrait page
canv.beginForm('test')
drawBox(canv)
canv.endForm()
#Print it
canv.doForm('test')
But that won't work because PDF forms draw to their own plane of existance outside of the current canvas context. That means that all operations you do to the canvas before beginForm() are ignored between the beginForm() and endForm() operation. No scaling, translation, skew, line-widths, color settings etc are maintained and the origin is back to 0,0 (bottom left of page) as if you were working with a new document.
You need to do all your canvas operations INSIDE the beginForm(), endForm() pair :
#Define it
canv.beginForm('test')
canv.translate(0,11 * inch) #Make origin to left corner of letter portrait page
drawBox(canv)
canv.endForm()
#Print it
canv.doForm('test')
This is obvious when you think about what beginForm() and endForm() are doing but because beginForm() and endForm() are methods of the canvas it's easy to forget that and get confused about where your settings went.
An extra paragraph in the manual would have saved me some pain. What about :
ch3_pdffeatures.py :
eg(examples.testforms)
disc("""NOTE : All canvas operations between beginForm() and endForm()
are working in a private canvas that ignores the state
of the existing canvas. All existing color settings, translations,
scaling etc are ignored inside the Form. However, when the Form
is draw it is drawn into the current canvas and will use the
current canvas settings :
""")
eg(examples.testformscanvstate)
examples.py :
testformscanvstate = """
def forms(canvas):
canvas.setStrokeColor(colors.green) #Set stroke color green This will be ignored by the form contents
canvas.beginForm("TestForm")
canvas.rect(0,inch,inch,inch) #Draw an inch-square box.
spumoni(canvas)
canvas.endForm()
#draw it (the box will be in green)
canvas.doForm("SpumoniForm")
canvas.setStrokeColor(colors.black)
#draw it (the box will be in black)
canvas.doForm("SpumoniForm")
"""
More information about the reportlab-users
mailing list