Fontique: 3-tier font fallback - #689
Open
nicoburns wants to merge 1 commit into
Open
Conversation
nicoburns
commented
Jul 14, 2026
|
|
||
| #[derive(Clone, PartialEq, Eq, Hash)] | ||
| struct TextFallbackKey { | ||
| chars: SmallVec<[char; 8]>, |
Collaborator
Author
There was a problem hiding this comment.
Is 8 chars a sensible size here?
Comment on lines
+129
to
+130
| let chars: SmallVec<[char; 8]> = chars.into_iter().collect(); | ||
| if self.state.fallback_chars != chars { |
Collaborator
Author
There was a problem hiding this comment.
I think we can eliminate this allocation.
Signed-off-by: Nico Burns <nico@nicoburns.com>
nicoburns
force-pushed
the
rigorous-font-fallback
branch
from
July 14, 2026 12:52
927b895 to
05bdd60
Compare
Contributor
|
I don’t have time for a deep dive on this right now but, at a glance, I’m generally supportive of this with a couple caveats:
Big +1 to returning multiple fallback fonts from the system. We should probably also extend the script sample array to support multiple samples per script. This would help, for example, with selecting the -ExtB CJK fonts on Windows. |
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.
汉on Windows #644Generated with Fable High.
Motivation
Font fallback completely fails to find a matching font for some glyphs.
This is because font fallback was keyed on (script, locale), and resolved by asking the OS for a single font family which matches a per-script sample string. If that one font lacked the actual character (for example, CJK extensions, symbols, punctuation shared between scripts, scripts without samples) the Fontique gave up, even if there was actually an installed font that had the required glyph.
Changes made
Implement 3-tier fallback:
Tier A (all backends) - Ordered list of fonts per script (script, locale)
This is the existing fallback mechanism, but modified to work with a list of fonts rather a single font per (script, locale).
CTFontCopyDefaultCascadeListForLanguagesfont_sortwith coverage trimming instead offont_matchTier B (skipped on Android) - per-character system fallback
Query::set_fallback_chars()where Parley passes the specific characters we are falling back forCTFontCreateForString/IDWriteFontFallback::MapCharacters/FC_CHARSETmatch)Tier C (all backends) - exhaustive coverage scan
As a last resort, all families are checked for real cmap coverage (guaranteeing a glyph is found if any font has one)
exhaustive_fallback: boolruntime setting onCollectionThis PR also:
Verification Performed
The AI has run temporary integration tests (not included in this PR) on macOS and Ubuntu.
Tested in Blitz on macOS, and it definitely seems to work and find glyphs where
maindoesn't.