From 417bb3123af9b53ad30442d17641460f239718a4 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 26 Jan 2022 14:42:44 +0100 Subject: [PATCH] Fonts: only pre-render glyphs for fonts in the current egui styles --- egui/src/context.rs | 8 ++++++++ egui/src/memory.rs | 21 ++++++++++++++++++++- epaint/src/text/font.rs | 12 +++++++----- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/egui/src/context.rs b/egui/src/context.rs index d7701ead..c997ea7d 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -92,6 +92,14 @@ impl ContextImpl { }); fonts.begin_frame(pixels_per_point, max_texture_side); + + if self.memory.options.preload_font_glyphs { + // Preload the most common characters for the most common fonts. + // This is not very important to do, but may a few GPU operations. + for font_id in self.memory.options.style.text_styles.values() { + fonts.lock().fonts.font(font_id).preload_common_characters(); + } + } } } diff --git a/egui/src/memory.rs b/egui/src/memory.rs index 3e683a0b..4afdfeb8 100644 --- a/egui/src/memory.rs +++ b/egui/src/memory.rs @@ -93,7 +93,7 @@ pub struct Memory { // ---------------------------------------------------------------------------- /// Some global options that you can read and write. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", serde(default))] pub struct Options { @@ -108,6 +108,25 @@ pub struct Options { /// but is a signal to any backend that we want the [`crate::Output::events`] read out loud. /// Screen readers is an experimental feature of egui, and not supported on all platforms. pub screen_reader: bool, + + /// If true, the most common glyphs (ASCII) are pre-rendered to the texture atlas. + /// + /// Only the fonts in [`Style::text_styles`] will be pre-cached. + /// + /// This can lead to fewer texture operations, but may use up the texture atlas quicker + /// if you are changing [`Style::text_styles`], of have a lot of text styles. + pub preload_font_glyphs: bool, +} + +impl Default for Options { + fn default() -> Self { + Self { + style: Default::default(), + tessellation_options: Default::default(), + screen_reader: false, + preload_font_glyphs: true, + } + } } // ---------------------------------------------------------------------------- diff --git a/epaint/src/text/font.rs b/epaint/src/text/font.rs index aab77be1..1dca6030 100644 --- a/epaint/src/text/font.rs +++ b/epaint/src/text/font.rs @@ -242,16 +242,18 @@ impl Font { }); slf.replacement_glyph = replacement_glyph; + slf + } + + pub fn preload_common_characters(&mut self) { // Preload the printable ASCII characters [32, 126] (which excludes control codes): const FIRST_ASCII: usize = 32; // 32 == space const LAST_ASCII: usize = 126; for c in (FIRST_ASCII..=LAST_ASCII).map(|c| c as u8 as char) { - slf.glyph_info(c); + self.glyph_info(c); } - slf.glyph_info('°'); - slf.glyph_info(crate::text::PASSWORD_REPLACEMENT_CHAR); - - slf + self.glyph_info('°'); + self.glyph_info(crate::text::PASSWORD_REPLACEMENT_CHAR); } /// All supported characters