From: Simon Tatham Date: Mon, 25 Dec 2023 13:12:45 +0000 (+0000) Subject: Render paragraphs by wrapping them. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=ce95d7ec08777b40a6e73e4a32424133f4a81a06;p=mastodonochrome.git Render paragraphs by wrapping them. --- diff --git a/src/text.rs b/src/text.rs index 2e7c95f..54e3aaa 100644 --- a/src/text.rs +++ b/src/text.rs @@ -310,9 +310,94 @@ fn test_para_build() { } impl TextFragment for Paragraph { - fn render(&self, _width: usize) -> Vec { - vec! { - ColouredString::plain("FIXME"), + fn render(&self, width: usize) -> Vec { + let mut lines = Vec::new(); + let mut curr_width = 0; + let mut curr_pos; + + let mut start_pos = 0; + let mut start_width = 0; + let mut break_pos = 0; + let mut break_width = 0; + let mut curr_indent = self.firstindent; + + for (i, word) in self.words.iter().enumerate() { + curr_width += word.width(); + curr_pos = i + 1; + + if !word.is_space() { + if self.wrap && break_pos > start_pos && + curr_width - start_width + curr_indent > width { + let mut line = ColouredString::plain(" ") + .repeat(curr_indent); + for i in start_pos..break_pos { + line.push_str(&self.words[i].slice()); + } + lines.push(line); + start_pos = break_pos; + start_width = break_width; + if self.words[start_pos].is_space() { + start_width += self.words[start_pos].width(); + start_pos += 1; + } + curr_indent = self.laterindent; + } + + break_pos = curr_pos; + break_width = curr_width; + } + } + + let mut line = ColouredString::plain(" ").repeat(curr_indent); + for i in start_pos..break_pos { + line.push_str(&self.words[i].slice()); } + lines.push(line); + + lines } } + +#[test] +fn test_para_wrap() { + let p = Paragraph::new().add(&ColouredString::plain( + "the quick brown fox jumps over the lazy dog")).into_box(); + assert_eq!(p.render(15), vec! { + ColouredString::plain("the quick brown"), + ColouredString::plain("fox jumps over"), + ColouredString::plain("the lazy dog"), + }); + + let p = Paragraph::new().add(&ColouredString::plain( + " one supercalifragilisticexpialidocious word")).into_box(); + assert_eq!(p.render(15), vec! { + ColouredString::plain(" one"), + ColouredString::plain("supercalifragilisticexpialidocious"), + ColouredString::plain("word"), + }); + + let p = Paragraph::new().add(&ColouredString::plain( + " supercalifragilisticexpialidocious word")).into_box(); + assert_eq!(p.render(15), vec! { + ColouredString::plain(" supercalifragilisticexpialidocious"), + ColouredString::plain("word"), + }); + + let p = Paragraph::new().add(&ColouredString::plain( + "the quick brown fox jumps over the lazy dog")) + .set_wrap(false).into_box(); + assert_eq!(p.render(15), vec! { + ColouredString::plain("the quick brown fox jumps over the lazy dog"), + }); + + let p = Paragraph::new().add(&ColouredString::plain( + "the quick brown fox jumps over the lazy dog")) + .set_indent(4, 2).into_box(); + assert_eq!(p.render(15), vec! { + ColouredString::plain(" the quick"), + ColouredString::plain(" brown fox"), + ColouredString::plain(" jumps over"), + ColouredString::plain(" the lazy dog"), + }); + +}