Performant and correct set_spans_truncated
the previous implementation used set_string_truncated. This is not only awkward with this kind of "streaming" string (and therefore lead to an inefficient and incorrect initial implementation) but that function also truncates strings of width 1 when there is only a single char available. The implementation here is performant, correct and also handles the single width case correctly.
This commit is contained in:
parent
e72be52996
commit
67783ddfd4
1 changed files with 36 additions and 20 deletions
|
@ -434,28 +434,44 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {
|
pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {
|
||||||
let mut remaining_width = width;
|
// prevent panic if out of range
|
||||||
let mut alt_x = x;
|
if !self.in_bounds(x, y) || width == 0 {
|
||||||
let (text, styles) =
|
return (x, y);
|
||||||
spans
|
}
|
||||||
.0
|
|
||||||
.iter()
|
|
||||||
.fold((String::new(), vec![]), |(mut s, mut h), span| {
|
|
||||||
s.push_str(span.content.as_ref());
|
|
||||||
let mut styles = span
|
|
||||||
.styled_graphemes(span.style)
|
|
||||||
.map(|grapheme| grapheme.style)
|
|
||||||
.collect();
|
|
||||||
h.append(&mut styles);
|
|
||||||
|
|
||||||
let w = span.width() as u16;
|
let mut x_offset = x as usize;
|
||||||
alt_x = alt_x + w;
|
let max_offset = min(self.area.right(), width.saturating_add(x));
|
||||||
remaining_width = remaining_width.saturating_sub(w);
|
let mut start_index = self.index_of(x, y);
|
||||||
|
let mut index = self.index_of(max_offset as u16, y);
|
||||||
|
|
||||||
(s, h)
|
let content_width = spans.width();
|
||||||
});
|
let truncated = content_width > width as usize;
|
||||||
self.set_string_truncated(x, y, &text, width.into(), |idx| styles[idx], true, true);
|
if truncated {
|
||||||
(x, y)
|
self.content[start_index].set_symbol("…");
|
||||||
|
start_index += 1;
|
||||||
|
} else {
|
||||||
|
index -= width as usize - content_width;
|
||||||
|
}
|
||||||
|
for span in spans.0.iter().rev() {
|
||||||
|
for s in span.content.graphemes(true).rev() {
|
||||||
|
let width = s.width();
|
||||||
|
if width == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let start = index - width;
|
||||||
|
if start < start_index {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
self.content[start].set_symbol(s);
|
||||||
|
self.content[start].set_style(span.style);
|
||||||
|
for i in start + 1..index {
|
||||||
|
self.content[i].reset();
|
||||||
|
}
|
||||||
|
index -= width;
|
||||||
|
x_offset += width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(x_offset as u16, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {
|
pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue