mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Avoid iterating graphemes unless we have to.
Iterating graphemes with `text.graphemes(true)` is somewhat expensive due to the complexity of unicode. However, we were doing it _twice_ in the `Printer::print` method in order to truncate the input text to fit the content area. This changes that method to track the width of the intput text, and only do the grapheme iteration when truncation is actually necessary.
This commit is contained in:
parent
af566dd57f
commit
561b83dbc9
@ -129,46 +129,55 @@ impl<'a, 'b> Printer<'a, 'b> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let text_width = text.width();
|
let mut text_width = text.width();
|
||||||
|
|
||||||
// If we're waaaay too far left, just give up.
|
// If we're waaaay too far left, just give up.
|
||||||
if hidden_part.x > text_width {
|
if hidden_part.x > text_width {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to drop hidden_part.x width from the start of the string.
|
let mut text = text;
|
||||||
// prefix() may be too short if there's a double-width character.
|
let mut start = start;
|
||||||
// So instead, keep the suffix and drop the prefix.
|
|
||||||
|
|
||||||
// TODO: use a different prefix method that is *at least* the width
|
if hidden_part.x > 0 {
|
||||||
// (and not *at most*)
|
// We have to drop hidden_part.x width from the start of the string.
|
||||||
let tail =
|
// prefix() may be too short if there's a double-width character.
|
||||||
suffix(text.graphemes(true), text_width - hidden_part.x, "");
|
// So instead, keep the suffix and drop the prefix.
|
||||||
let skipped_len = text.len() - tail.length;
|
|
||||||
let skipped_width = text_width - tail.width;
|
|
||||||
assert_eq!(text[..skipped_len].width(), skipped_width);
|
|
||||||
|
|
||||||
// This should be equal most of the time, except when there's a double
|
// TODO: use a different prefix method that is *at least* the width
|
||||||
// character preventing us from splitting perfectly.
|
// (and not *at most*)
|
||||||
assert!(skipped_width >= hidden_part.x);
|
let tail =
|
||||||
|
suffix(text.graphemes(true), text_width - hidden_part.x, "");
|
||||||
|
let skipped_len = text.len() - tail.length;
|
||||||
|
let skipped_width = text_width - tail.width;
|
||||||
|
assert_eq!(text[..skipped_len].width(), skipped_width);
|
||||||
|
|
||||||
|
// This should be equal most of the time, except when there's a double
|
||||||
|
// character preventing us from splitting perfectly.
|
||||||
|
assert!(skipped_width >= hidden_part.x);
|
||||||
|
|
||||||
|
// Drop part of the text, and move the cursor correspondingly.
|
||||||
|
text = &text[skipped_len..];
|
||||||
|
start = start + (skipped_width, 0);
|
||||||
|
text_width -= skipped_width;
|
||||||
|
}
|
||||||
|
|
||||||
// Drop part of the text, and move the cursor correspondingly.
|
|
||||||
let text = &text[skipped_len..];
|
|
||||||
let start = start + (skipped_width, 0);
|
|
||||||
assert!(start.fits(self.content_offset));
|
assert!(start.fits(self.content_offset));
|
||||||
|
|
||||||
// What we did before should guarantee that this won't overflow.
|
// What we did before should guarantee that this won't overflow.
|
||||||
let start = start - self.content_offset;
|
start = start - self.content_offset;
|
||||||
|
|
||||||
// Do we have enough room for the entire line?
|
// Do we have enough room for the entire line?
|
||||||
let room = self.output_size.x - start.x;
|
let room = self.output_size.x - start.x;
|
||||||
|
|
||||||
// Drop the end of the text if it's too long
|
if room < text_width {
|
||||||
// We want the number of CHARACTERS, not bytes.
|
// Drop the end of the text if it's too long
|
||||||
// (Actually we want the "width" of the string, see unicode-width)
|
// We want the number of CHARACTERS, not bytes.
|
||||||
let prefix_len = prefix(text.graphemes(true), room, "").length;
|
// (Actually we want the "width" of the string, see unicode-width)
|
||||||
let text = &text[..prefix_len];
|
let prefix_len = prefix(text.graphemes(true), room, "").length;
|
||||||
assert!(text.width() <= room);
|
text = &text[..prefix_len];
|
||||||
|
assert!(text.width() <= room);
|
||||||
|
}
|
||||||
|
|
||||||
let start = start + self.offset;
|
let start = start + self.offset;
|
||||||
self.backend.print_at(start, text);
|
self.backend.print_at(start, text);
|
||||||
|
Loading…
Reference in New Issue
Block a user