最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Rendering Emojis using PDFBox Does Not Work - Stack Overflow

programmeradmin2浏览0评论

I attempted to render emojis using the emoji-supported font Noto Color Emoji (+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.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();
        }
    }
}

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.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();
        }
    }
}
Share Improve this question asked Jan 20 at 19:30 Sudeepa NadeeshanSudeepa Nadeeshan 1822 silver badges13 bronze badges 5
  • 2 I answered that one on the mailing list. Did you forgot to subscribe or were you disappointed by the answer? – Tilman Hausherr Commented Jan 20 at 20:27
  • Oh, my apologies! It was the first one—I missed subscribing as I was still getting familiar with how the mailing list works. Thanks for the quick response; I just saw it now. – Sudeepa Nadeeshan Commented Jan 20 at 21:07
  • Either delete the question or respond to this comment so I'll add my answer here. – Tilman Hausherr Commented Jan 21 at 9:24
  • Yes, please, could you add the answer here? I think it will be useful to others. Also, I'm still not sure how to reply to your answer, which I can see on the archive page: lists.apache.org/thread/2x1r2jhz6qsx9t5xsdssr82c2vjhw433. Is it possible to use the 'In-Reply-To' headers in the email body to do that? (e.g., In-Reply-To: 2x1r2jhz6qsx9t5xsdssr82c2vjhw433). I haven't tried this yet, as I was afraid I might flood the mailing list. – Sudeepa Nadeeshan Commented Jan 21 at 11:45
  • 1 Done... the reply in the mailing list should be directed to users (at) pdfbox.apache.org. Some mail readers may have troubles. In Thunderbird you should click "reply to list". – Tilman Hausherr Commented Jan 21 at 12:04
Add a comment  | 

1 Answer 1

Reset to default 1

tl;dr: use a different font and simpler javacode.

I tried your code but failed initially... emojis usually don't work. 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 = "
发布评论

评论列表(0)

  1. 暂无评论