How to tile a document and add margins to the tiles?

Tags: clippingtilingiText 5

I am tiling a document as is done in the TilingHero example. That works well, but now I'd also like to add margins to each page. Is that possible?

Posted on StackOverflow on Sep 24, 2015 by lagnat

Please take a look at the TileClipped example. It is based on the TilingHero example, but it has a twist:

public void manipulatePdf(String src, String dest)
    throws IOException, DocumentException {
    float margin = 30;
    // Creating a reader
    PdfReader reader = new PdfReader(src);
    Rectangle rect = reader.getPageSizeWithRotation(1);
    Rectangle pagesize = new Rectangle(rect.getWidth() + margin * 2, rect.getHeight() + margin * 2);
    // step 1
    Document document = new Document(pagesize);
    // step 2
    PdfWriter writer
        = PdfWriter.getInstance(document, new FileOutputStream(dest));
    // step 3
    document.open();
    // step 4
    PdfContentByte content = writer.getDirectContent();
    PdfImportedPage page = writer.getImportedPage(reader, 1);
    // adding the same page 16 times with a different offset
    float x, y;
    for (int i = 0; i < 16; i++) {
        x = -rect.getWidth() * (i % 4) + margin;
        y = rect.getHeight() * (i / 4 - 3) + margin;
        content.rectangle(margin, margin, rect.getWidth(), rect.getHeight());
        content.clip();
        content.newPath();
        content.addTemplate(page, 4, 0, 0, 4, x, y);
        document.newPage();
    }
    // step 4
    document.close();
    reader.close();
}

Do you see how we make a distinction between rect and pagesize? We define rect as the size of the original pages and we define pagesize as a size that is slightly bigger (depending on the value of margin).

We use rect when we define the offset x and y, but we add margin to slightly change that offset. We change the offset because we clip the pagesize. Clipping is done by defining a clipping path:

content.rectangle(margin, margin, rect.getWidth(), rect.getHeight());
content.clip();
content.newPath();

Everything added after these three lines will be clipped by the rectangle we define in the rectangle() method. You may want to add extra saveState()/restoreState() methods if you also want to add other content, especially if that content needs to be added outside the clipping path.