[reportlab-users] Rotated paragraph/document with ReportLab (vertical text)

2,271 views
Skip to first unread message

Jesus Sanchez-Palencia

unread,
Oct 25, 2012, 9:16:56 AM10/25/12
to reportl...@lists2.reportlab.com
Hi!

I'm trying to get something like the following snippet to actually
draw this document rotated by 90 degrees. The pagesize is already the
way I want it in the end, but the text is still horizontal. How can I
rotate the text making it vertical?
What I want in the end is something similar to calling
canvas.rotate(90) and then canvas.drawString(), but I want to take
the advantage of word wrapping from Paragraph...

---------- SNIPPET ----------
style = getSampleStyleSheet()
normal = style["Normal"]
normal.alignment = TA_CENTER
normal.fontName = "Helvetica"
normal.fontSize = 15

pdf = SimpleDocTemplate("testplatypus.pdf", pagesize = (80, 250),
rightMargin=10, leftMargin=10, topMargin=20,bottomMargin=20)
story = []
text = "I really need this to be wrapped and vertical!"

para = Paragraph(text, normal)
story.append(para)
pdf.build(story)
_______________________________________________
reportlab-users mailing list
reportl...@lists2.reportlab.com
http://two.pairlist.net/mailman/listinfo/reportlab-users

Robin Becker

unread,
Oct 25, 2012, 12:54:08 PM10/25/12
to reportlab-users
I'm not sure exactly why you want to do this, but the code below is a start
you will need to tweak the translate here to get exactly what you want as we
will obviously be rotating about a place that's not exactly clear ie the center
of the top line.

#########################
from reportlab.platypus.doctemplate import SimpleDocTemplate
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_CENTER
from reportlab.platypus.paragraph import Paragraph
class RotatedPara(Paragraph):
def draw(self):
self.canv.saveState()
self.canv.translate(0,0)
self.canv.rotate(90)
Paragraph.draw(self)
self.canv.restoreState()

style = getSampleStyleSheet()
normal = style["Normal"]
normal.alignment = TA_CENTER
normal.fontName = "Helvetica"
normal.fontSize = 15

pdf = SimpleDocTemplate("rotatedpara.pdf", pagesize = (80, 250),
rightMargin=10, leftMargin=10, topMargin=20,bottomMargin=20)
story = []
text = "I really need this to be wrapped and vertical!"

para = RotatedPara(text, normal)
story.append(para)
pdf.build(story)
#########################

On 25/10/2012 14:16, Jesus Sanchez-Palencia wrote:
> Hi!
>
> I'm trying to get something like the following snippet to actually
> draw this document rotated by 90 degrees. The pagesize is already the
> way I want it in the end, but the text is still horizontal. How can I
> rotate the text making it vertical?
> What I want in the end is something similar to calling
> canvas.rotate(90) and then canvas.drawString(), but I want to take
> the advantage of word wrapping from Paragraph...
.........
--
Robin Becker

Jesus Sanchez-Palencia

unread,
Oct 25, 2012, 1:21:22 PM10/25/12
to Robin Becker, reportlab-users
Hi!

On Thu, Oct 25, 2012 at 1:54 PM, Robin Becker <ro...@reportlab.com> wrote:
> I'm not sure exactly why you want to do this, but the code below is a start
> you will need to tweak the translate here to get exactly what you want as we
> will obviously be rotating about a place that's not exactly clear ie the
> center of the top line.

Imagine that I'm generating a PDF to be printed as a label.
The page has to be that size (80x250, for example), and the text has
to be vertical, from bottom to top.

I have tried to this horizontally, saving the PDF, and then rotating
it somehow but usually what the pdf libraries do is just add a \Rotate
-90 into the PDF. The printers can't understand that, this is why I
need to actually rotate the canvas.

Is there any documentation about what happens to the coordinates after
we canvas.rotate(90) everything? That would help to tweak the
translation, but in summary I want the same behavior that my code
would have if the document had a size of 250x80 and then the result
would be rotated 90 degrees counter clockwise.

I will test your snippet later, thanks.

Tim Roberts

unread,
Oct 25, 2012, 1:41:15 PM10/25/12
to reportlab-users
Jesus Sanchez-Palencia wrote:
> Is there any documentation about what happens to the coordinates after
> we canvas.rotate(90) everything?

This is all part of PostScript, and it's all from a mathematical point
of view. A standard canvas has its origin at the bottom left, with X
increasing to the right, and Y increasing as you go up. For a 250 x 80
document:

+Y
(0,80) (250,80)
+-----------+
| |
| canvas |
| |
o-----------+ +X
(0,0) (250,0)

Positive rotation is counter-clockwise about the origin, so rotating by
90 degrees changes things so that Y increases to the left, and X
increases going up. The origin remains the same, so after this
rotation, all of the Y coordinates in the canvas will be negative.
That's why you often use a translation when you do a rotation:

+X
(250,0) (250,-80)
. - - - +-------+
: | |
: | |
: |canvas |
: | |
: | |
: | |
+Y . - - - o-------+
(0,0) (0,-80)

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Jesus Sanchez-Palencia

unread,
Nov 5, 2012, 10:23:22 PM11/5/12
to reportlab-users
Ok,

I can't get this to work as I was expeting it to work... All I want is
to get this snippet:

############################################
from reportlab.platypus.doctemplate import SimpleDocTemplate
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_CENTER
from reportlab.platypus.paragraph import Paragraph
class RotatedPara(Paragraph):
def draw(self):
self.canv.saveState()
Paragraph.draw(self)
self.canv.restoreState()


style = getSampleStyleSheet()
normal = style["Normal"]
normal.alignment = TA_CENTER
normal.fontName = "Helvetica"
normal.fontSize = 15

pdf = SimpleDocTemplate("notrotatedpara.pdf", pagesize = (250, 80),

rightMargin=5, leftMargin=5, topMargin=10, bottomMargin=5)
story = []
text = "Yet another random foo long text!"

para = RotatedPara(text, normal)
story.append(para)
pdf.build(story)
############################################

to work on the very same way it is right now, but with the result
being a rotated pdf. In other words, the end document will be 80 x 250
instead of 250 x 80.

So inside def draw(self) I have tried to self.canv.rotate(90) and then
to translate it as pointed out by Robin Becker, but I can't get the
same behavior. First of all, I don't really get what happens with the
margins from SimpleDocTemplate when we are dealing with the rotated
paragraph. Second, I can't get the translation to work properly. So
far translate(-125, -40) gave me the best results, but this was
somewhat randomly chosen...

Can anyone help me? Are there any other way around this?


Thanks again,
Jesus

Robin Becker

unread,
Nov 6, 2012, 10:19:32 AM11/6/12
to reportlab-users
On 06/11/2012 03:23, Jesus Sanchez-Palencia wrote:
> Ok,
>
> I can't get this to work as I was expeting it to work... All I want is
> to get this snippet:
>
>.........
> normal.fontSize = 15
>
> pdf = SimpleDocTemplate("notrotatedpara.pdf", pagesize = (250, 80),
>
......
rotations will not normally affect the page size so if you want a page that's 80
x 250 you should specify that. Again if you don't want to rotate the text why
use the extended class (even if the rotation has been removed). Rotations work
around an origin, in our case that's the bottom left hand corner of the page x=0
y=0.
--
Robin Becker

Jesus Sanchez-Palencia

unread,
Nov 6, 2012, 10:47:37 AM11/6/12
to reportlab-users
Hi! Thanks for answering!

On Tue, Nov 6, 2012 at 12:19 PM, Robin Becker <ro...@reportlab.com> wrote:
> rotations will not normally affect the page size so if you want a page
> that's 80 x 250 you should specify that. Again if you don't want to rotate
> the text why use the extended class (even if the rotation has been removed).
> Rotations work around an origin, in our case that's the bottom left hand
> corner of the page x=0 y=0.

I DO want to rotate the text. I was just saying that the output I want
is exactly what that code is doing, but rotated by 90 degrees counter
clockwise.

About the rotation, so if I first translate the origin to the center
of the document (point (40, 125) for a 80x250 document, right?) and
then rotate(90) it should do what I am expecting, right?

cheers,
jesus

Robin Becker

unread,
Nov 6, 2012, 11:46:57 AM11/6/12
to reportlab-users
On 06/11/2012 15:47, Jesus Sanchez-Palencia wrote:
> Hi! Thanks for answering!
>
> On Tue, Nov 6, 2012 at 12:19 PM, Robin Becker <ro...@reportlab.com> wrote:
>> rotations will not normally affect the page size so if you want a page
>> that's 80 x 250 you should specify that. Again if you don't want to rotate
>> the text why use the extended class (even if the rotation has been removed).
>> Rotations work around an origin, in our case that's the bottom left hand
>> corner of the page x=0 y=0.
>
> I DO want to rotate the text. I was just saying that the output I want
> is exactly what that code is doing, but rotated by 90 degrees counter
> clockwise.
>
> About the rotation, so if I first translate the origin to the center
> of the document (point (40, 125) for a 80x250 document, right?) and
> then rotate(90) it should do what I am expecting, right?
.......

If you do that you then have a document centred at that position. After the
rotate it's still centred there so you may need to translate back to the origin
that you want the rest of the document handling to respect.

Jesus Sanchez-Palencia

unread,
Nov 6, 2012, 12:22:28 PM11/6/12
to Robin Becker, reportlab-users
Hi,

On Tue, Nov 6, 2012 at 1:46 PM, Robin Becker <ro...@reportlab.com> wrote:
> On 06/11/2012 15:47, Jesus Sanchez-Palencia wrote:
>>
>> Hi! Thanks for answering!
>>
>> On Tue, Nov 6, 2012 at 12:19 PM, Robin Becker <ro...@reportlab.com> wrote:
>>>
>>> rotations will not normally affect the page size so if you want a page
>>> that's 80 x 250 you should specify that. Again if you don't want to
>>> rotate
>>> the text why use the extended class (even if the rotation has been
>>> removed).
>>> Rotations work around an origin, in our case that's the bottom left hand
>>> corner of the page x=0 y=0.
>>
>>
>> I DO want to rotate the text. I was just saying that the output I want
>> is exactly what that code is doing, but rotated by 90 degrees counter
>> clockwise.
>>
>> About the rotation, so if I first translate the origin to the center
>> of the document (point (40, 125) for a 80x250 document, right?) and
>> then rotate(90) it should do what I am expecting, right?
>
> .......
>
> If you do that you then have a document centred at that position. After the
> rotate it's still centred there so you may need to translate back to the
> origin that you want the rest of the document handling to respect.

And where does the Paragraph.draw(self) start to draw?
Reply all
Reply to author
Forward
0 new messages