fix(core/rust/ui): no hyphens when breaking monospace lines

[no changelog]
pull/2666/head
Martin Milata 2 years ago
parent 3b92923caa
commit a61a46808e

@ -13,6 +13,8 @@ pub enum LineBreaking {
/// Break words, adding a hyphen before the line-break. Does not use any
/// smart algorithm, just char-by-char.
BreakWordsAndInsertHyphen,
/// Break words char-by-char, don't insert hyphens.
BreakWordsNoHyphen,
}
#[derive(Copy, Clone)]
@ -81,6 +83,16 @@ impl TextStyle {
page_breaking: PageBreaking::CutAndInsertEllipsis,
}
}
pub const fn with_line_breaking(mut self, line_breaking: LineBreaking) -> Self {
self.line_breaking = line_breaking;
self
}
pub const fn with_page_breaking(mut self, page_breaking: PageBreaking) -> Self {
self.page_breaking = page_breaking;
self
}
}
impl TextLayout {
@ -423,7 +435,12 @@ impl Span {
ch == ASCII_SPACE || ch == ASCII_LF || ch == ASCII_CR
}
let hyphen_width = text_font.char_width(ASCII_HYPHEN);
let use_hyphens = !matches!(breaking, LineBreaking::BreakWordsNoHyphen);
let hyphen_width = if use_hyphens {
text_font.char_width(ASCII_HYPHEN)
} else {
0
};
// The span we return in case the line has to break. We mutate it in the
// possible break points, and its initial value is returned in case no text
@ -467,8 +484,8 @@ impl Span {
return line;
} else {
let have_space_for_break = span_width + char_width + hyphen_width <= max_width;
let can_break_word = matches!(breaking, LineBreaking::BreakWordsAndInsertHyphen)
|| !found_any_whitespace;
let can_break_word =
!matches!(breaking, LineBreaking::BreakAtWhitespace) || !found_any_whitespace;
if have_space_for_break && can_break_word {
// Break after this character, append hyphen.
line.length = match char_indices_iter.peek() {
@ -476,7 +493,7 @@ impl Span {
None => text.len(),
};
line.advance.x = span_width + char_width;
line.insert_hyphen_before_line_break = true;
line.insert_hyphen_before_line_break = use_hyphens;
line.skip_next_chars = 0;
}
}

@ -3,4 +3,4 @@ mod iter;
pub mod layout;
pub mod paragraphs;
pub use layout::TextStyle;
pub use layout::{LineBreaking, PageBreaking, TextStyle};

@ -490,9 +490,9 @@ mod tests {
);
page.place(SCREEN);
let expected1 = "<SwipePage active_page:0 page_count:3 content:<Paragraphs This paragraph is using a\nbold font. It doesn't\nneed to be all that long.\nAnd this one is\nusing MONO.\nMonospace is\nnice for...\n> buttons:<FixedHeightBar inner:<Button text:IDK > > >";
let expected2 = "<SwipePage active_page:1 page_count:3 content:<Paragraphs numbers, they\nhave the same\nwidth and can be\nscanned quickly.\nEven if they\nspan several\npages or...\n> buttons:<FixedHeightBar inner:<Button text:IDK > > >";
let expected3 = "<SwipePage active_page:2 page_count:3 content:<Paragraphs something.\nLet's add another one\nfor a good measure. This\none should overflow all\nthe way to the third\npage with a bit of luck.\n> buttons:<FixedHeightBar inner:<Button text:IDK > > >";
let expected1 = "<SwipePage active_page:0 page_count:3 content:<Paragraphs This paragraph is using a\nbold font. It doesn't\nneed to be all that long.\nAnd this one is\nusing MONO. Mono\nspace is nice fo\nr numbers, they\n> buttons:<FixedHeightBar inner:<Button text:IDK > > >";
let expected2 = "<SwipePage active_page:1 page_count:3 content:<Paragraphs have the same wi\ndth and can be s\ncanned quickly.\nEven if they spa\nn several pages\nor something.\nLet's add another one...\n> buttons:<FixedHeightBar inner:<Button text:IDK > > >";
let expected3 = "<SwipePage active_page:2 page_count:3 content:<Paragraphs for a good measure. This\none should overflow all\nthe way to the third\npage with a bit of luck.\n> buttons:<FixedHeightBar inner:<Button text:IDK > > >";
assert_eq!(trace(&page), expected1);
swipe_down(&mut page);

@ -1,6 +1,6 @@
use crate::ui::{
component::{
text::{formatted::FormattedFonts, TextStyle},
text::{formatted::FormattedFonts, LineBreaking, PageBreaking, TextStyle},
FixedHeightBar,
},
display::{Color, Font},
@ -357,7 +357,9 @@ pub fn loader_default() -> LoaderStyleSheet {
pub const TEXT_NORMAL: TextStyle = TextStyle::new(Font::NORMAL, FG, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_DEMIBOLD: TextStyle = TextStyle::new(Font::DEMIBOLD, FG, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_BOLD: TextStyle = TextStyle::new(Font::BOLD, FG, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_MONO: TextStyle = TextStyle::new(Font::MONO, FG, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_MONO: TextStyle = TextStyle::new(Font::MONO, FG, BG, GREY_LIGHT, GREY_LIGHT)
.with_line_breaking(LineBreaking::BreakWordsNoHyphen)
.with_page_breaking(PageBreaking::Cut);
pub const TEXT_NORMAL_OFF_WHITE: TextStyle =
TextStyle::new(Font::NORMAL, OFF_WHITE, BG, GREY_LIGHT, GREY_LIGHT);

@ -214,7 +214,7 @@ def test_show_multisig_xpubs(
yield # show address
layout = client.debug.wait_layout() # TODO: do not need to *wait* now?
assert layout.get_title() == "MULTISIG 2 OF 3"
assert layout.get_content() == address
assert layout.get_content().replace(" ", "") == address
client.debug.press_no()
yield # show QR code
@ -234,7 +234,10 @@ def test_show_multisig_xpubs(
layout2 = client.debug.wait_layout()
assert layout2.get_title() == expected_title
assert layout1.get_content() + layout2.get_content() == xpubs[xpub_num]
content = (layout1.get_content() + layout2.get_content()).replace(
" ", ""
)
assert content == xpubs[xpub_num]
client.debug.press_yes()

@ -324,7 +324,10 @@ def test_signmessage_pagination(client: Client, message: str):
)
# We cannot differentiate between a newline and space in the message read from Trezor.
expected_message = "Confirm message: " + message.replace("\n", " ").rstrip()
expected_message = (
("Confirm message: " + message).replace("\n", "").replace(" ", "")
)
message_read = message_read.replace(" ", "")
assert expected_message == message_read

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save