PDF Java: Characters changed in stamp

Binary_View_of_input_and_output_strings.png (121.3 KB)
input.pdf (85.8 KB)
output.pdf (283.5 KB)

Aspose Team,

We use the Aspose PDF java package to add stamps to each page of PDF files and found out that some characters are changed in the label of the stamp.

Following is the sample code that reproduces the problem and attached are the input and output pdf files.

The input string for the label is as follows. See the attached picture for the binary view.
S3CbwktvZdqTPAj8f紲吹蹮ヨ糖㒟񆔒ᡌ!kohyfXibc

and the output string in the label of the output pdf file is as follows (copied from the output pdf file that is opened with Adobe Acrobat Reader DC). See the attached picture for the binary view.
S3CbwktvZdqTPAj8f紲吹􀀀ヨ􀀀􀀀􀀀􀀀!kohyfXibc

Note that some characters in the output string are different from that in the input string (check with the binary views).

The operating system is Ubuntu 18.04. Java version is 1.8. Aspose PDF java package is 21.6.

import com.aspose.pdf.*;
import com.aspose.pdf.facades.FormattedText;
import com.aspose.pdf.facades.PdfFileEditor;
import java.util.ArrayList;
import java.util.List;

public class TestStamp {
public static void main(String[] args) {
try {
System.out.println(“Start”);

        String inPath = "/home/ubuntu/testdirs/testdir_stamp_chars/input.pdf";
        String outPath = "/home/ubuntu/testdirs/testdir_stamp_chars/output.pdf";
        String ucStr = "S3CbwktvZdqTPAj8f紲吹蹮ヨ糖㒟񆔒ᡌ!kohyfXibc";
        String llStr = "1";
        String lrStr = "YAX.PC.00000198";
        String fontFamily = "DejaVu Sans";
        Font font = FontRepository.findFont(fontFamily);;
        int fontSize = 10;

        // Stamps
        List<TextStamp> stampsToAdd = new ArrayList<>();
        // Uper Center
        stampsToAdd.add(convertToStamp(ucStr, HorizontalAlignment.Center, VerticalAlignment.Top, font, fontSize));
        // Lower Left
        stampsToAdd.add(convertToStamp(llStr, HorizontalAlignment.Left, VerticalAlignment.Bottom, font, fontSize));
        // Lower Right
        stampsToAdd.add(convertToStamp(lrStr, HorizontalAlignment.Right, VerticalAlignment.Bottom, font, fontSize));

        // Resize the page before adding the stamps
        int leftMargin = 0;
        int rightMargin = 0;
        int topMargin = 10;
        int bottomMargin = 10;
        PdfFileEditor.ContentsResizeParameters parameters = new PdfFileEditor.ContentsResizeParameters(
                PdfFileEditor.ContentsResizeValue.units(leftMargin),
                null,
                PdfFileEditor.ContentsResizeValue.units(rightMargin),
                PdfFileEditor.ContentsResizeValue.units(topMargin),
                null,
                PdfFileEditor.ContentsResizeValue.units(bottomMargin)
        );

        PdfFileEditor editor = new PdfFileEditor();
        Document document = new Document(inPath);
        editor.resizeContentsWithNormalization(document, parameters);

        for (Page page : document.getPages()) {
            for(TextStamp stamp : stampsToAdd){
                page.addStamp(stamp);
            }
        }
        document.save(outPath);

        System.out.println("Done");
    }
    catch(Exception ex) {
        ex.printStackTrace();
    }
}

private static TextStamp convertToStamp(String text, int horizontalAlignment, int verticalAlignment,
                                        Font font, int fontSize) {
    FormattedText formattedText = new FormattedText();
    formattedText.addNewLineText(text);
    TextStamp textStamp = new TextStamp(formattedText);
    textStamp.setWordWrap(true);
    textStamp.setHorizontalAlignment(horizontalAlignment);
    textStamp.setVerticalAlignment(verticalAlignment);
    textStamp.getTextState().setFont(font);
    textStamp.getTextState().setFontSize(fontSize);
    textStamp.setTopMargin(0);
    return textStamp;
}

}

@xyang

We have replicated the similar issue in our environment and have logged it as PDFJAVA-40629 in our issue tracking system. We will further look into its details and keep you posted with the status of its correction. Please be patient and spare us some time.

We are sorry for the inconvenience.

@asad.ali is there any update on this?

@aweech

We are afraid that the earlier logged ticket could not get resolved due to other pending issues in the queue. We will surely inform you as soon as we have definite updates about issue fix. Please be patient and spare us some time.

We are sorry for the inconvenience.

@asad.ali was the earlier ticket able to be resolved?

@aweech

Regretfully, the ticket could not get resolved yet. Your concerns have been recorded under the ticket and will surely be considered. As soon as we have some definite updates about ticket resolution, we will update you. We apologize for your inconvenience.

@aweech @xyang

Note that the “DejaVu Sans” font does not support 9 characters from the ucStr string.

System.out.println(font.getFontName());
for (char c : ucStr.toCharArray()) {
    System.out.println(c + ":" + font.doesFontContainAllCharacters(String.valueOf(c)));
}

The Aspose.PDF API ignores the explicitly specified “DejaVu Sans” font and substitutes it with the “MS Gothic” font instead. “MS Gothic” font does not support only six characters from the ucStr string.
We tried to find fonts that would support all font characters at the same time, but we didn’t find any that could support all characters of a string. The most suitable fonts are “Noto Serif SC” and “Noto Sans SC”.
As a workaround, you can split this text stamp into several and, for each, specify a font that supports the required character set.

String llStr = "1";
String lrStr = "YAX.PC.00000198";
FontRepository.addLocalFontPath(dataDir + "fonts");
Document document = new Document(inPath);
int fontSize = 10;
double height = document.getPages().get_Item(1).getRect().getHeight();

String ucStr1 = "S3CbwktvZdqTPAj8f紲吹蹮ヨ";
String ucStr2 = "糖㒟񆔒ᡌ";
String ucStr3 = "!kohyfXibc";

// Stamps
List<TextStamp> stampsToAdd = new ArrayList<>();

Font fontNotoSansSC = FontRepository.findFont("Noto Serif SC");
System.out.println(fontNotoSansSC.getFontName() + " contain characters " + ucStr1 + ": " + fontNotoSansSC.doesFontContainAllCharacters(ucStr1));
System.out.println(fontNotoSansSC.getFontName() + " contain characters " + ucStr3 + ": " + fontNotoSansSC.doesFontContainAllCharacters(ucStr3));

Font fontThatSupportChars2 = FontRepository.findFont("DejaVu Sans");
System.out.println(fontNotoSansSC.getFontName() + " contain characters " + ucStr2 + ": " + fontNotoSansSC.doesFontContainAllCharacters(ucStr2));
System.out.println(fontThatSupportChars2.getFontName() + " contain characters " + ucStr2 + ": " + fontThatSupportChars2.doesFontContainAllCharacters(ucStr2));

TextStamp textStamp1 = convertToStamp(ucStr1, HorizontalAlignment.None, VerticalAlignment.None, fontNotoSansSC, fontSize);
textStamp1.setXIndent(185);
textStamp1.setYIndent(height - fontSize - 2);
stampsToAdd.add(textStamp1);

TextStamp textStamp2 = convertToStamp(ucStr2, HorizontalAlignment.None, VerticalAlignment.None, fontThatSupportChars2, fontSize);
textStamp2.setXIndent(323);
textStamp2.setYIndent(height - fontSize - 2);
stampsToAdd.add(textStamp2);

TextStamp textStamp3 = convertToStamp(ucStr3, HorizontalAlignment.None, VerticalAlignment.None, fontNotoSansSC, fontSize);
textStamp3.setXIndent(365);
textStamp3.setYIndent(height - fontSize - 2);
stampsToAdd.add(textStamp3);

Font font = FontRepository.findFont("DejaVu Sans");

// Lower Left
stampsToAdd.add(convertToStamp(llStr, HorizontalAlignment.Left, VerticalAlignment.Bottom, font, fontSize));
// Lower Right
stampsToAdd.add(convertToStamp(lrStr, HorizontalAlignment.Right, VerticalAlignment.Bottom, font, fontSize));

// Resize the page before adding the stamps
int leftMargin = 0;
int rightMargin = 0;
int topMargin = 10;
int bottomMargin = 10;
PdfFileEditor.ContentsResizeParameters parameters = new PdfFileEditor.ContentsResizeParameters(
    PdfFileEditor.ContentsResizeValue.units(leftMargin),
    null,
    PdfFileEditor.ContentsResizeValue.units(rightMargin),
    PdfFileEditor.ContentsResizeValue.units(topMargin),
    null,
    PdfFileEditor.ContentsResizeValue.units(bottomMargin)
);

PdfFileEditor editor = new PdfFileEditor();
editor.resizeContentsWithNormalization(document, parameters);

for (Page page : document.getPages()) {
    for (TextStamp stamp : stampsToAdd) {
        page.addStamp(stamp);
    }
}

document.save(outPath);
System.out.println("Done");

Also, note that there are no fonts that contain absolutely all the symbols. But if you can find a universal font for all current symbols, then it is possible not to separate the string.
output_24.2.pdf (9.3 MB)