[poppler] [PATCHES] Support for the NoRotate annotation flag
Carlos Garcia Campos
carlosgc at gnome.org
Sun Mar 31 06:16:53 PDT 2013
Fabio D'Urso <fabiodurso at hotmail.it> writes:
> Hi,
>
> the attached patches implement support for the NoRotate annotation flag, which
> tells that the annotation must *not* be rotated according to the page
> orientation or requested rendering rotation (more on this later).
>
> The main reason why I have implemented these patches is
> https://bugs.kde.org/show_bug.cgi?id=313177, which consists in free-text
> annotations' text being wrongly oriented when the page has a /Rotate attribute
> whose value is different than 0. With the NoRotate flag, it will be possible
> to create annotations that always face the viewer, independently from the
> page's /Rotate attribute.
>
> NoRotate annotations are somewhat tricky, because they are never rotated,
> neither according to the orientation of page, nor according to the requested
> *rendering* rotation.
> I'm attaching a "orientation-examples.pdf" that shows this very important
> aspect. If you open it in acroread and rotate the pages, you'll see that
> NoRotate annotations pivot on their top-left corner and always face the
> viewer. I want to stress on this aspect: what you get if you render a page
> containing a NoRotate annotation and then apply a rotation *IS NOT* the same
> result that you would obtain by directly rendering the page at that
> rotation (see attached image for an example). This is the reason why I had to
> write patch 0004.
>
> ~ PATCHES 0001 and 0002
>
> Patch 0001 changes the Gfx::drawAnnot method so that it "unrotates" the
> coordinate system before drawing NoRotate annotations. This is the patch that
> actually implements the NoRotate flag, and it works in all cases but
> rasterized postscript output, which is addressed in patch 0004.
>
> Patch 0002 adds rotation control in poppler-qt4's demo application. I've used
> this patch to quickly test how NoRotate annotations behave with different
> rendering rotations.
> @@ -5144,6 +5157,28 @@ void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor,
> return;
> }
>
> + // saves gfx state and automatically restores it on return
> + GfxStackStateSaver stackStateSaver(this);
> +
> + /* If flag NoRotate is set then we need to "unrotate" the coordinate system */
> + if ((flags & Annot::flagNoRotate) && state->getRotate() != 0) {
> + const double angle_rad = state->getRotate() * M_PI / 180;
> + const double c = cos(angle_rad);
> + const double s = sin(angle_rad);
> +
> + // Rotation around topleft corner (xMin, yMax)
> + const double unrotateMTX[6] = {
> + +c, +s,
> + -s, +c,
> + -c*xMin + s*yMax + xMin, -c*yMax - s*xMin + yMax
> + };
> +
> + state->concatCTM(unrotateMTX[0], unrotateMTX[1], unrotateMTX[2],
> + unrotateMTX[3], unrotateMTX[4], unrotateMTX[5]);
> + out->updateCTM(state, unrotateMTX[0], unrotateMTX[1], unrotateMTX[2],
> + unrotateMTX[3], unrotateMTX[4], unrotateMTX[5]);
> + }
> +
> // draw the appearance stream (if there is one)
> if (str->isStream()) {
Unfortunately this doesn't work for the cairo backend either, since
state->getRotate() will be 0. In cairo the user typically does something
like:
cairo_create()
cairo_translate()
cairo_scale()
cairo_rotate()
poppler_page_render()
And we always pass 0 to displaySlice() since the cairo context is
already transformed.
--
Carlos Garcia Campos
PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/poppler/attachments/20130331/b4e2476a/attachment.pgp>
More information about the poppler
mailing list