Created
August 28, 2025 03:25
-
-
Save Omustardo/609f8d09880921f9a70d745e8f3c968e to your computer and use it in GitHub Desktop.
egui font fallback demo
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
| impl MyApp { | |
| /// Called once before the first frame. | |
| pub fn new(cc: &eframe::CreationContext<'_>) -> Self { | |
| // This is where you can customize the look and feel of egui using | |
| // `cc.egui_ctx.set_visuals` and `cc.egui_ctx.set_fonts`. | |
| Self::setup_fonts(cc); | |
| // Load previous app state (if any). | |
| // Note that you must enable the `persistence` feature for this to work. | |
| if let Some(storage) = cc.storage { | |
| return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); | |
| } | |
| MyApp::default() | |
| } | |
| // Initialize egui fonts. Note that this function globally modifies egui settings. | |
| fn setup_fonts(cc: &eframe::CreationContext<'_>) { | |
| // egui comes with some default fonts if the `default_fonts` feature is enabled in Cargo.toml, | |
| // but they don't cover all characters so we need to add fallbacks fonts. | |
| // See https://docs.rs/egui/latest/egui/struct.FontDefinitions.html | |
| // I'm embedding font data within the binary. I got the fonts with: | |
| // curl -L -o assets/fonts/JetBrainsMono-Regular.ttf https://github.com/JetBrains/JetBrainsMono/raw/master/fonts/ttf/JetBrainsMono-Regular.ttf | |
| // curl -L -o assets/fonts/JetBrainsMono-Bold.ttf https://github.com/JetBrains/JetBrainsMono/raw/master/fonts/ttf/JetBrainsMono-Bold.ttf | |
| // curl -L -o assets/fonts/JetBrainsMono-Italic.ttf https://github.com/JetBrains/JetBrainsMono/raw/master/fonts/ttf/JetBrainsMono-Italic.ttf | |
| // curl -L -o assets/fonts/JetBrainsMono-BoldItalic.ttf https://github.com/JetBrains/JetBrainsMono/raw/master/fonts/ttf/JetBrainsMono-BoldItalic.ttf | |
| // Note that JetBrainsMono is licenced: https://www.jetbrains.com/lp/mono/ https://github.com/JetBrains/JetBrainsMono/blob/master/OFL.txt | |
| // but it's it's free to use as long as I don't sell or distribute the font itself directly. | |
| // | |
| // Another option would be to use the default system font: https://github.com/emilk/egui/discussions/1344 | |
| // but I don't like that approach since it depends on something outside of this binary. | |
| const MY_FONTS: [(&str, &[u8]); 4] = [ | |
| ( | |
| "JetBrainsMono-Regular", | |
| include_bytes!("../assets/fonts/JetBrainsMono-Regular.ttf"), | |
| ), | |
| ( | |
| "JetBrainsMono-Bold", | |
| include_bytes!("../assets/fonts/JetBrainsMono-Bold.ttf"), | |
| ), | |
| ( | |
| "JetBrainsMono-Italic", | |
| include_bytes!("../assets/fonts/JetBrainsMono-Italic.ttf"), | |
| ), | |
| ( | |
| "JetBrainsMono-BoldItalic", | |
| include_bytes!("../assets/fonts/JetBrainsMono-BoldItalic.ttf"), | |
| ), | |
| ]; | |
| // Load all font variants. Note that this loads an entirely separate font for each bold/italic/etc | |
| // but then uses them in the same way. This is unintuitive but intentional. egui chooses | |
| // the first font to match a request, so if you try to print italicized text it'll iterate | |
| // through loaded fonts until it finds the `italic` ttf. So as long as we push these | |
| // into egui's font registry, they will be used when appropriate. | |
| let mut my_fonts: HashMap<&str, Arc<FontData>> = HashMap::new(); | |
| for (name, data) in MY_FONTS.iter() { | |
| my_fonts.insert(name, Arc::from(FontData::from_static(data))); | |
| } | |
| // Get the built-in defaults, and add my fonts to it. This maps the name to the data. | |
| let mut fonts = egui::FontDefinitions::default(); | |
| for (name, data) in my_fonts.into_iter() { | |
| fonts.font_data.insert(name.to_string(), data); | |
| } | |
| // To use my fonts as fallback to existing fonts, the names need to be added to a PATH-like list. | |
| // egui will iterate over the list until it finds a font that is valid. | |
| for (name, _) in MY_FONTS.iter() { | |
| fonts | |
| .families | |
| .get_mut(&egui::FontFamily::Monospace) | |
| .unwrap() | |
| .push(name.to_string()); | |
| // WARNING: JetBrainsMono is a monospace font so it shouldn't really be used here, but | |
| // it's safe enough since the default fonts should handle almost everything. | |
| // This fallback should only be used for things like emojis. | |
| fonts | |
| .families | |
| .get_mut(&egui::FontFamily::Proportional) | |
| .unwrap() | |
| .push(name.to_string()); | |
| } | |
| // Apply the font configuration | |
| cc.egui_ctx.set_fonts(fonts); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment