Skip to content

Instantly share code, notes, and snippets.

@Omustardo
Created August 28, 2025 03:25
Show Gist options
  • Select an option

  • Save Omustardo/609f8d09880921f9a70d745e8f3c968e to your computer and use it in GitHub Desktop.

Select an option

Save Omustardo/609f8d09880921f9a70d745e8f3c968e to your computer and use it in GitHub Desktop.
egui font fallback demo
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