diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 5b66a28a7a1..2e10206586f 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -9,7 +9,7 @@ use epaint::{ pos2, stats::PaintStats, tessellator, - text::{FontInsert, Fonts}, + text::{FontInsert, FontPriority, Fonts}, util::OrderedFloat, vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2, Rect, TessellationOptions, TextureAtlas, TextureId, Vec2, @@ -586,19 +586,18 @@ impl ContextImpl { let fonts = self.memory.add_fonts.drain(..); for font in fonts { self.fonts.clear(); - self.font_definitions - .font_data - .insert(font.name.clone(), font.data); - let fam = self - .font_definitions - .families - .entry(font.family) - .or_default(); - if font.family_append { - fam.push(font.name); - } else { - fam.insert(0, font.name); - }; + for family in font.families { + let fam = self + .font_definitions + .families + .entry(family.family) + .or_default(); + match family.priority { + FontPriority::Highest => fam.insert(0, font.name.clone()), + FontPriority::Lowest => fam.push(font.name.clone()), + } + } + self.font_definitions.font_data.insert(font.name, font.data); } #[cfg(feature = "log")] diff --git a/crates/epaint/src/text/fonts.rs b/crates/epaint/src/text/fonts.rs index 491845c46e3..685bdf9b8a8 100644 --- a/crates/epaint/src/text/fonts.rs +++ b/crates/epaint/src/text/fonts.rs @@ -262,22 +262,38 @@ pub struct FontInsert { /// A `.ttf` or `.otf` file and a font face index. pub data: FontData, - /// Sets the font family + /// Sets the font family and priority + pub families: Vec, +} + +#[derive(Debug, Clone)] +pub struct InsertFontFamily { + /// Font family pub family: FontFamily, - /// If append is true & there are multiple fonts for that font family the font will be added as fallback. - /// This decides if the font is added to the front or the back. - /// So the first font is the primary, and then comes a list of fallbacks in order of priority. - pub family_append: bool, + /// Fallback or Primary font + pub priority: FontPriority, +} + +#[derive(Debug, Clone)] +pub enum FontPriority { + /// Prefer this font before all existing ones. + /// + /// If a desired glyph exists in this font, it will be used. + Highest, + + /// Use this font as a fallback, after all existing ones. + /// + /// This font will only be used if the glyph is not found in any of the previously installed fonts. + Lowest, } impl FontInsert { - pub fn new(name: &str, data: FontData, family: FontFamily, primary_font: bool) -> Self { + pub fn new(name: &str, data: FontData, families: Vec) -> Self { Self { name: name.to_owned(), data, - family, - family_append: !primary_font, + families, } } } diff --git a/crates/epaint/src/text/mod.rs b/crates/epaint/src/text/mod.rs index 50ab17e2923..3cb0e98cbc5 100644 --- a/crates/epaint/src/text/mod.rs +++ b/crates/epaint/src/text/mod.rs @@ -11,7 +11,8 @@ pub const TAB_SIZE: usize = 4; pub use { fonts::{ - FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontTweak, Fonts, FontsImpl, + FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontPriority, FontTweak, Fonts, + FontsImpl, InsertFontFamily, }, text_layout::layout, text_layout_types::*, diff --git a/examples/custom_font/src/main.rs b/examples/custom_font/src/main.rs index 5afa72905af..8b54d950e17 100644 --- a/examples/custom_font/src/main.rs +++ b/examples/custom_font/src/main.rs @@ -1,7 +1,10 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release #![allow(rustdoc::missing_crate_level_docs)] // it's an example -use eframe::egui; +use eframe::{ + egui, + epaint::text::{FontInsert, InsertFontFamily}, +}; fn main() -> eframe::Result { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). @@ -16,7 +19,26 @@ fn main() -> eframe::Result { ) } -fn setup_custom_fonts(ctx: &egui::Context) { +fn add_font(ctx: &egui::Context) { + ctx.add_font(FontInsert::new( + "my_font", + egui::FontData::from_static(include_bytes!( + "../../../crates/epaint_default_fonts/fonts/Hack-Regular.ttf" + )), + vec![ + InsertFontFamily { + family: egui::FontFamily::Proportional, + priority: egui::epaint::text::FontPriority::Highest, + }, + InsertFontFamily { + family: egui::FontFamily::Monospace, + priority: egui::epaint::text::FontPriority::Lowest, + }, + ], + )); +} + +fn replace_fonts(ctx: &egui::Context) { // Start with the default fonts (we will be adding to them rather than replacing them). let mut fonts = egui::FontDefinitions::default(); @@ -53,7 +75,8 @@ struct MyApp { impl MyApp { fn new(cc: &eframe::CreationContext<'_>) -> Self { - setup_custom_fonts(&cc.egui_ctx); + replace_fonts(&cc.egui_ctx); + add_font(&cc.egui_ctx); Self { text: "Edit this text field if you want".to_owned(), }