Skip to content

Try to improve support for .notdef glyphs through FontTweak#4644

Open
Warpten wants to merge 1 commit intoemilk:mainfrom
Warpten:master
Open

Try to improve support for .notdef glyphs through FontTweak#4644
Warpten wants to merge 1 commit intoemilk:mainfrom
Warpten:master

Conversation

@Warpten
Copy link
Copy Markdown

@Warpten Warpten commented Jun 9, 2024

The idea consists of adding fallbacks to the FontTweak structure, which then get used in egui's Font (actually a wrapper over multiple FontImpl) to identify fallback characters. We look through each wrapped FontImpl, stopping in the first fallback character we found, defaulting to the empty glyph if none is found.

Example output when replacing the user font by MaterialSymbolsSharp in the egui custom font example:
image

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading("\u{E834} egui using custom fonts");
            ui.text_edit_multiline(&mut self.text);
        });
    }
}

Note that as it is (mostly due to my very limited understanding of fonts in general), this isn't enough to load .notdef properly, even with a user-definied fallback character set. I suspect this however has to do with ttf_parser seemingly not actually loading .notdef.

/// Can we display this glyph?
pub fn has_glyph(&mut self, c: char) -> bool {
self.glyph_info(c) != self.replacement_glyph // TODO(emilk): this is a false negative if the user asks about the replacement character itself 🤦‍♂️
self.glyph_info_no_cache_or_fallback(c).is_some()
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seemed a nice "bonus" to-do solving, slightly unrelated to the issue at hand; I'm suspecting there's a reason you chose not to do this in the first place?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, glyph_info_no_cache_or_fallback doesn't use the cache, so it is marginally slower.

@emilk
Copy link
Copy Markdown
Owner

emilk commented Jun 18, 2024

When would you want to have a different replacement char?

@Warpten
Copy link
Copy Markdown
Author

Warpten commented Jun 20, 2024

Whenever the default replacement character of a font is neither the empty square nor that font has a question mark, which is the case for Material Symbols Sharp:

image

Comment on lines +369 to +380
// For each font, find the first available fallback character
slf.replacement_glyph = slf
.fonts
.iter()
.enumerate()
.find_map(|(font_index, font_impl)| {
font_impl.fallbacks.iter().find_map(|chr| {
font_impl
.glyph_info(*chr)
.map(|glyph_info| (font_index, glyph_info))
})
})
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not call glyph_info_no_cache_or_fallback here like before?

@valadaptive valadaptive mentioned this pull request Mar 29, 2025
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't load Material Design font because of missing missing glyph

2 participants