Creating enormous pages in PDF
The PDF format has a few arbitrary limits, most of which start life as implementation limits in Acrobat before they migrate to the official specification and become hard limits for everyone working with PDF. One that we were genuinely not expecting to see came up in an email from a customer last month.
Acrobat has a maximum page size of 200x200 inches - that's just over 5 meters a side, or 25m². It turns out for one particular customer (in the packaging industry, naturally) that 5m is nowhere near enough. Fortunately this restriction was removed in PDF revision 1.6, although (of course) not by updating the code in Acrobat to remove this limit. No, instead a new "User Unit" property was added to the PDF language. Where supported this will act as a multiplier, scaling up the content of the page.
We've added support for this in version 2.22 of our API, with a new PDFPage.setUserUnit() method. In an ideal world we would have then handled all the scaling maths internally - generally we try to hide this sort of implementation horror from the customer, but for various reasons to do with font sizes in styles this simply wasn't practical. The good news is that you still don't really need to think about scaling.
This is because our PDFCanvas class (which creates a PDF "Form XObject") is not subject to this arbitrary limit. As the PDFCanvas can do everything a page can do, you can simply create your graphics on a PDFCanvas object at actual size, then draw it onto the scaled page right at the end. This avoids any need to manage scaling.
Here's an example showing how to create an actual football-pitch size page, complete with markings:
float w = 283464; // 100 meters float h = 195590; // 68 meters PDFCanvas canvas = new PDFCanvas(w, h); PDFStyle style = new PDFStyle(); style.setLineWeighting(250); style.setLineColor(Color.white); canvas.setStyle(style); canvas.drawLine(w/2, 0, w/2, h); // halfway line canvas.drawCircle(w/2, h/2, 28346); // center circle // penalty boxes canvas.drawRectangle(0, (h-114048)/2, 46656, (h+114048)/2); canvas.drawRectangle(w - 46656, (h-114048)/2, w, (h+114048)/2); // goal boxes canvas.drawRectangle(0, (h-56692)/2, 17007, (h+56692)/2); canvas.drawRectangle(w - 17007, (h-56692)/2, w, (h+56692)/2); // draw canvas on the page // We're going to create a page 1/100th of the full size (1000mm x 690mm). float userunit = 100; PDFPage page = new PDFPage((int)(w/userunit), (int)(h/userunit)); page.setUserUnit(userunit); page.drawCanvas(canvas, 0, 0, w/userunit, h/userunit);
The only new method here is the one marked in yellow above. Unfortunately any annotations or hyperlinks to areas of the page will have to be scaled manually: so if you were adding an annotation to the above page, you'd need to divide the final coordinates by 100.
I can't imagine this will be useful for too many. But if you do find yourself needing to create a PDF on this sort of scale, please let us know - we'd love to hear about it. Don't forget to send us a photo of your printer!