[reportlab-users] Integrate "Flowable" (SVG) with caching

Robin Becker robin at reportlab.com
Thu Nov 16 11:34:20 EST 2017


On 16/11/2017 14:16, Yannick Gosteli @ PETZI wrote:
> Robin,
> 
> Your example does not match with the case of SVG that we need to render in 
> reportlab - I mean we have to build the rasterization.
> The ways I know to do this rasterization are "renderPDF.draw()" and 
> "renderPM.drawToPIL()".
> 

there is also what Dinu pointed out, svglib can convert svg directly to a 
drawing object. That can be rendered like any other flowable using its drawOn 
command.

> 
> - CASE 1 -
> 
> "renderPDF.draw()" method explicitly needs x & y => there is no way to move the 
> point where SVG will be printed via the doForm()
> 
> Example:
> ```
> canv.beginForm('svg')
> renderPDF.draw(drawing, canv, x=0, y=0)
> canv.endForm()
> 
> canv.translate(100,100) # no effect
> canv.doForm('svg')
> 
> -------------
> 
I suspect your use of renderPDF.draw is drawing directly to the canvas and is 
ignoring the form entirely. I would just try drawing.drawOn(canv,0,0) instead..


eg new example which shows the drawing being translated etc etc; if you want to 
use svg I would definitely use this technique with Dinu's svglib svg2rlg function.
###############################################
from reportlab.pdfgen.canvas import Canvas
from reportlab.graphics.shapes import Drawing, Line, Circle

canv= Canvas('tform.pdf')

#make a drawing
d=Drawing(20,20)
d.add(Line(0,0,10,10,strokeWidth=1,strokeColor=(0,0,1)))
d.add(Circle(15,15,5,strokeWidth=1,strokeColor=(1,0,0),fillColor=(0.5,0.5,0)))


#define a form
canv.beginForm('myform')
canv.setFont('Times-Roman',10)
canv.setFillColor((1,0,0))
canv.setStrokeColor((0,1,0))
canv.setLineWidth(2)
s='In myform'
w=canv.stringWidth(s)
d.drawOn(canv,10,10)
canv.drawString(2,4,s)
canv.rect(0,0,2+w,14,stroke=1)
canv.endForm()

canv.drawString(10,10,'Hello World')


canv.saveState()
canv.translate(100,100)
canv.lines([(0,-5,0,5), (-5,0,5,0)])
canv.doForm('myform')
canv.restoreState()

canv.saveState()
canv.translate(200,200)
canv.scale(1.5,1.5)
canv.lines([(0,-5,0,5), (-5,0,5,0)])
canv.doForm('myform')
canv.restoreState()

canv.saveState()
canv.translate(300,300)
canv.lines([(0,-5,0,5), (-5,0,5,0)])
canv.doForm('myform')
canv.restoreState()

canv.showPage()
canv.save()
###############################################

> 
> - CASE 2 -
> 
> "renderPM.drawToPIL()" will render in a PIL image => we can use it in 
> canv.drawImage() => no needs of "form" (useless)
> 
> ------------
> 
> 
> Let me know if you see a better solution
> 
> Best regards
> Yannick
> 
> 
> Yannick Gosteli
> PETZI - Association suisse des clubs de musiques actuelles
> Billetterie/Petzitickets
> yannick.gosteli at petzi.ch
> www.petzi.ch - www.petzitickets.ch
> 
> Le 16. 11. 17 à 14:38, Robin Becker a écrit :
>> On 16/11/2017 12:57, Dinu Gherman wrote:
>>> Hi Yannick,
>>>
>>> have you tried using svglib that I originally wrote in the context of 
>>> reportlab? Using it you can import an SVG file and render it as a reportlab 
>>> flowable. I’m just not sure if it will be cached and reused the same way as 
>>> bitmap images over many pages. And I haven’t really produced 
>>> reportlab-generated docs in a long time.
>>>
>>> https://github.com/deeplook/svglib
>>>
>>> Cheers,
>>>
>>> Dinu
>>>
>> The current code draws directly into the canvas, so if a repeated image is 
>> required the code for drawing is repeated and document gets larger.
>>
>> My hack solution would be to draw into a form and then render the form as 
>> often as required.
>>
>> Yannick is correct in saying that the form is created in it's own space, but 
>> if that's zero based then when you use the form you can surround the doForm with
>>
>> saveState
>> scale translate etc etc
>> doForm
>> restoreState
>>
>> to position the image anywhere on the page see below.
>>
>> Obviously this is more work than just using a built in method, but it should 
>> be easy enough to make an svg cache.
>>
>> EG
>>
>> ############################################
>> from reportlab.pdfgen.canvas import Canvas
>>
>> canv= Canvas('tform.pdf')
>>
>> #define a form
>> canv.beginForm('myform')
>> canv.setFont('Times-Roman',10)
>> canv.setFillColor((1,0,0))
>> canv.setStrokeColor((0,1,0))
>> canv.setLineWidth(2)
>> s='In myform'
>> w=canv.stringWidth(s)
>> canv.drawString(2,4,s)
>> canv.rect(0,0,2+w,14,stroke=1)
>> canv.endForm()
>>
>> canv.drawString(10,10,'Hello World')
>>
>>
>> canv.saveState()
>> canv.translate(100,100)
>> canv.lines([(0,-5,0,5), (-5,0,5,0)])
>> canv.doForm('myform')
>> canv.restoreState()
>>
>> canv.saveState()
>> canv.translate(200,200)
>> canv.scale(1.5,1.5)
>> canv.lines([(0,-5,0,5), (-5,0,5,0)])
>> canv.doForm('myform')
>> canv.restoreState()
>>
>> canv.saveState()
>> canv.translate(300,300)
>> canv.lines([(0,-5,0,5), (-5,0,5,0)])
>> canv.doForm('myform')
>> canv.restoreState()
>>
>> canv.showPage()
>> canv.save()
>> ############################################
>>
>>
>>
>>
>>>> Am 15.11.2017 um 22:23 schrieb Yannick Gosteli @ PETZI 
>>>> <yannick.gosteli at petzi.ch>:
>>>>
>>>> Dear,
>>>>
>>>> I generate a document that contains a SVG repeated several times.
>>>> I wonder if there is a way to integrate this SVG with "caching" the same way 
>>>> it works with Canvas.drawImage*.
>>>>
>> ............
> 
> _______________________________________________
> reportlab-users mailing list
> reportlab-users at lists2.reportlab.com
> https://pairlist2.pair.net/mailman/listinfo/reportlab-users


-- 
Robin Becker


More information about the reportlab-users mailing list