Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any trick to rotate text in PDFKit?

I'm using PDFKit.org to generate PDF via JavaScript.

The documentation is pretty self-explanatory, but I'm facing an unsolved problem, and I guess some StackOverflow members may have already found a trick to do it.

I have to rotate a text at some point, and the documentation only explain how to rotate a shape ( like a rect() ).

I already tried several things, but none of them work so far.

So I'm looking for either a way to rotate it by tweaking the code, or maybe some of you can show me a part of the documentation I may have missed?

like image 218
LukyVj Avatar asked Jan 04 '17 17:01

LukyVj


2 Answers

The best way to write rotated text is to rotate pdf around a certain point (where you want to have a starting point of your text), then write it and rotate the pdf document back. Code example:

doc.rotate(angle, { origin: [x,y] });
doc.text( 'TEST', x, y);
doc.rotate(angle * (-1), { origin: [x,y] });

This way you don't need to calculate a new position.

Also it's worth knowing that pdfkit takes x and y of our text as left top point of our texts "box" (it did matter in my case).

like image 144
Artur Pschybysz Avatar answered Sep 20 '22 14:09

Artur Pschybysz


There's no special trick, but it's critical to correctly understand how transformations are applied in PDFKit.

The main thing to understand is that you don't rotate text or a shape: you rotate your document, as implied by doc.rotate(...).rect(...).

It might help you to see your document as a canvas with physical properties. One of its properties is its rotation.
If you want to draw rotated text on a page of paper, what you will likely do is physically rotate your page, then write some text horizontally as you'd usually do, then rotate back the page to its normal state.
What you end up with then, is a rotated text on a straight page:

This is exactly how PDFKit works: you apply a transformation on your document, draw everything you need to draw in this transformed context, and set back the document to its previous state.

To achieve that you have two methods: doc.save() and doc.restore().

  • Use save() before applying a transformation, so that everything that's been drawn before that isn't affected.
  • You can then transform your canvas and draw what you need
  • Once you've drawn everything that needed to be transformed, call restore() to put back the document in its initial state. It's basically going to roll back all transformations (ie. rotation, scaling, translation) performed after the latest save() call.

To (kinda) reproduce the above diagram you'd do:

doc.text('text', ...)
doc.save()
doc.rotate(90).text('rotated text', ...)
doc.restore()

One last thing to understand is that your document's coordinates system is affected by transformations:

So if text was drawn at coordinates (0, 0), then rotated text was drawn at something like (0, documentHeight / 2 - offset).
It's pretty easy to deal with when using multiples of 90 degrees rotations, but you'll have to play with trigonometry otherwise :)

To facilitate things, you can play with the origin of the rotation to make sure you rotate the document around a point that makes sense to your next drawings!

like image 44
Olivier Lance Avatar answered Sep 16 '22 14:09

Olivier Lance