chiark / gitweb /
Render paragraphs by wrapping them.
authorSimon Tatham <anakin@pobox.com>
Mon, 25 Dec 2023 13:12:45 +0000 (13:12 +0000)
committerSimon Tatham <anakin@pobox.com>
Mon, 25 Dec 2023 15:05:25 +0000 (15:05 +0000)
src/text.rs

index 2e7c95f19aada25ecbc225a446e9039f3b3e5677..54e3aaae3d5af394e6ac673da1a0b6b17bad021e 100644 (file)
@@ -310,9 +310,94 @@ fn test_para_build() {
 }
 
 impl TextFragment for Paragraph {
-    fn render(&self, _width: usize) -> Vec<ColouredString> {
-        vec! {
-            ColouredString::plain("FIXME"),
+    fn render(&self, width: usize) -> Vec<ColouredString> {
+        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"),
+        });
+
+}