I went through *exactly* the same source review last month when I started hitting it. I was quite happy to see that iText actually sets the rotation in the page dictionary (I needed it for constructing unit tests), but I agree that the way it happens is a bit hard to follow. If you think about it from the way the PDF spec is written, though, you could see how this implementation evolved:
There is a dictionary entry for the unrotated page size, plus the rotation entry. The rectangle that the user has been working with has been in rotated coordinates, so to set the unrotated page size, they have to unrotate. On the content side, iText rotates the coordinate system just to make life easier for the user. And PDF has a complete disassociation between rotation at the page level, and the required rotation at the content level. Confusing as all get out. In my parsing code, I am currently ignoring the page rotation entirely, so rotated pages wind up with text alignment being off by 90 degrees (generally speaking, not an issue for text extraction because all of the text rotates - but for rendering or geometric filtering, it is an issue). At some point, I'll have to address this - probably by applying yet another CTM when computing user space coordinates. Oy. - Kevin Mark Storer-2 wrote: > > Looking through the Rectangle.rotate() -> Pdf-structures-in-the-output > code, I think we might have An Issue. Woah woah woah... let me check the > trunk instead of my red-headed-stepchild-branch of 2.0.whatever-it-was. > > Rectangle.rotate() { // yep, no changes > Rectangle rect = new Rectangle(lly, llx, ury, urx); > rect.rotation = rotation + 90; > rect.rotation %= 360; > return rect; > } > > It swaps the x's and ys, and sets the rotation member. > > In PdfDocument.newPage(), we find The Following Code: > > // [U1] page size and rotation > int rotation = pageSize.getRotation(); > ... > PdfPage page = new PdfPage(new PdfRectangle(pageSize, rotation), > thisBoxSize, resources, rotation); > > ---- > So rotation gets passed to the new PdfRectangle and to the new PdfPage: > > public PdfRectangle(float llx, float lly, float urx, float ury, int > rotation) { > super(); > if (rotation == 90 || rotation == 270) { > this.llx = lly; > this.lly = llx; > this.urx = ury; > this.ury = urx; > } > else { > this.llx = llx; > this.lly = lly; > this.urx = urx; > this.ury = ury; > } > super.add(new PdfNumber(this.llx)); > super.add(new PdfNumber(this.lly)); > super.add(new PdfNumber(this.urx)); > super.add(new PdfNumber(this.ury)); > } > ---- > > PdfRectangle swaps the coordinates *again*. It doesn't store the rotation > value, just makes use of it. > > And... > PdfPage(PdfRectangle mediaBox, HashMap<String, PdfRectangle> boxSize, > PdfDictionary resources, int rotate) { > super(PAGE); > this.mediaBox = mediaBox; > put(PdfName.MEDIABOX, mediaBox); > put(PdfName.RESOURCES, resources); > if (rotate != 0) { > put(PdfName.ROTATE, new PdfNumber(rotate)); // *** This is the > only place its used *** > } > for (int k = 0; k < boxStrings.length; ++k) { > PdfObject rect = boxSize.get(boxStrings[k]); > if (rect != null) > put(boxNames[k], rect); > } > } > > ---- > > So we've swapped it back, and stored the value in the PdfDictionary for > the page ONLY. It's not retrieved anywhere in PdfPage... > > Ah! In PdfContent, the rotation is taken from the original Rectangle > again and used in a transformation matrix, just like Kev(in?) said. > > So while swapping the rectangle coordinates twice is certainly ODD, it > doesn't look like there's anything genuinely broken in there... just an > "Even Number of Sign Errors". Those are fine as long as you find both of > them. Finding one and having the "correct" output anyway is a bit > maddening. *twitch* > > --Mark Storer > Senior Software Engineer > Cardiff.com > > #include <disclaimer> > typedef std::Disclaimer<Cardiff> DisCard; > > > >> -----Original Message----- >> From: trumpetinc [mailto:forum_...@trumpetinc.com] >> Sent: Tuesday, January 19, 2010 9:00 PM >> To: itext-questions@lists.sourceforge.net >> Subject: Re: [iText-questions] Rotate Page After Adding Text >> to Document >> >> >> >> As a point of clarification, I'm pretty sure that, in >> addition to swapping >> width and height, rotate() signals PdfDocument to add a >> rotation cm entry to >> the beginning of the content stream, and adjusts the rotation >> dictionary >> entry for the page. >> >> And I completely agree with the 'messy code for dealing with >> it' comment. >> As an example, ImportedPage doesn't preserve the page >> rotation from the >> source, which can cause all sorts of mayhem (esp because the >> page rotation >> implies an awkward change in origin). >> >> - K >> >> >> Mark Storer-2 wrote: >> > >> > Ah. So you don't want to spin-the-pages-contents-sideways, you want >> > landscape-vs-portrait. >> > >> > "Rotation" isn't the word you want. You just want to >> change the page size >> > from 8.5x11 to 11x8.5. By the way, Rectangle.rotate() >> doesn't really >> > rotate the page either, it swaps the width/height. In PDF, >> there's a >> > concept of page rotation indepentant of a page's physical >> dimensions, >> > which can lead to all manner of Interesting Confusion (and >> messy code for >> > dealing with it). >> > >> > >> >> -- >> View this message in context: > http://old.nabble.com/Rotate-Page-After-Adding-Text-to-Document-tp27234067p27236838.html > Sent from the iText - General mailing list archive at Nabble.com. > > > ------------------------------------------------------------------------------ > Throughout its 18-year history, RSA Conference consistently attracts the > world's best and brightest in the field, creating opportunities for > Conference > attendees to learn about information security's most important issues > through > interactions with peers, luminaries and emerging and established > companies. > http://p.sf.net/sfu/rsaconf-dev2dev > _______________________________________________ > iText-questions mailing list > iText-questions@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/itext-questions > > Buy the iText book: http://www.1t3xt.com/docs/book.php > Check the site with examples before you ask questions: > http://www.1t3xt.info/examples/ > You can also search the keywords list: > http://1t3xt.info/tutorials/keywords/ > > ------------------------------------------------------------------------------ > Throughout its 18-year history, RSA Conference consistently attracts the > world's best and brightest in the field, creating opportunities for > Conference > attendees to learn about information security's most important issues > through > interactions with peers, luminaries and emerging and established > companies. > http://p.sf.net/sfu/rsaconf-dev2dev > _______________________________________________ > iText-questions mailing list > iText-questions@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/itext-questions > > Buy the iText book: http://www.1t3xt.com/docs/book.php > Check the site with examples before you ask questions: > http://www.1t3xt.info/examples/ > You can also search the keywords list: > http://1t3xt.info/tutorials/keywords/ > > -- View this message in context: http://old.nabble.com/Rotate-Page-After-Adding-Text-to-Document-tp27234067p27245470.html Sent from the iText - General mailing list archive at Nabble.com. ------------------------------------------------------------------------------ Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev _______________________________________________ iText-questions mailing list iText-questions@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/itext-questions Buy the iText book: http://www.1t3xt.com/docs/book.php Check the site with examples before you ask questions: http://www.1t3xt.info/examples/ You can also search the keywords list: http://1t3xt.info/tutorials/keywords/