diff --git a/src/text/line.rs b/src/text/line.rs old mode 100644 new mode 100755 index 902c8083..43c9e530 --- a/src/text/line.rs +++ b/src/text/line.rs @@ -687,6 +687,21 @@ impl Widget for Line<'_> { impl WidgetRef for Line<'_> { fn render_ref(&self, area: Rect, buf: &mut Buffer) { + self.render_with_alignment(area, buf, None); + } +} + +impl Line<'_> { + /// An internal implementation method for `WidgetRef::render_ref` + /// + /// Allows the parent widget to define a default alignment, to be + /// used if `Line::alignment` is `None`. + pub(crate) fn render_with_alignment( + &self, + area: Rect, + buf: &mut Buffer, + parent_alignment: Option, + ) { let area = area.intersection(buf.area); if area.is_empty() { return; @@ -699,10 +714,12 @@ impl WidgetRef for Line<'_> { buf.set_style(area, self.style); + let alignment = self.alignment.or(parent_alignment); + let area_width = usize::from(area.width); let can_render_complete_line = line_width <= area_width; if can_render_complete_line { - let indent_width = match self.alignment { + let indent_width = match alignment { Some(Alignment::Center) => (area_width.saturating_sub(line_width)) / 2, Some(Alignment::Right) => area_width.saturating_sub(line_width), Some(Alignment::Left) | None => 0, @@ -713,7 +730,7 @@ impl WidgetRef for Line<'_> { } else { // There is not enough space to render the whole line. As the right side is truncated by // the area width, only truncate the left. - let skip_width = match self.alignment { + let skip_width = match alignment { Some(Alignment::Center) => (line_width.saturating_sub(area_width)) / 2, Some(Alignment::Right) => line_width.saturating_sub(area_width), Some(Alignment::Left) | None => 0, diff --git a/src/text/text.rs b/src/text/text.rs old mode 100644 new mode 100755 index e1a68136..13f2ddda --- a/src/text/text.rs +++ b/src/text/text.rs @@ -735,23 +735,8 @@ impl WidgetRef for Text<'_> { fn render_ref(&self, area: Rect, buf: &mut Buffer) { let area = area.intersection(buf.area); buf.set_style(area, self.style); - for (line, row) in self.iter().zip(area.rows()) { - let line_width = line.width() as u16; - - let x_offset = match (self.alignment, line.alignment) { - (Some(Alignment::Center), None) => area.width.saturating_sub(line_width) / 2, - (Some(Alignment::Right), None) => area.width.saturating_sub(line_width), - _ => 0, - }; - - let line_area = Rect { - x: area.x + x_offset, - y: row.y, - width: area.width - x_offset, - height: 1, - }; - - line.render(line_area, buf); + for (line, line_area) in self.iter().zip(area.rows()) { + line.render_with_alignment(line_area, buf, self.alignment); } } } @@ -1196,6 +1181,33 @@ mod tests { assert_eq!(buf, Buffer::with_lines([" foo "])); } + #[test] + fn render_right_aligned_with_truncation() { + let text = Text::from("123456789").alignment(Alignment::Right); + let area = Rect::new(0, 0, 5, 1); + let mut buf = Buffer::empty(area); + text.render(area, &mut buf); + assert_eq!(buf, Buffer::with_lines(["56789"])); + } + + #[test] + fn render_centered_odd_with_truncation() { + let text = Text::from("123456789").alignment(Alignment::Center); + let area = Rect::new(0, 0, 5, 1); + let mut buf = Buffer::empty(area); + text.render(area, &mut buf); + assert_eq!(buf, Buffer::with_lines(["34567"])); + } + + #[test] + fn render_centered_even_with_truncation() { + let text = Text::from("123456789").alignment(Alignment::Center); + let area = Rect::new(0, 0, 6, 1); + let mut buf = Buffer::empty(area); + text.render(area, &mut buf); + assert_eq!(buf, Buffer::with_lines(["234567"])); + } + #[test] fn render_one_line_right() { let text = Text::from(vec![