From 320c91faf7c0c9b27e3380c26a68c52598c06c9a Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Mon, 22 Apr 2019 20:09:08 -0700 Subject: [PATCH] bam, variable font size --- docs/articles/rust/article.md | 1 - editor/src/main.rs | 2 +- editor/src/plugins/sim/show_score.rs | 14 +++++- ezgui/src/drawing.rs | 2 +- ezgui/src/text.rs | 71 ++++++++++++++-------------- ezgui/src/widgets/menu.rs | 9 +++- ezgui/src/widgets/top_menu.rs | 4 +- 7 files changed, 58 insertions(+), 45 deletions(-) diff --git a/docs/articles/rust/article.md b/docs/articles/rust/article.md index 1ffe09e3fe..a0f7088e60 100644 --- a/docs/articles/rust/article.md +++ b/docs/articles/rust/article.md @@ -62,7 +62,6 @@ screenshot tool after each render. Sometimes the quick hack works perfectly. I would consider cleaning up ezgui and publishing it as a generally usable crate, except it's pretty crippled: -- the text rendering is very primitive; font size is fixed - basic widgets like a scrolling text box, list with radio buttons, and tables are missing - The imperative style makes it quite easy for different parts of the UI to diff --git a/editor/src/main.rs b/editor/src/main.rs index e08ecb9d33..e162b901b7 100644 --- a/editor/src/main.rs +++ b/editor/src/main.rs @@ -199,7 +199,7 @@ impl GUI for GameState { } } -const SPEED: Speed = Speed::const_meters_per_second(50.0); +const SPEED: Speed = Speed::const_meters_per_second(20.0); struct Screensaver { line: Line, diff --git a/editor/src/plugins/sim/show_score.rs b/editor/src/plugins/sim/show_score.rs index d034a094f0..039a0b4df3 100644 --- a/editor/src/plugins/sim/show_score.rs +++ b/editor/src/plugins/sim/show_score.rs @@ -56,7 +56,12 @@ fn panel(ctx: &mut PluginCtx) -> ShowScoreState { } fn summarize(txt: &mut Text, summary: ScoreSummary) { - txt.add_styled_line("Walking".to_string(), None, Some(Color::RED.alpha(0.8)), None); + txt.add_styled_line( + "Walking".to_string(), + None, + Some(Color::RED.alpha(0.8)), + None, + ); txt.add_line(format!( " {}/{} trips done", (summary.total_walking_trips - summary.pending_walking_trips), @@ -64,7 +69,12 @@ fn summarize(txt: &mut Text, summary: ScoreSummary) { )); txt.add_line(format!(" {} total", summary.total_walking_trip_time)); - txt.add_styled_line("Driving".to_string(), None, Some(Color::BLUE.alpha(0.8)), None); + txt.add_styled_line( + "Driving".to_string(), + None, + Some(Color::BLUE.alpha(0.8)), + None, + ); txt.add_line(format!( " {}/{} trips done", (summary.total_driving_trips - summary.pending_driving_trips), diff --git a/ezgui/src/drawing.rs b/ezgui/src/drawing.rs index 4e2d4183b1..8d9532c716 100644 --- a/ezgui/src/drawing.rs +++ b/ezgui/src/drawing.rs @@ -155,7 +155,7 @@ impl<'a> GfxCtx<'a> { }; let y1 = match vert { VerticalAlignment::Top => 0.0, - VerticalAlignment::BelowTopMenu => self.canvas.line_height(text::FONT_SIZE), + VerticalAlignment::BelowTopMenu => self.canvas.top_menu_height(), VerticalAlignment::Center => (self.canvas.window_height - height) / 2.0, VerticalAlignment::Bottom => self.canvas.window_height - height, }; diff --git a/ezgui/src/text.rs b/ezgui/src/text.rs index 75c6220ae9..05ae2fc843 100644 --- a/ezgui/src/text.rs +++ b/ezgui/src/text.rs @@ -120,33 +120,31 @@ impl Text { } pub(crate) fn dims(&self, canvas: &Canvas) -> (f64, f64) { - // Always use the max height, since other stuff like menus assume a fixed height. - let height = (self.lines.len() as f64) * canvas.line_height(FONT_SIZE); + let mut max_width = 0; + let mut height = 0.0; - let mut glyphs = canvas.glyphs.borrow_mut(); - let width = f64::from( - self.lines - .iter() - .map(|(_, l)| { - let full_line = l.iter().fold(String::new(), |mut so_far, span| { - so_far.push_str(&span.text); - so_far - }); - // Empty lines or whitespace-only lines effectively have 0 width. - glyphs - .pixel_bounds(Section { - text: &full_line, - scale: Scale::uniform(FONT_SIZE as f32), - ..Section::default() - }) - .map(|rect| rect.width()) - .unwrap_or(0) + for (_, line) in &self.lines { + let mut full_line = String::new(); + let mut max_size = 0; + for span in line { + full_line.push_str(&span.text); + max_size = max_size.max(span.size); + } + // Empty lines or whitespace-only lines effectively have 0 width. + let width = canvas + .glyphs + .borrow_mut() + .pixel_bounds(Section { + text: &full_line, + scale: Scale::uniform(max_size as f32), + ..Section::default() }) - .max() - .unwrap(), - ); - - (width, height) + .map(|rect| rect.width()) + .unwrap_or(0); + max_width = max_width.max(width); + height += canvas.line_height(max_size); + } + (max_width as f64, height) } } @@ -173,32 +171,33 @@ pub fn draw_text_bubble( let mut y = top_left.y; for (line_color, line) in &txt.lines { + let mut max_size = 0; let section = VariedSection { screen_position: (top_left.x as f32, y as f32), text: line .into_iter() - .map(|span| SectionText { - text: &span.text, - color: span.fg_color.0, - scale: Scale::uniform(FONT_SIZE as f32), - ..SectionText::default() + .map(|span| { + max_size = max_size.max(span.size); + SectionText { + text: &span.text, + color: span.fg_color.0, + scale: Scale::uniform(span.size as f32), + ..SectionText::default() + } }) .collect(), ..VariedSection::default() }; + let height = g.canvas.line_height(max_size); if let Some(c) = line_color { g.draw_polygon( *c, - &Polygon::rectangle_topleft( - Pt2D::new(top_left.x, y), - total_width, - g.canvas.line_height(FONT_SIZE), - ), + &Polygon::rectangle_topleft(Pt2D::new(top_left.x, y), total_width, height), ); } - y += g.canvas.line_height(FONT_SIZE); + y += height; g.canvas.glyphs.borrow_mut().queue(section); } diff --git a/ezgui/src/widgets/menu.rs b/ezgui/src/widgets/menu.rs index 152dba58a3..c4eaf39513 100644 --- a/ezgui/src/widgets/menu.rs +++ b/ezgui/src/widgets/menu.rs @@ -66,7 +66,7 @@ impl Menu { } else { total_width }; - ScreenPt::new(canvas.window_width - w, canvas.line_height(text::FONT_SIZE)) + ScreenPt::new(canvas.window_width - w, canvas.top_menu_height()) } }; @@ -221,7 +221,12 @@ impl Menu { None, ); } else { - txt.add_styled_line(choice.to_string(), Some(text::INACTIVE_CHOICE_COLOR), bg, None); + txt.add_styled_line( + choice.to_string(), + Some(text::INACTIVE_CHOICE_COLOR), + bg, + None, + ); } } } diff --git a/ezgui/src/widgets/top_menu.rs b/ezgui/src/widgets/top_menu.rs index d0e5565277..4543576486 100644 --- a/ezgui/src/widgets/top_menu.rs +++ b/ezgui/src/widgets/top_menu.rs @@ -126,7 +126,7 @@ impl TopMenu { x1: 0.0, y1: 0.0, x2: g.canvas.window_width, - y2: g.canvas.line_height(text::FONT_SIZE), + y2: g.canvas.top_menu_height(), }); g.fork_screenspace(); @@ -135,7 +135,7 @@ impl TopMenu { &Polygon::rectangle_topleft( Pt2D::new(0.0, 0.0), g.canvas.window_width, - g.canvas.line_height(text::FONT_SIZE), + g.canvas.top_menu_height(), ), ); g.unfork();