1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-15 20:19:23 +00:00

TR-rust: properly centering all text in ChoiceItem

This commit is contained in:
grdddj 2023-04-11 12:54:25 +02:00
parent 43174e04b1
commit a546c9dba5
2 changed files with 46 additions and 19 deletions

View File

@ -129,15 +129,43 @@ impl Font {
display::text_width(text, self.into())
}
/// Width of the text that is visible, not including the space
/// after the last character.
/// Width of the text that is visible.
/// Not including the spaces before the first and after the last character.
pub fn visible_text_width(self, text: &str) -> i16 {
let text_minus_one = &text[..text.len() - 1];
match text.len() {
0 => 0,
1 => {
let char = unwrap!(text.chars().last());
let char_glyph = unwrap!(self.get_glyph(char as u8));
char_glyph.width
},
_ => {
let first_char = unwrap!(text.chars().next());
let first_char_glyph = unwrap!(self.get_glyph(first_char as u8));
let first_char_visible_width = first_char_glyph.adv - first_char_glyph.bearing_x;
let last_char = unwrap!(text.chars().last());
let last_char_glyph = unwrap!(self.get_glyph(last_char as u8));
let middle_chars = &text[1..text.len() - 1];
let middle_chars_width = self.text_width(middle_chars);
self.text_width(text_minus_one) + last_char_glyph.width
let last_char = unwrap!(text.chars().last());
let last_char_glyph = unwrap!(self.get_glyph(last_char as u8));
let last_char_visible_width = last_char_glyph.width + last_char_glyph.bearing_x;
first_char_visible_width + middle_chars_width + last_char_visible_width
}
}
}
/// Returning the x-bearing (offset) of the first character.
/// Useful to enforce that the text is positioned correctly (e.g. centered).
pub fn start_x_bearing(self, text: &str) -> i16 {
if text.is_empty() {
return 0;
}
let first_char = unwrap!(text.chars().next());
let first_char_glyph = unwrap!(self.get_glyph(first_char as u8));
first_char_glyph.bearing_x
}
pub fn char_width(self, ch: char) -> i16 {

View File

@ -57,23 +57,24 @@ impl ChoiceItem {
}
}
/// Getting the text width in pixels.
fn text_width(&self) -> i16 {
self.font.text_width(&self.text)
}
/// Getting the visible text width in pixels.
fn visible_text_width(&self) -> i16 {
self.font.visible_text_width(&self.text)
}
/// Getting the initial x-bearing of the text in pixels,
/// so that we can adjust its positioning to center it properly.
fn text_x_bearing(&self) -> i16 {
self.font.start_x_bearing(&self.text)
}
/// Getting the non-central width in pixels.
/// It will show an icon if defined, otherwise the text, not both.
fn width_side(&self) -> i16 {
if let Some(icon) = self.icon {
icon.toif.width()
} else {
self.text_width()
self.visible_text_width()
}
}
@ -89,12 +90,7 @@ impl ChoiceItem {
let bound = theme::BUTTON_OUTLINE;
let left_bottom =
area.bottom_center() + Offset::new(-self.width_center() / 2 - bound, bound + 1);
let mut x_size = self.width_center() + 2 * bound;
// Shortening the x-size by one pixel when visible text width is even to center
// it properly.
if self.visible_text_width() % 2 == 0 {
x_size -= 1;
}
let x_size = self.width_center() + 2 * bound;
let y_size = self.font.text_height() + 2 * bound;
let outline_size = Offset::new(x_size, y_size);
let outline = Rect::from_bottom_left_and_size(left_bottom, outline_size);
@ -175,6 +171,9 @@ impl Choice for ChoiceItem {
);
baseline = baseline + Offset::x(icon.toif.width() + ICON_RIGHT_PADDING);
}
// Possibly shifting the baseline left, when there is a text bearing.
// This is to center the text properly.
baseline = baseline - Offset::x(self.text_x_bearing());
if inverse {
display_inverse(baseline, &self.text, self.font);
} else {
@ -190,7 +189,7 @@ impl Choice for ChoiceItem {
} else {
0
};
icon_width + self.text_width()
icon_width + self.visible_text_width()
}
/// Painting item on the side if it fits, otherwise paint incomplete if