diff --git a/egui/src/containers/collapsing_header.rs b/egui/src/containers/collapsing_header.rs index de95c289b..b5b681693 100644 --- a/egui/src/containers/collapsing_header.rs +++ b/egui/src/containers/collapsing_header.rs @@ -262,12 +262,7 @@ impl CollapsingHeader { paint_icon(ui, openness, &icon_response); } - ui.painter().galley( - text_pos, - galley, - label.text_style_or_default(ui.style()), - text_color, - ); + ui.painter().galley(text_pos, galley, text_color); Prepared { id, diff --git a/egui/src/containers/combo_box.rs b/egui/src/containers/combo_box.rs index d25a80120..4622a1194 100644 --- a/egui/src/containers/combo_box.rs +++ b/egui/src/containers/combo_box.rs @@ -179,8 +179,9 @@ fn combo_box( let full_minimum_width = ui.spacing().slider_width; let icon_size = Vec2::splat(ui.spacing().icon_width); - let text_style = TextStyle::Button; - let galley = ui.fonts().layout_no_wrap(text_style, selected.into()); + let galley = ui + .fonts() + .layout_no_wrap(TextStyle::Button, selected.into()); let width = galley.size.x + ui.spacing().item_spacing.x + icon_size.x; let width = width.at_least(full_minimum_width); @@ -197,7 +198,7 @@ fn combo_box( let text_rect = Align2::LEFT_CENTER.align_size_within_rect(galley.size, rect); ui.painter() - .galley(text_rect.min, galley, text_style, visuals.text_color()); + .galley(text_rect.min, galley, visuals.text_color()); }); if button_response.clicked() { diff --git a/egui/src/painter.rs b/egui/src/painter.rs index 48fcf5067..f4b85c4dd 100644 --- a/egui/src/painter.rs +++ b/egui/src/painter.rs @@ -172,10 +172,11 @@ impl Painter { } pub fn error(&self, pos: Pos2, text: impl std::fmt::Display) -> Rect { - let text_style = TextStyle::Monospace; - let galley = - self.fonts() - .layout_multiline(text_style, format!("🔥 {}", text), f32::INFINITY); + let galley = self.fonts().layout_multiline( + TextStyle::Monospace, + format!("🔥 {}", text), + f32::INFINITY, + ); let rect = Align2::LEFT_TOP.anchor_rect(Rect::from_min_size(pos, galley.size)); let frame_rect = rect.expand(2.0); self.add(Shape::Rect { @@ -184,7 +185,7 @@ impl Painter { fill: Color32::from_black_alpha(240), stroke: Stroke::new(1.0, Color32::RED), }); - self.galley(rect.min, galley, text_style, Color32::RED); + self.galley(rect.min, galley, Color32::RED); frame_rect } } @@ -296,27 +297,25 @@ impl Painter { .fonts() .layout_multiline(text_style, text.into(), f32::INFINITY); let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size)); - self.galley(rect.min, galley, text_style, text_color); + self.galley(rect.min, galley, text_color); rect } /// Paint text that has already been layed out in a `Galley`. - pub fn galley(&self, pos: Pos2, galley: Galley, text_style: TextStyle, color: Color32) { - self.galley_with_italics(pos, galley, text_style, color, false) + pub fn galley(&self, pos: Pos2, galley: Galley, color: Color32) { + self.galley_with_italics(pos, galley, color, false) } pub fn galley_with_italics( &self, pos: Pos2, galley: Galley, - text_style: TextStyle, color: Color32, fake_italics: bool, ) { self.add(Shape::Text { pos, galley, - text_style, color, fake_italics, }); diff --git a/egui/src/widgets/button.rs b/egui/src/widgets/button.rs index f3339f5b4..24a1743ee 100644 --- a/egui/src/widgets/button.rs +++ b/egui/src/widgets/button.rs @@ -141,8 +141,7 @@ impl Button { let text_color = text_color .or(ui.visuals().override_text_color) .unwrap_or_else(|| visuals.text_color()); - ui.painter() - .galley(text_cursor, galley, text_style, text_color); + ui.painter().galley(text_cursor, galley, text_color); } response @@ -264,8 +263,7 @@ impl<'a> Widget for Checkbox<'a> { let text_color = text_color .or(ui.visuals().override_text_color) .unwrap_or_else(|| visuals.text_color()); - ui.painter() - .galley(text_cursor, galley, text_style, text_color); + ui.painter().galley(text_cursor, galley, text_color); response } } @@ -373,7 +371,7 @@ impl Widget for RadioButton { let text_color = text_color .or(ui.visuals().override_text_color) .unwrap_or_else(|| visuals.text_color()); - painter.galley(text_cursor, galley, text_style, text_color); + painter.galley(text_cursor, galley, text_color); response } } diff --git a/egui/src/widgets/label.rs b/egui/src/widgets/label.rs index 4f6137f2b..e3f0f1b9a 100644 --- a/egui/src/widgets/label.rs +++ b/egui/src/widgets/label.rs @@ -163,7 +163,7 @@ impl Label { pub fn font_height(&self, fonts: &epaint::text::Fonts, style: &Style) -> f32 { let text_style = self.text_style_or_default(style); - fonts[text_style].row_height() + fonts.row_height(text_style) } // TODO: this should return a LabelLayout which has a paint method. @@ -234,9 +234,8 @@ impl Label { } } - let text_style = self.text_style_or_default(ui.style()); ui.painter() - .galley_with_italics(pos, galley, text_style, text_color, italics); + .galley_with_italics(pos, galley, text_color, italics); ui.painter().extend(lines); } diff --git a/egui/src/widgets/plot.rs b/egui/src/widgets/plot.rs index 1539ea504..74ef9da38 100644 --- a/egui/src/widgets/plot.rs +++ b/egui/src/widgets/plot.rs @@ -661,7 +661,6 @@ impl Prepared { shapes.push(Shape::Text { pos: text_pos, galley, - text_style, color: ui.visuals().text_color(), fake_italics: false, }); diff --git a/egui/src/widgets/selected_label.rs b/egui/src/widgets/selected_label.rs index e14acf504..8d64eae9e 100644 --- a/egui/src/widgets/selected_label.rs +++ b/egui/src/widgets/selected_label.rs @@ -78,8 +78,7 @@ impl Widget for SelectableLabel { .visuals .override_text_color .unwrap_or_else(|| visuals.text_color()); - ui.painter() - .galley(text_cursor, galley, text_style, text_color); + ui.painter().galley(text_cursor, galley, text_color); response } } diff --git a/egui/src/widgets/text_edit.rs b/egui/src/widgets/text_edit.rs index c8bea4359..919550f07 100644 --- a/egui/src/widgets/text_edit.rs +++ b/egui/src/widgets/text_edit.rs @@ -513,8 +513,7 @@ impl<'t> TextEdit<'t> { .or(ui.visuals().override_text_color) // .unwrap_or_else(|| ui.style().interact(&response).text_color()); // too bright .unwrap_or_else(|| ui.visuals().widgets.inactive.text_color()); - ui.painter() - .galley(response.rect.min, galley, text_style, text_color); + ui.painter().galley(response.rect.min, galley, text_color); if text.is_empty() && !hint_text.is_empty() { let galley = if multiline { @@ -525,7 +524,7 @@ impl<'t> TextEdit<'t> { }; let hint_text_color = ui.visuals().weak_text_color(); ui.painter() - .galley(response.rect.min, galley, text_style, hint_text_color); + .galley(response.rect.min, galley, hint_text_color); } ui.memory().text_edit.insert(id, state); diff --git a/egui_demo_lib/benches/benchmark.rs b/egui_demo_lib/benches/benchmark.rs index 7a1042913..7ae032132 100644 --- a/egui_demo_lib/benches/benchmark.rs +++ b/egui_demo_lib/benches/benchmark.rs @@ -79,7 +79,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { &fonts, egui::Pos2::ZERO, &galley, - text_style, egui::Color32::WHITE, fake_italics, &mut mesh, diff --git a/epaint/src/shape.rs b/epaint/src/shape.rs index 303f05a37..357064e26 100644 --- a/epaint/src/shape.rs +++ b/epaint/src/shape.rs @@ -40,13 +40,13 @@ pub enum Shape { stroke: Stroke, }, Text { - /// Top left corner of the first character. + /// Top left corner of the first character.. pos: Pos2, - /// The layed out text + /// The layed out text. galley: Galley, - text_style: TextStyle, // TODO: Font? + /// Text color (foreground). color: Color32, - /// If true, tilt the letters for an ugly italics effect + /// If true, tilt the letters for a hacky italics effect. fake_italics: bool, }, Mesh(Mesh), @@ -137,7 +137,6 @@ impl Shape { Self::Text { pos: rect.min, galley, - text_style, color, fake_italics: false, } diff --git a/epaint/src/tessellator.rs b/epaint/src/tessellator.rs index 147e175ce..b1c6a337f 100644 --- a/epaint/src/tessellator.rs +++ b/epaint/src/tessellator.rs @@ -566,7 +566,6 @@ impl Tessellator { Shape::Text { pos, galley, - text_style, color, fake_italics, } => { @@ -581,7 +580,7 @@ impl Tessellator { out, ); } - self.tessellate_text(fonts, pos, &galley, text_style, color, fake_italics, out); + self.tessellate_text(fonts, pos, &galley, color, fake_italics, out); } } } @@ -622,7 +621,6 @@ impl Tessellator { fonts: &Fonts, pos: Pos2, galley: &super::Galley, - text_style: super::TextStyle, color: Color32, fake_italics: bool, out: &mut Mesh, @@ -641,7 +639,7 @@ impl Tessellator { let clip_rect = self.clip_rect.expand(2.0); // Some fudge to handle letters that are slightly larger than expected. - let font = &fonts[text_style]; + let font = &fonts[galley.text_style]; let mut chars = galley.text.chars(); for line in &galley.rows { let line_min_y = pos.y + line.y_min; diff --git a/epaint/src/text/font.rs b/epaint/src/text/font.rs index 60d79b2ca..fd1f2b55e 100644 --- a/epaint/src/text/font.rs +++ b/epaint/src/text/font.rs @@ -7,7 +7,10 @@ use { use crate::{ mutex::{Mutex, RwLock}, - text::galley::{Galley, Row}, + text::{ + galley::{Galley, Row}, + TextStyle, + }, TextureAtlas, }; use emath::{vec2, Vec2}; @@ -153,8 +156,8 @@ type FontIndex = usize; // TODO: rename? /// Wrapper over multiple `FontImpl` (e.g. a primary + fallbacks for emojis) -#[derive(Default)] pub struct Font { + text_style: TextStyle, fonts: Vec>, replacement_glyph: (FontIndex, GlyphInfo), pixels_per_point: f32, @@ -163,15 +166,23 @@ pub struct Font { } impl Font { - pub fn new(fonts: Vec>) -> Self { + pub fn new(text_style: TextStyle, fonts: Vec>) -> Self { if fonts.is_empty() { - return Default::default(); + return Self { + text_style, + fonts, + replacement_glyph: Default::default(), + pixels_per_point: 0.0, + row_height: 0.0, + glyph_info_cache: Default::default(), + }; } let pixels_per_point = fonts[0].pixels_per_point(); let row_height = fonts[0].row_height(); let mut slf = Self { + text_style, fonts, replacement_glyph: Default::default(), pixels_per_point, @@ -204,6 +215,11 @@ impl Font { slf } + #[inline(always)] + pub fn text_style(&self) -> TextStyle { + self.text_style + } + #[inline] pub fn round_to_pixel(&self, point: f32) -> f32 { (point * self.pixels_per_point).round() / self.pixels_per_point @@ -301,6 +317,7 @@ impl Font { let width = row.max_x(); let size = vec2(width, self.row_height()); let galley = Galley { + text_style: self.text_style, text, rows: vec![row], size, @@ -391,7 +408,13 @@ impl Font { } let size = vec2(widest_row, rows.last().unwrap().y_max); - let galley = Galley { text, rows, size }; + let text_style = self.text_style; + let galley = Galley { + text_style, + text, + rows, + size, + }; galley.sanity_check(); galley } diff --git a/epaint/src/text/fonts.rs b/epaint/src/text/fonts.rs index a13642b8a..d7b5a5a2c 100644 --- a/epaint/src/text/fonts.rs +++ b/epaint/src/text/fonts.rs @@ -221,7 +221,7 @@ impl Fonts { .map(|font_name| font_impl_cache.font_impl(font_name, scale_in_points)) .collect(); - (text_style, Font::new(fonts)) + (text_style, Font::new(text_style, fonts)) }) .collect(); diff --git a/epaint/src/text/galley.rs b/epaint/src/text/galley.rs index 14f0fd3a0..7e72b678c 100644 --- a/epaint/src/text/galley.rs +++ b/epaint/src/text/galley.rs @@ -23,8 +23,11 @@ use super::cursor::*; use emath::{pos2, NumExt, Rect, Vec2}; /// A collection of text locked into place. -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct Galley { + /// The [`crate::TextStyle`] (font) used. + pub text_style: crate::TextStyle, + /// The full text, including any an all `\n`. pub text: String,