From de614153b5d80b578b51cb10a6f70f6ed73a52e8 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 26 Dec 2020 21:20:55 +0100 Subject: [PATCH] Add default_fonts feature: Turn off if you use your own fonts --- egui/Cargo.toml | 12 ++++-- egui/src/paint/font.rs | 22 +++++++---- egui/src/paint/fonts.rs | 88 ++++++++++++++++++++++++----------------- 3 files changed, 75 insertions(+), 47 deletions(-) diff --git a/egui/Cargo.toml b/egui/Cargo.toml index 2cad4e01..e3a9a12d 100644 --- a/egui/Cargo.toml +++ b/egui/Cargo.toml @@ -20,7 +20,7 @@ include = [ [dependencies] ahash = { version = "0.6", features = ["std"], default-features = false } -atomic_refcell = { version = "0.1", optional = true } # Used instead of parking_lot when you are always using Egui in a single thread. About as fast as parking_lot. +atomic_refcell = { version = "0.1", optional = true } # Used instead of parking_lot when you are always using Egui in a single thread. About as fast as parking_lot. Panics on multi-threaded use of egui::Context. parking_lot = { version = "0.11", optional = true } # Using parking_lot over std::sync::Mutex gives 50% speedups in some real-world scenarios rusttype = "0.9" serde = { version = "1", features = ["derive"], optional = true } @@ -30,8 +30,14 @@ serde_json = { version = "1", optional = true } criterion = { version = "0.3", default-features = false } [features] -default = ["atomic_refcell"] # Using the same egui::Context from multiple threads will result in a panic. -multi_threaded = ["parking_lot"] # Only needed if you plan to use the same egui::Context from multiple threads. +default = ["atomic_refcell", "default_fonts"] + +# If set, egui will use `include_bytes!` to bundle some fonts. +# If you plan on specifying your own fonts you may disable this feature. +default_fonts = [] + +# Only needed if you plan to use the same egui::Context from multiple threads. +multi_threaded = ["parking_lot"] [[bench]] name = "benchmark" diff --git a/egui/src/paint/font.rs b/egui/src/paint/font.rs index c4b88389..c4313819 100644 --- a/egui/src/paint/font.rs +++ b/egui/src/paint/font.rs @@ -142,6 +142,7 @@ type FontIndex = usize; // TODO: rename? /// Wrapper over multiple `FontImpl` (e.g. a primary + fallbacks for emojis) +#[derive(Default)] pub struct Font { fonts: Vec>, replacement_glyph: (FontIndex, GlyphInfo), @@ -152,7 +153,10 @@ pub struct Font { impl Font { pub fn new(fonts: Vec>) -> Self { - assert!(!fonts.is_empty()); + if fonts.is_empty() { + return Default::default(); + } + let pixels_per_point = fonts[0].pixels_per_point(); let row_height = fonts[0].row_height(); @@ -239,15 +243,17 @@ impl Font { let mut last_glyph_id = None; for c in text.chars() { - let (font_index, glyph_info) = self.glyph_info(c); - let font_impl = &self.fonts[font_index]; + if !self.fonts.is_empty() { + let (font_index, glyph_info) = self.glyph_info(c); + let font_impl = &self.fonts[font_index]; - if let Some(last_glyph_id) = last_glyph_id { - cursor_x_in_points += font_impl.pair_kerning(last_glyph_id, glyph_info.id) + if let Some(last_glyph_id) = last_glyph_id { + cursor_x_in_points += font_impl.pair_kerning(last_glyph_id, glyph_info.id) + } + cursor_x_in_points += glyph_info.advance_width; + cursor_x_in_points = self.round_to_pixel(cursor_x_in_points); + last_glyph_id = Some(glyph_info.id); } - cursor_x_in_points += glyph_info.advance_width; - cursor_x_in_points = self.round_to_pixel(cursor_x_in_points); - last_glyph_id = Some(glyph_info.id); x_offsets.push(cursor_x_in_points); } diff --git a/egui/src/paint/fonts.rs b/egui/src/paint/fonts.rs index 4d952500..180bc9ef 100644 --- a/egui/src/paint/fonts.rs +++ b/egui/src/paint/fonts.rs @@ -89,48 +89,60 @@ impl Default for FontDefinitions { impl FontDefinitions { /// Default values for the fonts pub fn default_with_pixels_per_point(pixels_per_point: f32) -> Self { + #[allow(unused)] let mut font_data: BTreeMap = BTreeMap::new(); - // Use size 13 for this. NOTHING ELSE: - font_data.insert( - "ProggyClean".to_owned(), - std::borrow::Cow::Borrowed(include_bytes!("../../fonts/ProggyClean.ttf")), - ); - font_data.insert( - "Ubuntu-Light".to_owned(), - std::borrow::Cow::Borrowed(include_bytes!("../../fonts/Ubuntu-Light.ttf")), - ); - - // Few, but good looking. Use as first priority: - font_data.insert( - "NotoEmoji-Regular".to_owned(), - std::borrow::Cow::Borrowed(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")), - ); - // Bigger emojis, and more. : - font_data.insert( - "emoji-icon-font".to_owned(), - std::borrow::Cow::Borrowed(include_bytes!("../../fonts/emoji-icon-font.ttf")), - ); - - // TODO: figure out a way to make the WASM smaller despite including fonts. Zip them? let mut fonts_for_family = BTreeMap::new(); - fonts_for_family.insert( - FontFamily::Monospace, - vec![ + + #[cfg(feature = "default_fonts")] + { + // TODO: figure out a way to make the WASM smaller despite including fonts. Zip them? + + // Use size 13 for this. NOTHING ELSE: + font_data.insert( "ProggyClean".to_owned(), - "Ubuntu-Light".to_owned(), // fallback for √ etc - "NotoEmoji-Regular".to_owned(), - "emoji-icon-font".to_owned(), - ], - ); - fonts_for_family.insert( - FontFamily::VariableWidth, - vec![ + std::borrow::Cow::Borrowed(include_bytes!("../../fonts/ProggyClean.ttf")), + ); + font_data.insert( "Ubuntu-Light".to_owned(), + std::borrow::Cow::Borrowed(include_bytes!("../../fonts/Ubuntu-Light.ttf")), + ); + + // Some good looking emojis. Use as first priority: + font_data.insert( "NotoEmoji-Regular".to_owned(), + std::borrow::Cow::Borrowed(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")), + ); + // Bigger emojis, and more. : + font_data.insert( "emoji-icon-font".to_owned(), - ], - ); + std::borrow::Cow::Borrowed(include_bytes!("../../fonts/emoji-icon-font.ttf")), + ); + + fonts_for_family.insert( + FontFamily::Monospace, + vec![ + "ProggyClean".to_owned(), + "Ubuntu-Light".to_owned(), // fallback for √ etc + "NotoEmoji-Regular".to_owned(), + "emoji-icon-font".to_owned(), + ], + ); + fonts_for_family.insert( + FontFamily::VariableWidth, + vec![ + "Ubuntu-Light".to_owned(), + "NotoEmoji-Regular".to_owned(), + "emoji-icon-font".to_owned(), + ], + ); + } + + #[cfg(not(feature = "default_fonts"))] + { + fonts_for_family.insert(FontFamily::Monospace, vec![]); + fonts_for_family.insert(FontFamily::VariableWidth, vec![]); + } let mut family_and_size = BTreeMap::new(); family_and_size.insert(TextStyle::Small, (FontFamily::VariableWidth, 10.0)); @@ -196,7 +208,11 @@ impl Fonts { .family_and_size .iter() .map(|(&text_style, &(family, scale_in_points))| { - let fonts: Vec> = self.definitions.fonts_for_family[&family] + let fonts = &self.definitions.fonts_for_family.get(&family); + let fonts = fonts.unwrap_or_else(|| { + panic!("FontFamily::{:?} is not bound to any fonts", family) + }); + let fonts: Vec> = fonts .iter() .map(|font_name| font_impl_cache.font_impl(font_name, scale_in_points)) .collect();