I am having some issues with some specific emoji rendering using the Noto Color Emoji library: https://github.com/googlefonts/noto-emoji. For the most part this has been working great, but I have a specific set of characters that won't seem to render correctly. In the attached document I have two different emoji: one the renders and one that does not. The weird thing is that if you remove the failing emoji, you still get an error about bitmap missing for glyph 1. When you leave the failed emoji in, you get two separate bitmap missing errors. Using Chrome's dev tools it is claiming this emoji is a valid part of the font but who knows if that is really accurate.
Forum âē Bugs
Emoji rendering: Bitmap missing for glyph 1
What's even weirder is that I can see in some cases the failed emoji actually does render. I have had difficulty narrowing down why though. Here is a non-simplified case where it did actually render.
Wait, I figured out why I could reproduce on some renders and not others. I give the customer a choice between rendering to jpg or pdf and jpg renders work for both emoji but pdf renders only work for the one type. Here is an example of the jpg render with the same html file and it works fine.
Short version: đŠ (SMALL AIRPLANE) is missing a variation selector to make it use emoji presentation. Adding this will achieve the desired result:
Long version:
Each character that can be shown as emoji has an "Emoji_Presentation" property that indicates whether it defaults to text presentation (black and white) or emoji presentation (colour). â (AIRPLANE) and đŠ (SMALL AIRPLANE) both default to text presentation. The default can be changed with variation selectors. There is one for requesting text presentation (U+FE0E) and one for emoji presentation (U+FE0F).
In "output.html" AIRPLANE is followed by the emoji variation selector but SMALL AIRPLANE is not. Prince tries to find a text presentation version of SMALL AIRPLANE in Noto Color Emoji, but this font only contains colour bitmaps and no regular glyphs, which causes it to output the warning "bitmap missing for glyph".
To complicate matters some applications that render text favour showing emoji regardless of the default presentation for the character. Browsers tend to do this. We don't do this in Prince because we didn't want the output from existing workflows making use of text presentation emoji to suddenly change in Prince 14.
Lastly the behaviour between raster output (E.g. JPEG) versus PDF was different in this case due to different code paths taken to render emoji for raster output vs. into PDF.
<tspan style="font-size: 32px; font-family: emoji;">
Works - âī¸ Fails - đŠ️
</tspan>
Long version:
Each character that can be shown as emoji has an "Emoji_Presentation" property that indicates whether it defaults to text presentation (black and white) or emoji presentation (colour). â (AIRPLANE) and đŠ (SMALL AIRPLANE) both default to text presentation. The default can be changed with variation selectors. There is one for requesting text presentation (U+FE0E) and one for emoji presentation (U+FE0F).
In "output.html" AIRPLANE is followed by the emoji variation selector but SMALL AIRPLANE is not. Prince tries to find a text presentation version of SMALL AIRPLANE in Noto Color Emoji, but this font only contains colour bitmaps and no regular glyphs, which causes it to output the warning "bitmap missing for glyph".
To complicate matters some applications that render text favour showing emoji regardless of the default presentation for the character. Browsers tend to do this. We don't do this in Prince because we didn't want the output from existing workflows making use of text presentation emoji to suddenly change in Prince 14.
Lastly the behaviour between raster output (E.g. JPEG) versus PDF was different in this case due to different code paths taken to render emoji for raster output vs. into PDF.
Hmm this is an odd one. I even tested Window 10's default emoji selector, and selecting the small airplane emoji inserts with the two characters and missing that third character. But I can see what you mean that for example in the js console it shows the emoji as the text representation until you add that third character. Man emoji sucks sometimes. I guess I will need to figure out how to detect these broken emoji and auto fix them.
Two follow up questions
:1) Do you guys have any plans to make both code paths the same? Obviously I would prefer if it defaulted to color emoji in both, but at the very least being consistent would be better than the current situation.
2) Is there a reason why the emoji is not rendering at all instead of rendering as text presentation in PDF mode?
Two follow up questions
:1) Do you guys have any plans to make both code paths the same? Obviously I would prefer if it defaulted to color emoji in both, but at the very least being consistent would be better than the current situation.
2) Is there a reason why the emoji is not rendering at all instead of rendering as text presentation in PDF mode?
1) Do you guys have any plans to make both code paths the same? Obviously I would prefer if it defaulted to color emoji in both, but at the very least being consistent would be better than the current situation.
It's on the roadmap but unfortunately I can't really give a time frame of when it will be implemented.
2) Is there a reason why the emoji is not rendering at all instead of rendering as text presentation in PDF mode?
So I've dug into this and it's due to few things combined, and a current limitation:
- Explicitly setting the font-family to NotoColorEmoji
- Omitting the emoji variation selector
- NotoColorEmoji containing an emoji presentation glyph for SMALL AIRPLANE but lacking regular outlines (B&W glyphs)
In this case Prince maps đŠī¸ to NotoColorEmoji during the glyph mapping phase. Late in the process when the PDF is being generated it needs a B&W glyph from NotoColorEmoji and gets nothing, since it contains neither a `glyf` or `CFF` table. At this point it emits the warning and writes an empty glyph.
Ideally in this case it would fall back on the bitmap glyph, even though text presentation was requested â we don't do this yet. It's been added to the roadmap as well.
Sweet thank you for the detailed responses! I think I am set to work around this on my end due to you guys giving so much info about how it works.
Just a quick note to mention that in the latest builds we've made some changes to handle this situation better. The example in the top post now produces this output: