Hi,
tl;dr: use a different font and simpler javacode.
I tried your code but failed initially... emojis usually don't work.
What I tried first was to simplify this by calling showText immediately.
This brought a GSUB exception (?!) so I disabled GSUB for now, and I got
a PDF with nothing. Then I tried this:
String text = new String(Character.toChars(0x1f600));
because \uD83D\uDE00 is really unicode U+1f600. However this didn't work
either. A look at the font with DTL OTMaster 3.7 light shows that the
code in the PDF (2386) is correct because that one does have unicode
1f600, however no glyph.
Same when doing
text = "😀 😉";
I then tried a different font that I found while researching, "Symbola",
and I got this:
It works both with using the emojis directly or using your original line
with "\uD83D\uDE00 \uD83D\uDE09", and the GSUB modification has been
removed.
However the long java segment where you're breaking this into codepoints
doesn't work, probably because font.hasGlyph() doesn't work the way you
expect. The javadoc mentions that the "code" parameter isn't unicode but
that's what you're passing. It's better to catch the IllegalArgument
exception like done in the EmbeddedMultipleFonts example.
Oh, if you were expecting this to appear in color like in your browser:
that isn't supported. That's not part of the original truetype
specification.
Tilman
On 18.01.2025 10:19, Sudeepa Nadeeshan wrote:
Hi Devs,
I attempted to render emojis using the emoji-supported font Noto Color
Emoji<https://fonts.google.com/noto/specimen/Noto+Color+Emoji> with the PDFBox
3.0.3 Java library. However, the font.hasGlyph(codePoint) method consistently returns
false for all codepoint availability checks. Despite this, the emojis in question are
clearly supported by the specified Google font. I have included the code below. Could
someone kindly guide me in identifying the cause of this issue?
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import java.io.File;
import java.io.IOException;
public class EmojiPdfExample {
public static void main(String[] args) {
try (PDDocument doc = new PDDocument()) {
File fontFile = new File("NotoColorEmoji-Regular.ttf");
var font = PDType0Font.load(doc, fontFile);
// Add a page
PDPage page = new PDPage();
doc.addPage(page);
try (PDPageContentStream cs = new PDPageContentStream(doc, page)) {
cs.beginText();
cs.setFont(font, 20);
cs.newLineAtOffset(50, 700);
// Emoji string
String text = "\uD83D\uDE00 \uD83D\uDE09";
for (int i = 0; i < text.length(); ) {
int codePoint = Character.codePointAt(text, i);
i += Character.charCount(codePoint);
String glyph;
try {
glyph = new String(Character.toChars(codePoint));
} catch (IllegalArgumentException e) {
System.err.println("Invalid code point: U+" +
Integer.toHexString(codePoint));
continue; // Skip invalid code points
}
try {
if (font.hasGlyph(codePoint)) {
cs.showText(glyph);
} else {
// Handle unsupported glyphs
System.out.println("Unsupported glyph," + glyph);
}
} catch (IOException e) {
System.err.println("IOException while showing glyph:
U+" + Integer.toHexString(codePoint));
}
}
cs.endText();
}
doc.save("emojis.pdf");
System.out.println("PDF created: emojis.pdf");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks,
Sudeepa.