Browse Source

refactor fonts: put TextStyle in Galley instead of in Shape::Text

pull/275/head
Emil Ernerfeldt 4 years ago
parent
commit
d4e5133da2
  1. 7
      egui/src/containers/collapsing_header.rs
  2. 7
      egui/src/containers/combo_box.rs
  3. 19
      egui/src/painter.rs
  4. 8
      egui/src/widgets/button.rs
  5. 5
      egui/src/widgets/label.rs
  6. 1
      egui/src/widgets/plot.rs
  7. 3
      egui/src/widgets/selected_label.rs
  8. 5
      egui/src/widgets/text_edit.rs
  9. 1
      egui_demo_lib/benches/benchmark.rs
  10. 9
      epaint/src/shape.rs
  11. 6
      epaint/src/tessellator.rs
  12. 33
      epaint/src/text/font.rs
  13. 2
      epaint/src/text/fonts.rs
  14. 5
      epaint/src/text/galley.rs

7
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,

7
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() {

19
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,
});

8
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
}
}

5
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);
}

1
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,
});

3
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
}
}

5
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);

1
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,

9
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,
}

6
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;

33
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<Arc<FontImpl>>,
replacement_glyph: (FontIndex, GlyphInfo),
pixels_per_point: f32,
@ -163,15 +166,23 @@ pub struct Font {
}
impl Font {
pub fn new(fonts: Vec<Arc<FontImpl>>) -> Self {
pub fn new(text_style: TextStyle, fonts: Vec<Arc<FontImpl>>) -> 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
}

2
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();

5
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,

Loading…
Cancel
Save