ZF-33: Cannot reliably draw on loaded documents containing rotated pages

Issue Type: Bug Created: 2006-06-19T22:59:04.000+0000 Last Updated: 2013-02-10T16:36:21.000+0000 Status: Postponed Fix version(s): Reporter: Aaron Edmonds (datafirminc) Assignee: Dolf Schimmel (Freeaqingme) (freak) Tags: - Zend_Pdf

Related issues: - ZF-129

Attachments: - 6890.pdf


If an existing PDF document is loaded which contains a page that is rotated, drawing pretty much doesn't work as the end-user would expect. The original report:

bq. drawText renders text rotated 90 degrees counter-clockwise when using a 5.5(w) x 8.5(h) in. document. You can see an example of this at .

The problem Aaron is experiencing is that the page he's trying to draw to has been rotated 270 degrees and cropped in the page dictionary:

<pre class="literal">
10 0 obj<[17 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R]
/Type/Page/Parent 4 0 R/Rotate 270/MediaBox[0 0 612 792]
/CropBox[0.0 396.0 612.0 792.0]/Resources 11 0 R>>

Zend_Pdf currently does not handle page rotation, so doesn't do anything special with the rotation entry in the page's dictionary.

The issue is that even though the page is "rotated", it is only rotated at display time; the page's coordinate system is unchanged. This is why the $line_1 y coordinate in the example below must be at just over 9 inches to appear on the page.

The illustration zf33illustration.png attached to this issue shows the actual drawing coordinate system for this page:


As a workaround, the user can rotate the drawing coordinate system with page->rotate($x, $y, $degrees) and then adjust the $x and $y coordinates appropriately, but this is a pain.

I'm not sure what we should actually do here. It would be convenient for the end-user if we 'automagically' rotated and translated the coordinate system if a rotated page is loaded, but there may be cases where such behavior is not desired.


Posted by Aaron Edmonds (datafirminc) on 2006-06-19T23:00:48.000+0000

This is the example of the issue. All that was used to generate this is the $page->drawText method.

Posted by Willie Alberty (willie) on 2006-06-20T10:34:27.000+0000

This isn't a problem with drawing the text. The following example works as expected (result attached as reduction1.pdf):

<pre class="highlight">
$pdf = new Zend_Pdf();

// 5.5x8.5in document. the extra colon needed in the page definition appears to be a bug...
$pdf->pages[] = ($page = $pdf->newPage('396:612:'));

$page->setFont(Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES), 18);
$page->drawText('This is a test', 72, 300);


The problem is not that the PDF document uses a custom size, it's that the page that is being drawn to is rotated:

<pre class="literal">
10 0 obj 
<[17 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 27 0 R ] /Type /Page /Parent 4 0 R /Rotate 270 /MediaBox [0 0 612 792 ] 
/CropBox [0 396 612 792 ] /Resources 11 0 R >>

The text appears to be drawing on the page in its original (non-rotated) orientation. Looking to see what needs to be fixed...

In the interim, can you post the actual code you're using to generate this document (as with the sample above)?

Posted by Aaron Edmonds (datafirminc) on 2006-06-20T10:49:13.000+0000

Here is the code that is used to generate the pdf. This is extracted from a method in a controller for a MCV app. The view just sets the content type and echoes $data.

<pre class="highlight">
        $data = $this->Sale->read();
        $pdf = Zend_Pdf::load(ROOT.DS.'pdfs'.DS.'6890.pdf');
        $page = $pdf->pages[0];
        $page->setFont(new Zend_Pdf_Font_Standard(Zend_Pdf_Const::FONT_HELVETICA), 12);
        $margin_left = 50;
        // Line #1
        $line_1 = 650;
        // Plate Number
        $page->drawText($data['Inventory']['license_number'], $margin_left + 5, $line_1);
        $this->set('data', $pdf->render());

Posted by Aaron Edmonds (datafirminc) on 2006-06-20T10:55:59.000+0000

Actually I forgot a line of code. The pdf that is imported is two pages so I use ``` to take off the extra page. Not sure if that helps but I thought I'd put it in there.

Posted by Aaron Edmonds (datafirminc) on 2006-06-20T11:03:28.000+0000

This is the source template that is used in my code.

Posted by Willie Alberty (willie) on 2006-06-20T11:08:06.000+0000

Thanks for the code. I'm trying to reproduce your issue here, but Zend_Pdf is throwing an exception when trying to read the nstv.pdf file. (That's another bug.) Can you attach the original 6890.pdf file?

Posted by Willie Alberty (willie) on 2006-06-20T11:08:54.000+0000

LOL - you beat me to the punch. Taking a look now...

Posted by Willie Alberty (willie) on 2006-06-20T12:11:31.000+0000

Attached illustration showing the actual drawing coordinate system

Posted by Willie Alberty (willie) on 2006-06-20T12:20:18.000+0000

Changed title of issue and revised description to reflect root of problem. We'll need to hash out a solution here--it's not going to be a trivial change.

Posted by Aaron Edmonds (datafirminc) on 2006-06-20T13:04:29.000+0000

Can you give an example of how you could use $page->rotate($x, $y, $degrees) to fix the text?

Posted by Willie Alberty (willie) on 2006-06-20T14:30:46.000+0000

You need to do two things:

First, you need to rotate the coordinate system. $x and $y specify the rotation point. Positive numbers for $degrees rotate counter-clockwise; negative numbers rotate clockwise. I find it easiest to rotate about the origin (imagine rotating the a sheet of paper with the lower-left corner pinned). So you'd need something like this: $page->rotate(0, 0, deg2rad(-90));

Then, you need to adjust the $x and $y coordinates for your drawing commands. Right now, you'll have to do this manually. (In addition to $page->rotate(), we really need $page->translate() so it becomes automatic. See ZF-64.) If you rotated about the origin, you probably only need an offset for your $x coordinates: $xOffset = -792

Note that the rotation origin and the specific offsets you use will be entirely dependent on the page you're working with. For your specific example, the page was rotated 270 degrees clockwise and the bottom half was cropped. Other documents will be different. Trial-and-error and a little bit of sleuthing inside the PDF file itself will help you find the right values to use.

Here's a full example using your document:

<pre class="highlight">
$pdf = Zend_Pdf::load('/path/to/6890.pdf');

$page = $pdf->pages[0];
$page->setFont(Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES), 18);

// Rotate the coordinate system 90 degrees clockwise
$page->rotate(0, 0, deg2rad(-90));

// Calculate the x and y offsets to "shift the origin."
$xOffset = -792;
$yOffset = 0;

// Make the text blue (so you can see it; I find it easier to adjust positioning this way).
$page->setFillColor(new Zend_Pdf_Color_HTML('blue'));

$page->drawText('This is a test', (24 + $xOffset), (418 + $yOffset));


Posted by Jayson Minard (jayson) on 2006-07-09T00:34:45.000+0000

Positioned out a few releases, if timing isn't right please set fix version to something more appropriate.

Posted by Bill Karwin (bkarwin) on 2006-11-13T15:16:40.000+0000

Changing fix version to 0.6.0.

Posted by Alexander Veremyev (alexander) on 2007-05-25T02:04:14.000+0000

Zend_Pdf needs clear API for rotating.

There are two different rotating types: a) page presentation rotating (/Rotate PDF page property is intended for this and must be multiple of 90) b) drawing coordinate system rotation (also needs translate() implementation)

That's a question, should we automatically translate drawing coordinate system if page presentation is rotated???

It needs to be discussed.

Posted by Alexander Veremyev (alexander) on 2007-05-25T02:04:45.000+0000

Postponed to post-1.0 period

Posted by Wil Sinclair (wil) on 2008-04-18T13:11:59.000+0000

This doesn't appear to have been fixed in 1.5.0. Please update if this is not correct.

Posted by Alexander Veremyev (alexander) on 2008-12-03T09:47:53.000+0000

It's clear now how to implement this feature, but it breaks backward compatibility at drawing behavior level. Automatic rotation and shifting coordinate system affects drawing behavior.

So it may come only with ZF 1.8 or 2.0 and must be described in the release notes.

Have you found an issue?

See the Overview section for more details.


© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.