javaitextwatermark

Watermark RTL text appears incorrect


I am using Itext 5 and I am trying to add non removable watermark text as follows, but the issue is that the RTL text appears incorrectly:

ByteArrayOutputStream baos = new ByteArrayOutputStream();

PdfReader reader = new PdfReader(byteArray);
PdfStamper stamper = new PdfStamper(reader, baos);

BaseFont baseFont = BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.WINANSI, false);
String watermarkText = "مسودة";

int numberOfPages = reader.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++) {
    Rectangle pageSize = reader.getPageSizeWithRotation(i);

    // get handle for existing page content
    PdfImportedPage pageContent = stamper.getImportedPage(reader, i);
    // store that content as form XObject
    stamper.getWriter().addToBody(pageContent.getFormXObject(stamper.getWriter().getCompressionLevel()), pageContent.getIndirectReference());
    pageContent.setCopied();
    // reset page content
    reader.getPageN(i).put(PdfName.CONTENTS, null);

    // create pattern with former page content
    PdfPatternPainter bodyPainter = stamper.getOverContent(i).createPattern(pageSize.getWidth(),
            pageSize.getHeight());
    bodyPainter.addTemplate(pageContent, 0, 0);

    // add watermark to pattern
    PdfGState state = new PdfGState();
    state.setFillOpacity(0.3f);
    bodyPainter.saveState();
    bodyPainter.setGState(state);
    for (float x = 70f; x < pageSize.getWidth(); x += 100) {
        for (float y = 90; y < pageSize.getHeight(); y += 100) {
            bodyPainter.beginText();
            bodyPainter.setTextRenderingMode(PdfPatternPainter.TEXT_RENDER_MODE_FILL);
            bodyPainter.setFontAndSize(baseFont, 13);
            bodyPainter.showTextAlignedKerned(Element.ALIGN_MIDDLE, watermarkText, x, y, 45f);
            bodyPainter.endText();
        }
    }
    bodyPainter.restoreState();

    // create new page content
    PdfContentByte canvas = stamper.getUnderContent(i);
    // add pseudo-content
    canvas.beginText();
    canvas.setFontAndSize(baseFont, 13);
    canvas.showTextAlignedKerned(Element.ALIGN_MIDDLE, "        ", 0, 0, 45f);
    canvas.endText();
    // fill with pattern holding former page content
    canvas.setColorFill(new PatternColor(bodyPainter));
    canvas.rectangle(pageSize.getLeft(), pageSize.getBottom(), pageSize.getWidth(),
            pageSize.getHeight());
    canvas.fill();
}

stamper.close();
reader.close();
byteArray = baos.toByteArray();

The watermark appears incorrectly as follows:

enter image description here

How can I fix this issue?


Solution

  • I was able to fix it as follows:

    for (float x = xAxis; x < pageSize.getWidth(); x += height + 100) {
                        for (float y = yAxis; y < pageSize.getHeight(); y += height + 100) {
    
                            if (isRTL) {
                                ColumnText.showTextAligned(bodyPainter, Element.ALIGN_CENTER, rtlPhrase, x, y, 45f,
                                        PdfWriter.RUN_DIRECTION_RTL, ColumnText.DIGITS_AN2EN);
                            } else {
                                bodyPainter.beginText();
                                bodyPainter.setTextRenderingMode(PdfPatternPainter.TEXT_RENDER_MODE_FILL);
                                bodyPainter.setFontAndSize(baseFont, 13);
                                bodyPainter.showTextAlignedKerned(Element.ALIGN_RIGHT, watermarkText, x, y, 45f);
                                bodyPainter.endText();
                            }
    
                        }
                    }