From 4384435941b8c7658856b381d071aee2e0035e89 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 17:49:34 +0300 Subject: term: move the term core to subprojects/term The core now builds, tests, and benchmarks alone, as a Meson subproject with no dependency on the main tree. - include/term/ holds term.h and the header-only unicode/. src/ holds the core and its private headers. The main tree gets only include/term through term_dep, so it cannot reach a private header. - The term tests, the term benchmarks, the Kitty parser suite, and tools/amalgamate.py and tools/generate_unicode.py move with it. The tests run as term:. - The main build passes its -march (arch_flag) and b_ndebug to the subproject. A directory configured before this commit needs meson configure -Dterm:arch_flag=-march=... once. - The term tests compile with -UNDEBUG. They do work inside assert. - The subproject exports term_test_dep with term_api.h, for the main tree's render, thumbnail, color, and selection tests. - The Kitty bridge used struct vector2i and has not compiled since the public API redesign. It builds again. 2 of its 14 tests fail: REP after a tab, and a cursor report after a resize. - dirgraph.py drops the term and unicode layers. Its self-test uses pty. - The symbols test ignores the __odr_asan symbols that ASan adds. Co-Authored-By: Claude Opus 5.5 --- src/pen.h | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 src/pen.h (limited to 'src/pen.h') diff --git a/src/pen.h b/src/pen.h new file mode 100644 index 0000000..d7118b5 --- /dev/null +++ b/src/pen.h @@ -0,0 +1,165 @@ +#ifndef WSAP_TERM_PEN_H +#define WSAP_TERM_PEN_H + +#include "term.h" +#include +#include + +struct term_pen { + uint32_t fg; + uint32_t bg; + uint32_t ul; + uint8_t underline; + bool bold : 1; + bool faint : 1; + bool italic : 1; + bool strike : 1; + bool overline : 1; + bool inverse : 1; +}; + +/* The pen of a stored cell. A cell has no underline color, so neither has + * this. */ +struct pen_attr { + uint32_t fg; + uint32_t bg; + uint16_t flags; + uint16_t link; +}; + +static inline struct pen_attr pen_attr_default(void) +{ + return (struct pen_attr){ .fg = TERM_COLOR_FG, .bg = TERM_COLOR_BG }; +} + +static inline bool pen_attr_is_default(const struct pen_attr *a) +{ + return a->fg == TERM_COLOR_FG && a->bg == TERM_COLOR_BG && a->flags == 0 && a->link == 0; +} + +static inline bool pen_attr_equal(const struct pen_attr *a, const struct pen_attr *b) +{ + return a->fg == b->fg && a->bg == b->bg && a->flags == b->flags && a->link == b->link; +} + +static inline uint32_t term_rgb(int r, int g, int b) +{ + return term_color_rgb((uint8_t)r, (uint8_t)g, (uint8_t)b); +} + +static inline void pen_reset(struct term_pen *p) +{ + p->fg = TERM_COLOR_FG; + p->bg = TERM_COLOR_BG; + p->ul = 0; + p->underline = 0; + p->bold = false; + p->faint = false; + p->italic = false; + p->strike = false; + p->overline = false; + p->inverse = false; +} + +static inline int sgr_extended_color(const int *params, int nparams, uint16_t subparams, int i, + uint32_t *color, bool *assigned) +{ + *assigned = false; + if (i + 1 >= nparams) + return 0; + if (i + 2 < nparams && params[i + 1] == 5) { + int index = params[i + 2]; + if (index >= 0 && index <= 255) { + *color = term_color_index(index); + *assigned = true; + } + return 2; + } + if (params[i + 1] != 2) + return 0; + int colon = 0; + while (i + 2 + colon < nparams && i + 2 + colon < 16 && + (subparams & (1u << (i + 2 + colon)))) + colon++; + int skip = colon >= 4 ? 1 : 0; + if (i + 4 + skip >= nparams) + return 0; + *color = term_rgb(params[i + 2 + skip], params[i + 3 + skip], params[i + 4 + skip]); + *assigned = true; + return 4 + skip; +} + +static inline bool pen_set_standard_color(struct term_pen *p, int code) +{ + if ((unsigned)(code - 30) < 8) + p->fg = term_color_index(code - 30); + else if ((unsigned)(code - 40) < 8) + p->bg = term_color_index(code - 40); + else if ((unsigned)(code - 90) < 8) + p->fg = term_color_index(code - 90 + 8); + else if ((unsigned)(code - 100) < 8) + p->bg = term_color_index(code - 100 + 8); + else + return false; + return true; +} + +static inline void sgr_apply(struct term_pen *pen, const int *params, int nparams, uint16_t subparams) +{ + if (nparams == 0) { + pen_reset(pen); + return; + } + for (int i = 0; i < nparams; i++) { + int p = params[i]; + switch (p) { + case 0: pen_reset(pen); break; + case 1: pen->bold = true; break; + case 2: pen->faint = true; break; + case 3: pen->italic = true; break; + case 4: { + int style = 1; + if (i + 1 < nparams && (subparams & (1u << (i + 1)))) + style = params[++i]; + pen->underline = (uint8_t)(style <= 5 ? style : 1); + break; + } + case 7: pen->inverse = true; break; + case 9: pen->strike = true; break; + case 21: pen->underline = 2; break; + case 22: pen->bold = false; pen->faint = false; break; + case 23: pen->italic = false; break; + case 24: pen->underline = 0; break; + case 27: pen->inverse = false; break; + case 29: pen->strike = false; break; + case 38: { + uint32_t c; bool ok; + i += sgr_extended_color(params, nparams, subparams, i, &c, &ok); + if (ok) pen->fg = c; + break; + } + case 39: pen->fg = TERM_COLOR_FG; break; + case 48: { + uint32_t c; bool ok; + i += sgr_extended_color(params, nparams, subparams, i, &c, &ok); + if (ok) pen->bg = c; + break; + } + case 49: pen->bg = TERM_COLOR_BG; break; + case 53: pen->overline = true; break; + case 55: pen->overline = false; break; + case 58: { + uint32_t c; bool ok; + i += sgr_extended_color(params, nparams, subparams, i, &c, &ok); + if (ok) pen->ul = c; + break; + } + case 59: pen->ul = 0; break; + default: + pen_set_standard_color(pen, p); + break; + } + } +} + +#endif -- cgit v1.2.3