From c43a29a3fcfccce70236fa7c69f7b5822a29d212 Mon Sep 17 00:00:00 2001 From: Phillip Tennen Date: Fri, 5 Apr 2024 09:22:10 +0100 Subject: [PATCH] [Rust - libgui] Allow calculating text layout size on a TextView --- rust_programs/libgui/src/text_view.rs | 29 ++++++++++++++++++++++++ rust_programs/ttf_renderer/src/render.rs | 8 ++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/rust_programs/libgui/src/text_view.rs b/rust_programs/libgui/src/text_view.rs index 2ae2e368..dba87cb3 100644 --- a/rust_programs/libgui/src/text_view.rs +++ b/rust_programs/libgui/src/text_view.rs @@ -19,6 +19,7 @@ use alloc::{ }; use axle_rt::AmcMessage; use core::fmt::Formatter; +use core::ops::Add; use core::ptr; use file_manager_messages::{ReadFile, ReadFileResponse, FILE_SERVER_SERVICE_NAME}; use libgui_derive::{Drawable, NestedLayerSlice, UIElement}; @@ -180,6 +181,34 @@ impl TextView { cursor_pos } + /// Note that this will respect the need to split onto newlines due to the size of the parent slice. + pub fn rendered_string_size( + s: &str, + font: &Font, + font_size: Size, + container_size: Size, + text_origin: Point, + ) -> Size { + // Pretend we're doing layout and keep track of the area we cross + let mut layout_size = Size::new(0, font.scaled_line_height(font_size)); + let mut cursor_pos = text_origin; + for ch in s.chars() { + let next_cursor_pos = Self::next_cursor_pos_for_char( + cursor_pos, + ch, + font, + font_size, + container_size, + ); + layout_size = layout_size + Size::new( + next_cursor_pos.x - cursor_pos.x, + next_cursor_pos.y - cursor_pos.y, + ); + cursor_pos = next_cursor_pos; + } + layout_size + } + pub fn cursor_pos(&self) -> CursorPos { *self.cursor_pos.borrow() } diff --git a/rust_programs/ttf_renderer/src/render.rs b/rust_programs/ttf_renderer/src/render.rs index f625a855..77f78f58 100644 --- a/rust_programs/ttf_renderer/src/render.rs +++ b/rust_programs/ttf_renderer/src/render.rs @@ -30,6 +30,8 @@ pub fn render_char_onto( render_glyph_onto(glyph, font, onto, draw_loc, draw_color, font_size) } +/// Note that this implementation does not respect the need to split onto newlines due to the size +/// of the parent container. pub fn rendered_string_size(s: &str, font: &Font, font_size: Size) -> Size { let scale_factor = font_size.height as f64 / font.units_per_em as f64; let mut bounding_box = Size::new( @@ -68,9 +70,9 @@ pub fn render_antialiased_glyph_onto( let scaled_glyph_metrics = glyph.metrics().scale(scale_x, scale_y); let draw_loc = draw_loc + Point::new( - scaled_glyph_metrics.left_side_bearing, - scaled_glyph_metrics.top_side_bearing, - ); + scaled_glyph_metrics.left_side_bearing, + scaled_glyph_metrics.top_side_bearing, + ); let draw_box = Rect::from_parts(draw_loc, font_size); let mut dest_slice = onto.get_slice(draw_box);