Skip to content
Advertisement

Remove FixedLeading at the first line on each page

I want to remove setFixedLeading at the first line on each page (100+)

I read a bit text(more 100 page with help while). And I set padding and margin to 0 but I still have top indent. Why? Help me pls? How delete it?

public static final String DEST = "PDF.pdf";
public static void main(String[] args) throws FileNotFoundException {

    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST));
    Document doc = new Document(pdfDoc);
    doc.setMargins(0,0,0,0);
    for (int i = 0; i <20 ; i++) {
        Paragraph element = new Paragraph("p " + i);
        element.setPadding(0);
        element.setMargin(0);
        element.setFixedLeading(55);
        doc.add(element);
    }
    doc.close();

}

PDF file: https://pdfhost.io/v/Byt9LHJcy_PDFpdf.pdf

First page:

Second page

Advertisement

Answer

At the time of element creation you don’t know the page it will end up on nor its resultant position. I don’t think there is a property that allows you to configure the behavior depending on whether it’s the top element on a page (such property would be too custom and tied to a specific workflow).

Fortunately, the layout mechanism is quite flexible and you can implement the desired behavior in a couple of lines of code.

First off, let’s not use setFixedLeading and set the top margin for all paragraphs instead:

Document doc = new Document(pdfDocument);
doc.setMargins(0, 0, 0, 0);
for (int i = 0; i < 20; i++) {
    Paragraph element = new Paragraph("p " + i);
    element.setPadding(0);
    element.setMargin(0);
    element.setMarginTop(50);
    doc.add(element);
}
doc.close();

This does not pretty much change anything in the visual result – it’s just another way of doing things.

Now, we need a custom renderer to tweak the behavior of a paragraph if it is rendered at the top of the page. We are going to override layout method and check if the area we are given is located at the top of the page – and if so, we will not apply the top margin:

private static class CustomParagraphRenderer extends ParagraphRenderer {

    Document document;

    public CustomParagraphRenderer(Paragraph modelElement, Document document) {
        super(modelElement);
        this.document = document;
    }

    @Override
    public IRenderer getNextRenderer() {
        return new ParagraphRenderer((Paragraph) modelElement);
    }

    @Override
    public LayoutResult layout(LayoutContext layoutContext) {
        if (layoutContext.getArea().getBBox().getTop() == document.getPdfDocument().getDefaultPageSize().getHeight()) {
            ((Paragraph)getModelElement()).setMarginTop(0);
        }
        return super.layout(layoutContext);
    }
}

Now the only thing we need to do is to set the custom renderer instance to each paragraph in the loop:

element.setNextRenderer(new CustomParagraphRenderer(element, doc));

Visual result:

result

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement