==> include/tui/text.h <==1/* @ajax/tui-text: ratatui's Span (a string with a style), Line (spans, a style, an alignment) and
2 * Text (lines). Everything is built in a tui_arena and lives as long as the frame. Widths are
3 * unicode-width's; rendering follows ratatui's Widget impls for &Span, &Line and &Text. */
4#ifndef TUI_TEXT_H
5#define TUI_TEXT_H
6
7#include "tui/arena.h"
8#include "tui/buffer.h"
9
10#include <stddef.h>
11#include <stdint.h>
12
13enum { TUI_ALIGN_NONE = -1, TUI_ALIGN_LEFT = 0, TUI_ALIGN_CENTER = 1, TUI_ALIGN_RIGHT = 2 };
14
15typedef struct {
16 const char *s; /* NUL-terminated UTF-8 */
17 tui_style style;
18} tui_span;
19
20typedef struct {
21 tui_span *spans;
22 size_t n, cap;
23 tui_style style;
24 int8_t align; /* TUI_ALIGN_* (NONE: the parent's) */
25} tui_line;
26
27typedef struct {
28 tui_line *lines;
29 size_t n, cap;
30 tui_style style;
31 int8_t align;
32} tui_text;
33
34/* A grapheme with the style it renders in (StyledGrapheme). */
35typedef struct {
36 const char *s;
37 size_t len;
38 tui_style style;
39} tui_sgrapheme;
40
41static inline tui_span tui_span_raw(const char *s) { return (tui_span){.s = s}; }
42static inline tui_span tui_span_styled(const char *s, tui_style st) { return (tui_span){s, st}; }
43static inline tui_line tui_line_empty(void) { return (tui_line){.align = TUI_ALIGN_NONE}; }
44static inline tui_text tui_text_empty(void) { return (tui_text){.align = TUI_ALIGN_NONE}; }
45
46void tui_line_push(tui_arena *a, tui_line *l, tui_span s);
47/* Line::from(Vec<Span>). */
48tui_line tui_line_of(tui_arena *a, size_t n, const tui_span *spans);
49static inline tui_line tui_line_span(tui_arena *a, tui_span s) { return tui_line_of(a, 1, &s); }
50/* Line::from(&str) / Line::raw: one raw span per line of s (str::lines). */
51tui_line tui_line_from_str(tui_arena *a, const char *s);
52void tui_text_push(tui_arena *a, tui_text *t, tui_line l);
53/* Text::from(&str): one line per line of s. */
54tui_text tui_text_from_str(tui_arena *a, const char *s);
55static inline tui_text tui_text_line(tui_arena *a, tui_line l) {
56 tui_text t = tui_text_empty();
57 tui_text_push(a, &t, l);
58 return t;
59}
60tui_text tui_text_of(tui_arena *a, size_t n, const tui_line *lines);
61
62/* str::lines: splits at '\n', drops one '\r' before it, no empty last line. Calls f per line. */
63void tui_str_lines(const char *s, void (*f)(void *ctx, const char *line, size_t len), void *ctx);
64
65size_t tui_span_width(const tui_span *s);
66size_t tui_line_width(const tui_line *l);
67size_t tui_text_width(const tui_text *t); /* the widest line */
68
69/* The line's graphemes (control ones left out) with base patched by the line's style and each
70 * span's (Line::styled_graphemes). *out is arena memory; returns the count. */
71size_t tui_line_graphemes(tui_arena *a, const tui_line *l, tui_style base, tui_sgrapheme **out);
72
73void tui_span_render(const tui_span *s, tui_rect area, tui_buffer *b);
74/* Line::render_with_alignment (parent: the alignment to use when the line has none). */
75void tui_line_render(tui_arena *a, const tui_line *l, tui_rect area, tui_buffer *b, int8_t parent);
76void tui_text_render(tui_arena *a, const tui_text *t, tui_rect area, tui_buffer *b);
77/* Buffer::set_line: each span through set_stringn with the line's style patched by the span's.
78 * Returns the x after the last cell written. */
79uint16_t tui_buffer_set_line(tui_buffer *b, uint16_t x, uint16_t y, const tui_line *l, uint16_t max_width);
80
81#endif