From 42a6a5ac9b5f88c2afcca0011cd009307d97ae1a Mon Sep 17 00:00:00 2001 From: grdddj Date: Tue, 19 Sep 2023 11:04:10 +0200 Subject: [PATCH] chore(core): adjust the chunkification logic to account for really mono font Also improving the positioning of prev/next page arrows when paginating. [no changelog] --- .../rust/src/ui/component/text/layout.rs | 63 +++++++++++-------- core/embed/rust/src/ui/model_tr/theme.rs | 4 +- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/core/embed/rust/src/ui/component/text/layout.rs b/core/embed/rust/src/ui/component/text/layout.rs index d713e9b0e3..70feef8eab 100644 --- a/core/embed/rust/src/ui/component/text/layout.rs +++ b/core/embed/rust/src/ui/component/text/layout.rs @@ -59,8 +59,6 @@ pub struct Chunks { pub chunk_size: usize, /// How big will be the space between chunks (in pixels). pub x_offset: i16, - /// Optional characters that are wider and should be accounted for - pub wider_chars: Option<&'static str>, } impl Chunks { @@ -68,20 +66,6 @@ impl Chunks { Chunks { chunk_size, x_offset, - wider_chars: None, - } - } - - pub const fn with_wider_chars(mut self, wider_chars: &'static str) -> Self { - self.wider_chars = Some(wider_chars); - self - } - - pub fn is_char_wider(self, ch: char) -> bool { - if let Some(wider_chars) = self.wider_chars { - wider_chars.contains(ch) - } else { - false } } } @@ -192,6 +176,14 @@ impl TextStyle { self.text_font.text_width(ELLIPSIS) } } + + fn prev_page_ellipsis_icon_width(&self) -> i16 { + if let Some((icon, _)) = self.prev_page_ellipsis_icon { + icon.toif.width() + } else { + 0 + } + } } impl TextLayout { @@ -262,9 +254,21 @@ impl TextLayout { PageBreaking::CutAndInsertEllipsisBoth ) && self.continues_from_prev_page { - sink.prev_page_ellipsis(*cursor, self); // Move the cursor to the right, always the same distance - cursor.x += self.style.prev_page_ellipsis_width(); + // Special case in chunkifying text - move the cursor so that we + // start with the second chunk. + if let Some(chunk_config) = self.style.chunks { + // Showing the arrow at the last chunk position + // Assuming mono-font, so all the letters have the same width + let letter_size = self.style.text_font.text_width("a"); + let icon_offset = self.style.prev_page_ellipsis_icon_width() + 2; + cursor.x += chunk_config.chunk_size as i16 * letter_size - icon_offset; + sink.prev_page_ellipsis(*cursor, self); + cursor.x += icon_offset + chunk_config.x_offset; + } else { + sink.prev_page_ellipsis(*cursor, self); + cursor.x += self.style.prev_page_ellipsis_width(); + } } while !remaining_text.is_empty() { @@ -285,6 +289,20 @@ impl TextLayout { self.style.chunks, ); + if let Some(chunk_config) = self.style.chunks { + // Last chunk on the page should not be rendered, put just ellipsis there + // Chunks is last when the next chunk would not fit on the page horizontally + let is_last_chunk = (2 * span.advance.x - chunk_config.x_offset) > remaining_width; + if is_last_line && is_last_chunk && remaining_text.len() > chunk_config.chunk_size { + // Making sure no text is rendered here, and that we force a line break + span.length = 0; + span.advance.x = 2; // To start at the same horizontal line as the chunk itself + span.advance.y = self.bounds.y1; + span.insert_hyphen_before_line_break = false; + span.skip_next_chars = 0; + } + } + cursor.x += match self.align { Alignment::Start => 0, Alignment::Center => (remaining_width - span.advance.x) / 2, @@ -598,7 +616,6 @@ impl Span { let mut span_width = 0; let mut found_any_whitespace = false; - let mut chunks_wider_chars = 0; let mut char_indices_iter = text.char_indices().peekable(); // Iterating manually because we need a reference to the iterator inside the @@ -611,14 +628,8 @@ impl Span { if let Some(chunkify_config) = chunks { if i == chunkify_config.chunk_size { line.advance.y = 0; - // Decreasing the offset for each wider character in the chunk - line.advance.x += chunkify_config.x_offset - chunks_wider_chars; + line.advance.x += chunkify_config.x_offset; return line; - } else { - // Counting all the wider characters in the chunk - if chunkify_config.is_char_wider(ch) { - chunks_wider_chars += 1; - } } } diff --git a/core/embed/rust/src/ui/model_tr/theme.rs b/core/embed/rust/src/ui/model_tr/theme.rs index 0dd5b16031..7360164368 100644 --- a/core/embed/rust/src/ui/model_tr/theme.rs +++ b/core/embed/rust/src/ui/model_tr/theme.rs @@ -43,8 +43,8 @@ pub const TEXT_MONO_ADDRESS_CHUNKS: TextStyle = TEXT_MONO_DATA .with_line_spacing(2) .with_ellipsis_icon(ICON_NEXT_PAGE, -2); -// Chunks for this model, with accounting for some wider characters in MONO font -pub const MONO_CHUNKS: Chunks = Chunks::new(4, 4).with_wider_chars("mMwW"); +// Chunks for this model +pub const MONO_CHUNKS: Chunks = Chunks::new(4, 4); /// Convert Python-side numeric id to a `TextStyle`. pub fn textstyle_number(num: i32) -> &'static TextStyle {