commit 55b6cc3
uint
·
2026-07-31 18:45:48 +0000 UTC
parent d647190
remove libgrapheme dependency, ignore utf8 characters
3 files changed,
+9,
-89
M
Makefile
+0,
-1
1@@ -2,7 +2,6 @@ CC = cc
2 CFLAGS = -std=c99 -Wall -Wextra
3 CPPFLAGS = -Iinclude -Ilibmaus/include
4 LDFLAGS =
5-LDLIBS = -lgrapheme
6
7 include platform.mk
8
+1,
-3
1@@ -61,8 +61,6 @@ typedef struct {
2 bool bracketed_paste;
3 int csi_params[CSI_PARAMS_MAX];
4 int csi_idx;
5- char utf8[4];
6- size_t utf8_len;
7 } Term;
8
9 /* clear screen by filling runes with ' ' and reseting
10@@ -86,7 +84,7 @@ int term_resize(Term* t, Caret* c, int cols, int rows);
11 /* scroll viewport up by one */
12 void term_scroll(Term* t);
13
14-/* processes terminal input, parse utf8, escape sequences, update
15+/* processes terminal input, parse escape sequences, update
16 caret, screen state, and damage status. */
17 bool term_write(Term* t, Caret* c, const char* s, size_t n);
18
+8,
-85
1@@ -1,9 +1,6 @@
2 #include <stdbool.h>
3 #include <stdlib.h>
4 #include <string.h>
5-#include <wchar.h>
6-
7-#include <grapheme.h>
8
9 #include "../config.h"
10 #include "term.h"
11@@ -16,7 +13,6 @@ static void chars_delete(Term* t, Caret* c, int n);
12 static uint32_t acs_map(unsigned char ch);
13 static void csi_dispatch(Term* t, Caret* c, unsigned char ch);
14 static void csi_reset(Term* t);
15-static int cp_width(uint32_t cp);
16 static void erase_display(Term* t, Caret* c);
17 static void erase_line(Term* t, Caret* c);
18 static void reset_rune(Term* t, int x, int y);
19@@ -24,8 +20,6 @@ static void rune_prepare(Term* t, int x, int y);
20 static void scroll_down(Term* t, int top, int bot, int n);
21 static void scroll_up(Term* t, int top, int bot, int n);
22 static void sgr(Term* t);
23-static void utf8_flush(Term* t, Caret* c);
24-static void utf8_putc(Term* t, Caret* c, unsigned char ch);
25
26 /* TODO */
27 static uint32_t acs_map(unsigned char ch)
28@@ -305,18 +299,6 @@ static void csi_reset(Term* t)
29 t->csi_idx = 0;
30 }
31
32-/* TODO */
33-static int cp_width(uint32_t cp)
34-{
35- int w = wcwidth((wchar_t)cp);
36-
37- if (w < 0)
38- return 1;
39- if (w > 2)
40- return 2;
41- return w;
42-}
43-
44 /* TODO */
45 static void erase_display(Term* t, Caret* c)
46 {
47@@ -464,49 +446,6 @@ static void sgr(Term* t)
48 }
49 }
50
51-/* TODO */
52-static void utf8_flush(Term* t, Caret* c)
53-{
54- if (t->utf8_len == 0)
55- return;
56- term_putc(t, c, GRAPHEME_INVALID_CODEPOINT);
57- t->utf8_len = 0;
58-}
59-
60-/* buffer and decode utf8 to code points, then write
61- using current character set */
62-static void utf8_putc(Term* t, Caret* c, unsigned char ch)
63-{
64- uint_least32_t cp;
65- size_t ret;
66-
67- if (ch < 0x80) {
68- utf8_flush(t, c);
69- term_putc(t, c, t->acs[t->charset] ? acs_map(ch) : ch);
70- return;
71- }
72-
73- if (t->utf8_len == sizeof(t->utf8))
74- utf8_flush(t, c);
75-
76- t->utf8[t->utf8_len++] = (char)ch;
77- for (;;) {
78- ret = grapheme_decode_utf8(t->utf8, t->utf8_len, &cp);
79- if (ret > t->utf8_len)
80- return;
81- if (ret == 0) {
82- t->utf8_len = 0;
83- return;
84- }
85-
86- term_putc(t, c, (uint32_t)cp);
87- t->utf8_len -= ret;
88- if (t->utf8_len == 0)
89- return;
90- memmove(t->utf8, t->utf8 + ret, t->utf8_len);
91- }
92-}
93-
94 void term_clear(Term* t, Caret* c)
95 {
96 for (int y = 0; y < t->rows; y++) {
97@@ -570,48 +509,30 @@ void term_putc(Term* t, Caret* c, uint32_t cp)
98 term_putc(t, c, '\n');
99 break;
100 default: {
101- int w;
102-
103 if (cp < 32)
104 break;
105- w = cp_width(cp);
106- if (w == 0)
107- break;
108- if (w == 2 && t->cols < 2)
109- w = 1;
110
111 if (t->wrapnext) {
112 term_putc(t, c, '\n');
113 t->wrapnext = false;
114 }
115- if (w == 2 && c->x == t->cols - 1)
116- term_putc(t, c, '\n');
117
118 rune_prepare(t, c->x, c->y);
119 Rune* r = &RUNE(t, c->x, c->y);
120 if (r->cp != cp || r->fg != t->fg || r->bg != t->bg ||
121- r->attr != t->attr || r->width != w) {
122+ r->attr != t->attr || r->width != 1) {
123 r->cp = cp;
124 r->fg = t->fg;
125 r->bg = t->bg;
126 r->attr = t->attr;
127- r->width = w;
128+ r->width = 1;
129 r->dmg = true;
130 }
131- if (w == 2) {
132- Rune* spacer = &RUNE(t, c->x + 1, c->y);
133- spacer->cp = ' ';
134- spacer->fg = t->fg;
135- spacer->bg = t->bg;
136- spacer->attr = t->attr;
137- spacer->width = 0;
138- spacer->dmg = true;
139- }
140
141- if (c->x + w >= t->cols)
142+ if (c->x + 1 >= t->cols)
143 t->wrapnext = true;
144 else
145- c->x += w;
146+ c->x++;
147
148 break;
149 }
150@@ -708,7 +629,6 @@ bool term_write(Term* t, Caret* c, const char* s, size_t n)
151 switch (t->state) {
152 case TSTATE_NORMAL:
153 if (ch == '\x1B') {
154- utf8_flush(t, c);
155 t->state = TSTATE_ESC;
156 }
157 else if (ch == '\x0E') {
158@@ -717,8 +637,11 @@ bool term_write(Term* t, Caret* c, const char* s, size_t n)
159 else if (ch == '\x0F') {
160 t->charset = 0;
161 }
162+ else if (ch >= 0x80) {
163+ /* utf8 unsupported . ignore high bit bytes */
164+ }
165 else {
166- utf8_putc(t, c, ch);
167+ term_putc(t, c, t->acs[t->charset] ? acs_map(ch) : ch);
168 }
169 break;
170