1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 03:50:58 +00:00

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]
This commit is contained in:
grdddj 2023-09-19 11:04:10 +02:00 committed by Jiří Musil
parent ad5c1858c1
commit 42a6a5ac9b
2 changed files with 39 additions and 28 deletions

View File

@ -59,8 +59,6 @@ pub struct Chunks {
pub chunk_size: usize, pub chunk_size: usize,
/// How big will be the space between chunks (in pixels). /// How big will be the space between chunks (in pixels).
pub x_offset: i16, pub x_offset: i16,
/// Optional characters that are wider and should be accounted for
pub wider_chars: Option<&'static str>,
} }
impl Chunks { impl Chunks {
@ -68,20 +66,6 @@ impl Chunks {
Chunks { Chunks {
chunk_size, chunk_size,
x_offset, 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) 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 { impl TextLayout {
@ -262,9 +254,21 @@ impl TextLayout {
PageBreaking::CutAndInsertEllipsisBoth PageBreaking::CutAndInsertEllipsisBoth
) && self.continues_from_prev_page ) && self.continues_from_prev_page
{ {
sink.prev_page_ellipsis(*cursor, self);
// Move the cursor to the right, always the same distance // 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() { while !remaining_text.is_empty() {
@ -285,6 +289,20 @@ impl TextLayout {
self.style.chunks, 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 { cursor.x += match self.align {
Alignment::Start => 0, Alignment::Start => 0,
Alignment::Center => (remaining_width - span.advance.x) / 2, Alignment::Center => (remaining_width - span.advance.x) / 2,
@ -598,7 +616,6 @@ impl Span {
let mut span_width = 0; let mut span_width = 0;
let mut found_any_whitespace = false; let mut found_any_whitespace = false;
let mut chunks_wider_chars = 0;
let mut char_indices_iter = text.char_indices().peekable(); let mut char_indices_iter = text.char_indices().peekable();
// Iterating manually because we need a reference to the iterator inside the // 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 let Some(chunkify_config) = chunks {
if i == chunkify_config.chunk_size { if i == chunkify_config.chunk_size {
line.advance.y = 0; line.advance.y = 0;
// Decreasing the offset for each wider character in the chunk line.advance.x += chunkify_config.x_offset;
line.advance.x += chunkify_config.x_offset - chunks_wider_chars;
return line; return line;
} else {
// Counting all the wider characters in the chunk
if chunkify_config.is_char_wider(ch) {
chunks_wider_chars += 1;
}
} }
} }

View File

@ -43,8 +43,8 @@ pub const TEXT_MONO_ADDRESS_CHUNKS: TextStyle = TEXT_MONO_DATA
.with_line_spacing(2) .with_line_spacing(2)
.with_ellipsis_icon(ICON_NEXT_PAGE, -2); .with_ellipsis_icon(ICON_NEXT_PAGE, -2);
// Chunks for this model, with accounting for some wider characters in MONO font // Chunks for this model
pub const MONO_CHUNKS: Chunks = Chunks::new(4, 4).with_wider_chars("mMwW"); pub const MONO_CHUNKS: Chunks = Chunks::new(4, 4);
/// Convert Python-side numeric id to a `TextStyle`. /// Convert Python-side numeric id to a `TextStyle`.
pub fn textstyle_number(num: i32) -> &'static TextStyle { pub fn textstyle_number(num: i32) -> &'static TextStyle {