skip to content
==> tests/text.c <==
1/* Lines and text as ratatui renders them: alignment, truncation of the left part when a right-
2 * or centre-aligned line is too long, wide characters, styles. */
3#include "mesh/check.h"
4#include "tui/text.h"
5
6#include <string.h>
7
8static const char *row(const tui_buffer *b, uint16_t y) {
9    static char out[512];
10    size_t n = 0;
11    for (uint16_t x = 0; x < b->area.width; x++) {
12        const char *s = tui_cell_symbol(tui_buffer_cell_c(b, x, y));
13        size_t k = strlen(s);
14        memcpy(out + n, s, k);
15        n += k;
16    }
17    out[n] = 0;
18    return out;
19}
20
21int main(void) {
22    tui_arena a = {0};
23    tui_buffer b;
24    tui_buffer_init(&b, (tui_rect){0, 0, 10, 4});
25    tui_line l = tui_line_empty();
26    tui_line_push(&a, &l, tui_span_raw("ab"));
27    tui_line_push(&a, &l, tui_span_styled("cd", tui_fg(TUI_RED)));
28    CHECK_U(tui_line_width(&l), 4);
29    l.align = TUI_ALIGN_RIGHT;
30    tui_line_render(&a, &l, (tui_rect){0, 0, 10, 1}, &b, TUI_ALIGN_NONE);
31    CHECK_S(row(&b, 0), "      abcd");
32    CHECK(tui_color_eq(tui_buffer_cell(&b, 9, 0)->fg, TUI_RED));
33    l.align = TUI_ALIGN_CENTER;
34    tui_line_render(&a, &l, (tui_rect){0, 1, 10, 1}, &b, TUI_ALIGN_NONE);
35    CHECK_S(row(&b, 1), "   abcd   ");
36    /* Too long: right alignment keeps the end, centre the middle. */
37    tui_line long_l = tui_line_from_str(&a, "0123456789abcdef");
38    long_l.align = TUI_ALIGN_RIGHT;
39    tui_line_render(&a, &long_l, (tui_rect){0, 2, 10, 1}, &b, TUI_ALIGN_NONE);
40    CHECK_S(row(&b, 2), "6789abcdef");
41    long_l.align = TUI_ALIGN_CENTER;
42    tui_line_render(&a, &long_l, (tui_rect){0, 3, 10, 1}, &b, TUI_ALIGN_NONE);
43    CHECK_S(row(&b, 3), "3456789abc");
44    /* str::lines semantics. */
45    tui_text t = tui_text_from_str(&a, "one\r\ntwo\n\nfour\n");
46    CHECK_U(t.n, 4);
47    CHECK_S(t.lines[1].spans[0].s, "two");
48    CHECK_U(t.lines[2].spans[0].s[0], 0);
49    CHECK_U(tui_text_from_str(&a, "").n, 0);
50    CHECK_U(tui_line_from_str(&a, "a\nb").n, 2);
51    /* Wide characters in a right-aligned overflow: the cut falls between graphemes. */
52    tui_buffer_clear(&b, b.area);
53    tui_line w = tui_line_from_str(&a, "\xE6\x97\xA5\xE6\x97\xA5\xE6\x97\xA5\xE6\x97\xA5\xE6\x97\xA5\xE6\x97\xA5");
54    w.align = TUI_ALIGN_RIGHT;
55    tui_line_render(&a, &w, (tui_rect){0, 0, 9, 1}, &b, TUI_ALIGN_NONE);
56    CHECK_S(tui_cell_symbol(tui_buffer_cell(&b, 1, 0)), "\xE6\x97\xA5");
57    CHECK_S(tui_cell_symbol(tui_buffer_cell(&b, 0, 0)), " ");
58    /* set_line patches the line's style with each span's. */
59    tui_line s = tui_line_empty();
60    s.style = tui_fg(TUI_BLUE);
61    tui_line_push(&a, &s, tui_span_styled("x", tui_style_bold(tui_style_new())));
62    uint16_t x = tui_buffer_set_line(&b, 0, 3, &s, 5);
63    CHECK_U(x, 1);
64    CHECK(tui_color_eq(tui_buffer_cell(&b, 0, 3)->fg, TUI_BLUE));
65    CHECK_U(tui_buffer_cell(&b, 0, 3)->mod, TUI_BOLD);
66    tui_sgrapheme *g;
67    CHECK_U(tui_line_graphemes(&a, &l, tui_style_new(), &g), 4);
68    tui_buffer_free(&b);
69    tui_arena_free(&a);
70    return mesh_check_done();
71}