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

Tags: clippingtilingiText 7

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 {
    float margin = 30;
    PdfDocument srcDoc = new PdfDocument(new PdfReader(src));
    Rectangle rect = srcDoc.getFirstPage().getPageSizeWithRotation();
    Rectangle pageSize = new Rectangle(rect.getWidth() + margin * 2, rect.getHeight() + margin * 2);

    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
    pdfDoc.setDefaultPageSize(new PageSize(pageSize));

    PdfCanvas content = new PdfCanvas(pdfDoc.addNewPage());
    PdfFormXObject page = srcDoc.getFirstPage().copyAsFormXObject(pdfDoc);
    // 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.addXObject(page, 4, 0, 0, 4, x, y);
        if (15 != i) {
            content = new PdfCanvas(pdfDoc.addNewPage());
        }
    }
    srcDoc.close();
    pdfDoc.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.

Click this link if you want to see how to answer this question in iText 5.