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.

Reply via email to