Search code examples
javaitext7

Generate underline Waves itext7


How can I draw specific underline between :

String s = "This text is underlined with a dashed line";
Paragraph paragraph = new Paragraph();
Text text;
for (int i = 0; i <s.length() ; i++) {
    text = new Text(String.valueOf(s.charAt(i)));
    paragraph.add(text);
    text.setNextRenderer(new DashedLineTextRenderer(text));
}

doc.add(paragraph);
doc.close();

private static class DashedLineTextRenderer extends TextRenderer {

    public DashedLineTextRenderer(Text textElement) {
        super(textElement);
    }

    // If renderer overflows on the next area, iText uses getNextRender() method to create a renderer for the overflow part.
    // If getNextRenderer isn't overriden, the default method will be used and thus a default rather than custom
    // renderer will be created
    @Override
    public IRenderer getNextRenderer() {

        return new DashedLineTextRenderer((Text) modelElement);
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);
        Rectangle rect = this.getOccupiedAreaBBox();
        PdfCanvas canvas = drawContext.getCanvas();
        canvas.moveTo(rect.getLeft(), rect.getBottom());

        canvas.curveTo(rect.getLeft()+100,rect.getBottom()+5,
        rect.getLeft()+150,rect.getBottom()-2,rect.getLeft()+200,rect.getBottom()-5);
        canvas.stroke();
    }
}

if i do with single element text it works: enter image description here

How i can define where draw canvas if there are several text elements


Solution

  • The question is underspecified (see clarifying comment). Basically to avoid the overlap as on the screenshot:

    bad result

    You can customize the renderer for the Paragraph, not for the Text:

    private static class WaveUnderlinedParagraphRenderer extends ParagraphRenderer {
        public WaveUnderlinedParagraphRenderer(Paragraph paragraph) {
            super(paragraph);
        }
    
        @Override
        public void draw(DrawContext drawContext) {
            super.draw(drawContext);
            Rectangle rect = this.getOccupiedAreaBBox();
            PdfCanvas canvas = drawContext.getCanvas();
            canvas.moveTo(rect.getLeft(), rect.getBottom());
    
            canvas.curveTo(rect.getLeft() + 100, rect.getBottom() + 5,
                    rect.getLeft() + 150, rect.getBottom() - 2, rect.getLeft() + 200, rect.getBottom() - 5);
            canvas.stroke();
        }
    
        @Override
        public IRenderer getNextRenderer() {
            return new WaveUnderlinedParagraphRenderer((Paragraph) modelElement);
        }
    }
    
    Document doc = new Document(pdfDocument);
    String s = "This text is underlined with a dashed line";
    Paragraph paragraph = new Paragraph();
    Text text;
    for (int i = 0; i <s.length() ; i++) {
        text = new Text(String.valueOf(s.charAt(i)));
        paragraph.add(text);
    }
    
    paragraph.setNextRenderer(new WaveUnderlinedParagraphRenderer(paragraph));
    doc.add(paragraph);
    doc.close();
    

    And get the following result:

    result