Repository navigation
feat: color emoji rendering (epaint + swash) with clean app chrome - #204
Merged
Merged
Conversation
egui/ab_glyph cannot rasterize color-emoji fonts (CBDT/CBLC, COLR/CPAL); system NotoColorEmoji.ttf loads but renders blank. The bundled monochrome NotoEmoji (Google Fonts VF release) has vector outlines and covers all modern emoji codepoints, including U+1F7E2 which epaint's built-in NotoEmoji-Regular lacks. Appended last to Proportional and Monospace chains so it only supplies glyphs nothing else covers. Verified by a new unit test that rasterizes the doc's emoji through the full chain and asserts real ink in the atlas (cmap hit + empty outline would fail).
Vendored epaint 0.33.3 (crates/epaint, [patch.crates-io]) with a minimal color-glyph patch: - UvRect gains a 'colored' flag - FontImpl keeps raw font bytes; when ab_glyph has no outline for a glyph (CBDT/CBLC, sbix, COLR fonts), allocate_glyph falls back to swash (Source::ColorBitmap/BestFit then ColorOutline) and writes RGBA pixels straight into the texture atlas - tessellate_glyphs uses a white vertex color for colored glyphs so the atlas RGB is not tinted by the text color App side: install_emoji_fonts() inserts the system NotoColorEmoji face AHEAD of epaint's built-in monochrome emoji faces (which would otherwise claim the glyph first), with the bundled monochrome NotoEmoji still last for codepoints the color font lacks. Verified by unit test: 🟢 green peak 207, 🔴 red peak 252 in the atlas.
NotoColorEmoji's cmap covers general symbols (▶ ⚠ ✔ → …), so after inserting it ahead of the text faces it hijacked nav/UI glyphs into blob-style emoji. FontData gains an emoji_only flag; when set, the face only supplies characters with Unicode Emoji_Presentation=Yes (compact range table in epaint). UI symbols fall through to the regular text faces exactly as before. Regression-tested: ▶▼⚠✔→✓ are NOT claimed; 🟢🔴⚪✅ still render in color (atlas peaks 207 green / 252 red).
The explorer/search/welcome/theme UI used emoji literals (📄 📂 📁 🔍 🌙) that predated color support and previously rendered as near-invisible monochrome glyphs. With color emoji live they turned into colorful blob icons, clashing with the clean UI design. Color emoji are for document content only; app chrome now uses plain text glyphs: ▪ file marker, expand arrows for folders (emoji removed), text buttons on the welcome screen, and ☀/☾ (text-presentation symbols) for the theme toggle.
Paint small document (page with folded corner) and folder (tab + body, lighter fill when expanded) icons with the egui painter — theme-aware, no font or emoji dependence. Replaces the ▪ text marker from the emoji cleanup; color emoji remain reserved for document content only.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
crates/epaint,[patch.crates-io]) with a ~90-line patch that rasterizes color-bitmap glyphs (CBDT/CBLC, sbix, COLR) via swash and stores RGBA pixels in the font atlas; colored glyphs tessellate with a white vertex color so text-color tinting doesn't destroy them.FontData.emoji_onlygate: the system NotoColorEmoji face only claims characters withEmoji_Presentation=Yes(compact range table), so UI symbols (▶ ⚠ ✔ → …) always come from regular text faces.Verification
Notes
emilk/egui; if merged upstream, the vendoring can be dropped.