about summary refs log tree commit diff stats
path: root/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs')
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs
new file mode 100644
index 00000000..7f0aaec9
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs
@@ -0,0 +1,57 @@
+use ab_glyph::{point, Font, Glyph, Point, ScaleFont};
+
+use crate::wayland::ansi::{StyledChar, StyledString};
+
+/// Simple paragraph layout for glyphs into `target`.
+/// Starts at position `(0, ascent)`.
+///
+/// This is for testing and examples.
+pub(super) fn layout_paragraph<F, SF, BF, BSF>(
+    font: SF,
+    bold_font: BSF,
+    position: Point,
+    max_width: f32,
+    text: &StyledString,
+    target: &mut Vec<(Glyph, StyledChar)>,
+) where
+    F: Font,
+    SF: ScaleFont<F>,
+    BF: Font,
+    BSF: ScaleFont<BF>,
+{
+    let v_advance = font.height() + font.line_gap();
+    let mut caret = position + point(0.0, font.ascent());
+    let mut last_glyph: Option<Glyph> = None;
+
+    for c in text.chars() {
+        if c.as_char().is_control() {
+            if c.as_char() == '\n' {
+                caret = point(position.x, caret.y + v_advance);
+                last_glyph = None;
+            }
+            continue;
+        }
+
+        let mut glyph = if c.is_bold() {
+            bold_font.scaled_glyph(c.as_char())
+        } else {
+            font.scaled_glyph(c.as_char())
+        };
+
+        if let Some(previous) = last_glyph.take() {
+            caret.x += font.kern(previous.id, glyph.id);
+        }
+        glyph.position = caret;
+
+        last_glyph = Some(glyph.clone());
+        caret.x += font.h_advance(glyph.id);
+
+        if !c.as_char().is_whitespace() && caret.x > position.x + max_width {
+            caret = point(position.x, caret.y + v_advance);
+            glyph.position = caret;
+            last_glyph = None;
+        }
+
+        target.push((glyph, c));
+    }
+}