mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-18 20:48:18 +00:00
TR-rust: properly centering all text in ChoiceItem
This commit is contained in:
parent
43174e04b1
commit
a546c9dba5
@ -129,15 +129,43 @@ impl Font {
|
|||||||
display::text_width(text, self.into())
|
display::text_width(text, self.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Width of the text that is visible, not including the space
|
/// Width of the text that is visible.
|
||||||
/// after the last character.
|
/// Not including the spaces before the first and after the last character.
|
||||||
pub fn visible_text_width(self, text: &str) -> i16 {
|
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 middle_chars = &text[1..text.len() - 1];
|
||||||
let last_char_glyph = unwrap!(self.get_glyph(last_char as u8));
|
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 {
|
pub fn char_width(self, ch: char) -> i16 {
|
||||||
|
@ -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.
|
/// Getting the visible text width in pixels.
|
||||||
fn visible_text_width(&self) -> i16 {
|
fn visible_text_width(&self) -> i16 {
|
||||||
self.font.visible_text_width(&self.text)
|
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.
|
/// Getting the non-central width in pixels.
|
||||||
/// It will show an icon if defined, otherwise the text, not both.
|
/// It will show an icon if defined, otherwise the text, not both.
|
||||||
fn width_side(&self) -> i16 {
|
fn width_side(&self) -> i16 {
|
||||||
if let Some(icon) = self.icon {
|
if let Some(icon) = self.icon {
|
||||||
icon.toif.width()
|
icon.toif.width()
|
||||||
} else {
|
} else {
|
||||||
self.text_width()
|
self.visible_text_width()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,12 +90,7 @@ impl ChoiceItem {
|
|||||||
let bound = theme::BUTTON_OUTLINE;
|
let bound = theme::BUTTON_OUTLINE;
|
||||||
let left_bottom =
|
let left_bottom =
|
||||||
area.bottom_center() + Offset::new(-self.width_center() / 2 - bound, bound + 1);
|
area.bottom_center() + Offset::new(-self.width_center() / 2 - bound, bound + 1);
|
||||||
let mut x_size = self.width_center() + 2 * bound;
|
let 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 y_size = self.font.text_height() + 2 * bound;
|
let y_size = self.font.text_height() + 2 * bound;
|
||||||
let outline_size = Offset::new(x_size, y_size);
|
let outline_size = Offset::new(x_size, y_size);
|
||||||
let outline = Rect::from_bottom_left_and_size(left_bottom, outline_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);
|
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 {
|
if inverse {
|
||||||
display_inverse(baseline, &self.text, self.font);
|
display_inverse(baseline, &self.text, self.font);
|
||||||
} else {
|
} else {
|
||||||
@ -190,7 +189,7 @@ impl Choice for ChoiceItem {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
icon_width + self.text_width()
|
icon_width + self.visible_text_width()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Painting item on the side if it fits, otherwise paint incomplete if
|
/// Painting item on the side if it fits, otherwise paint incomplete if
|
||||||
|
Loading…
Reference in New Issue
Block a user