Search code examples
javaitext

iText fails to render paragraph with overlength text


I want to add a variable string to a fixed drawing rectangle using iText 7 - this is a sample code:

try (PdfWriter writer = new PdfWriter("test.pdf");
        PdfDocument pdf = new PdfDocument(writer)) {
    // Create a page
    PdfPage currentPage = pdf.addNewPage(PageSize.A4);
    // Create the position rectangle
    Rectangle rect = new Rectangle(
            75f, 
            currentPage.getPageSize().getHeight() - 315f - 22f, 
            75f, 
            22f
    );
    // Create the font
    PdfFont currentFont = PdfFontFactory.createFont(
            "Helvetica", 
            "Cp1252"
    );
    // Create the paragraph
    Paragraph p = (new Paragraph("Some longer value"))
            .setFont(currentFont)
            .setFontSize(12f)
            .setWidth(75f)
            .setHeight(22f)
            .setTextAlignment(TextAlignment.LEFT);
    // Add the paragraph
    (new Canvas(new PdfCanvas(currentPage), pdf, rect))
            .add((BlockElement)p);
}

When I run this code, I'll get this exception when the last line is being executed:

Exception in thread "main" java.lang.IllegalArgumentException: fromIndex(0) > toIndex(-1)
        at java.base/java.util.AbstractList.subListRangeCheck(AbstractList.java:509)
        at java.base/java.util.ArrayList.subList(ArrayList.java:1138)
        at com.itextpdf.layout.renderer.ParagraphRenderer.layout(ParagraphRenderer.java:235)
        at com.itextpdf.layout.renderer.RootRenderer.addChild(RootRenderer.java:84)
        at com.itextpdf.layout.renderer.CanvasRenderer.addChild(CanvasRenderer.java:86)
        at com.itextpdf.layout.RootElement.add(RootElement.java:98)
        at itext.bug.reproduce.ITextBugReproduce.main(ITextBugReproduce.java:50)

When I replace Some longer value with test, everything works. So it seems adding an overlength string to a small drawing area fails.

The problem is: In real know only the destination drawing area, but I don't know the string which is going to be processed. This leads to my question: How can I draw even an overlength string to the PDF without pre-measuring etc.?

Update: When I expand the paragraph dimensions, I still have the same exception, so I assume its not a problem with the paragraph, but with the canvas which I use to restrict drawing to the destination rectangle (for not overwriting any contents outside of the rectangle).


Solution

  • With a newer iText 7 version (I used 7.0.1 before) and a slightly different code it's working now:

    BasicConfigurator.configure();// Satisfy the logger
    try (PdfWriter writer = new PdfWriter("test.pdf");
            PdfDocument pdf = new PdfDocument(writer)) {
        // Create a page
        PdfPage currentPage = pdf.addNewPage(PageSize.A4);
        // Create the position rectangle
        Rectangle rect = new Rectangle(
                75f, 
                currentPage.getPageSize().getHeight() - 315f - 22f, 
                75f, 
                22f
        );
        // Create the font
        PdfFont currentFont = PdfFontFactory.createFont(
                "Helvetica", 
                "Cp1252"
        );
        // Create the paragraph
        Paragraph p = (new Paragraph("Some longer value"))
                .setFont(currentFont)
                .setFontSize(12f)
                .setWidth(75f)
                .setHeight(22f)
                .setTextAlignment(TextAlignment.LEFT);
        // Override the renderer
        p.setNextRenderer(new ParagraphRenderer(p){
            @Override
            public List initElementAreas(LayoutArea area) {
                List list = new ArrayList();
                list.add(rect);
                return list;
            }
        });
        // Add the paragraph
        (new Canvas(new PdfCanvas(currentPage), rect))
                .add((BlockElement)p);