gpui: Fix emoji rendering in SVG preview#51569
gpui: Fix emoji rendering in SVG preview#51569smitbarmase merged 6 commits intozed-industries:mainfrom
Conversation
|
We require contributors to sign our Contributor License Agreement, and we don't have @alanpjohn on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
CC: @smitbarmase |
smitbarmase
left a comment
There was a problem hiding this comment.
Thanks, this is good improvement overall.
I have two concerns:
util::is_emoji_characterdoes not seem like the right predicate for font fallback. The added unit test also fails locally for me. I think it fails on1.
We should verify these too in addition to existing ones:
[
("©", false),
("©️", true),
("♥", false),
("♥️", true),
("1", false),
("1️⃣", true),
("🇺🇸", true),
("👨👩👧👧", true),
("a", false),
]Can you try with Emoji_Presentation for regex directly, which might be a bit conservative but will do that job in most cases? Let's keep it local to svg_renderer and not in util.
- One more thing I noticed:
fontdb::Database::queryreturns the best face from the first installed family infamilies. It does not keep walking the rest ofEMOJI_FONT_FAMILIESlooking for one that also supportsch.
That means if the first installed emoji family is already in fonts, or if it exists but does not have this glyph, we fall back to the default usvg resolver without ever trying the remaining emoji families.
I think this should iterate the families manually and check both:
!fonts.contains(&id)db.has_char(id, ch)
|
Is this what you had in mind
Fixed that
Reverted any changes I made to util and moved all logic into
I added the check to see if fonts contains ID already but I couldn't see a |
- enabled `raster_images` feature on `resvg` crate to allow resvg to render emoji fonts - Add a custom fallback selection function to make the fallback fonts for emojis more consistent. Signed-off-by: Alan P John <alanpjohn@outlook.com>
Accidentally removed in db622ed Signed-off-by: Alan P John <alanpjohn@outlook.com>
fallback - revert changes to util crate Signed-off-by: Alan P John <alanpjohn@outlook.com>
Signed-off-by: Alan P John <alanpjohn@outlook.com>
4f21838 to
c980730
Compare
smitbarmase
left a comment
There was a problem hiding this comment.
Thanks! I added a has_char check and test for that.
Also, I updated the emoji presentation test with an expected shortcoming for certain emojis like 1️⃣ and char.
But this is fine for now, and the current form is a huge improvement anyways. Thanks again for working on this.
Closes #50483
Findings
As reported in the original issue, emojis in SVG preview were not rendering consistently with the editor.
The SVG renderer uses
usvg/resvgfor parsing and rendering SVG files. The first problem was that emoji fonts were not rendering at all, which was fixed by enabling theraster_imagesonresvg.Beyond that it was observed that the default font fallback mechanism in
usvgsearches through the font database alphabetically without prioritizing emoji fonts. This caused emojis to sometimes render in non-emoji fonts that happened to contain glyph mappings for those characters.For example, on Linux systems with the default
uvsg::FontResolver::default_fallback_selector():FreeSerif(monochrome)Noto Color Emoji(full color)Log output showed the inconsistent behavior:
This created a jarring inconsistency where the same emoji character would render differently in:
Solution
If the specified font in SVG is available on the system, we should show that. If not, we should fallback to what editors show today for that emoji.
This PR implements emoji-aware font fallback that:
raster_imagesbuild feature to render emojis in SVG.\p{Emoji}regex pattern), consistent with how we check for emoji in the Editor as well.Font Family Selection
I avoided completely reusing/rebuilding the logic for emoji font selection used by the editor as
uvsginternally does quite a bit of the job and it felt like overcomplicating the solution. Instead using hard coded platform specific font family names.The hardcoded emoji font families are sourced from Zed's existing platform-specific text rendering systems:
Apple Color Emoji,.AppleColorEmojiUISource:
zed/crates/gpui_macos/src/text_system.rs
Lines 353 to 359 in db622ed
Noto Color Emoji,Emoji OneSource: https://github.com/zed-industries/zed/blob/db622edc8b26bd138c91027a02792a84c083acbf/crates/gpui_wgpu/src/cosmic_text_system.rs#L642-L646
Segoe UI Emoji,Segoe UI SymbolSource: Standard Windows emoji font stack
These match the fonts the editor uses for emoji rendering on each platform.
To break down further into the similarity and differences in the emoji font resolution:
Similarities:
Differences:
Testing
is_emoji_characterinutilcrateRelease Notes: