Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
sowbug opened this issue Nov 3, 2023 · 6 comments · May be fixed by #4644
Closed

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

sowbug opened this issue Nov 3, 2023 · 6 comments · May be fixed by #4644
Labels
bug Something is broken

Comments

@sowbug
Copy link
Contributor

sowbug commented Nov 3, 2023

  1. Try to load the font file called MaterialIcons-Regular.ttf located in this giant zip.
  2. Get error Failed to find replacement characters '◻' or '?' that originates from epaint-0.23.0/src/text/font.rs:364:17.

This is the code that I used to load the font file:

        let mut fonts = FontDefinitions::default();
        fonts.font_data.insert(
            Self::FONT_ICONS.to_owned(),
            FontData::from_static(include_bytes!(
                "../../../res/fonts/material-design-4.0/MaterialIcons-Regular.ttf"
            )),
        );

        fonts
            .families
            .entry(FontFamily::Name(Self::FONT_ICONS.into()))
            .or_default()
            .insert(0, Self::FONT_ICONS.to_owned());

and this is an excerpt from the egui/epaint font.rs file:

        const PRIMARY_REPLACEMENT_CHAR: char = '◻'; // white medium square
        const FALLBACK_REPLACEMENT_CHAR: char = '?'; // fallback for the fallback

        let replacement_glyph = slf
            .glyph_info_no_cache_or_fallback(PRIMARY_REPLACEMENT_CHAR)
            .or_else(|| slf.glyph_info_no_cache_or_fallback(FALLBACK_REPLACEMENT_CHAR))
            .unwrap_or_else(|| {
                panic!(
                    "Failed to find replacement characters {PRIMARY_REPLACEMENT_CHAR:?} or {FALLBACK_REPLACEMENT_CHAR:?}"
                )
            });

I think that this font family represents an edge case, because it's icons rather than letters/numbers/symbols, which means that nobody will ever use this font without knowing exactly which code points to use, which means that the concept of a replacement glyph shouldn't apply.

Clearly, it would have been better if the authors of this font file had included a glyph for the white medium square, but since they didn't, and I'd like to use the font file as-is, I don't have a good workaround at this point.

@sowbug
Copy link
Contributor Author

sowbug commented Nov 3, 2023

See discussion in google/material-design-icons#1600. It looks like glyph #0 is called .notdef and is supposed to serve as the glyph for missing glyphs. I'll see if I can update epaint to know about this.

@sowbug
Copy link
Contributor Author

sowbug commented Nov 3, 2023

I tried reading the code, and it looks like ab_glyph::GlyphId(0) has a special meaning in epaint to get substituted with the replacement character. I'm not sure whether ab_glyph::GlyphId is the same as a "glyph ID" in the TTF spec, so I don't know whether ab_glyph::GlyphId(0) means glyph ID 0. But it seems like if the code that calculated replacement_glyph were replaced with something that just asked ab_glyph for information about Glyph ID 0, then it would give the same functionality, but properly using .notdef rather than heuristically identifying the glyph to render when there is no glyph to render.

@sowbug
Copy link
Contributor Author

sowbug commented Nov 3, 2023

I've attached MaterialIcons-Regular.ttf.zip so you don't have to download that big zip to repro the bug.

@sowbug
Copy link
Contributor Author

sowbug commented Nov 6, 2023

Same behavior with MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf.

@oing9179
Copy link

oing9179 commented Dec 28, 2023

I stumbled on the same bug, well, not necessiarly a bug, anyway, here's my workaround:

  1. Watch a series of tutorial of FontForge on YouTube, take about half hour.
  2. Open your icon font with FontForge.
  3. Put whatever glyph/vector/thingy into position 0x3F which is where the ? character should be, as long as the slot isn't empty. For example the > is empty but ? isn't:
    screenshot
  4. From menu bar go to File -> Generate Fonts, then save it to somewhere.
  5. Use the newly generated font in your code.
  6. Profit.

@emilk
Copy link
Owner

emilk commented Jun 18, 2024

@emilk emilk closed this as completed Jun 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants