commit 7a5f4cd

uint  ·  2026-05-16 13:52:33 +0000 UTC
parent 7a30e87
add dec line drawing character set support
2 files changed,  +52, -1
+5, -0
 1@@ -18,6 +18,8 @@ enum TState {
 2 	TSTATE_CSI,
 3 	TSTATE_OSC,
 4 	TSTATE_OSC_ESC,
 5+	TSTATE_CHARSET,
 6+	TSTATE_CHARSET_SKIP,
 7 };
 8 
 9 typedef struct {
10@@ -51,6 +53,9 @@ typedef struct {
11 	pid_t          ptypid;
12 
13 	enum TState    state;
14+	bool           acs[2];
15+	int            charset;
16+	int            charset_target;
17 	bool           wrapnext;
18 	bool           cursor_visible;
19 	int            csi_params[CSI_PARAMS_MAX];
+47, -1
 1@@ -12,6 +12,7 @@ static int csi_arg(Term* t, int i, int fallback);
 2 static void alt_screen(Term* t, Caret* c, bool on);
 3 static void chars_insert(Term* t, Caret* c, int n);
 4 static void chars_delete(Term* t, Caret* c, int n);
 5+static uint32_t acs_map(unsigned char ch);
 6 static void csi_dispatch(Term* t, Caret* c, unsigned char ch);
 7 static void csi_reset(Term* t);
 8 static int cp_width(uint32_t cp);
 9@@ -32,6 +33,25 @@ static const uint32_t ansi_colours[16] = { /* TODO */
10 	0xffff5c5c, 0xffff00ff, 0xffffff00, 0xffffffff,
11 };
12 
13+/** TODO
14+ */
15+static uint32_t acs_map(unsigned char ch)
16+{
17+	switch (ch) {
18+	case '`': return 0x25c6; /* ◆ */ case 'a': return 0x2592; /* ▒ */
19+	case 'f': return 0x00b0; /* ° */ case 'g': return 0x00b1; /* ± */
20+	case 'j': return 0x2518; /* ┘ */ case 'k': return 0x2510; /* ┐ */
21+	case 'l': return 0x250c; /* ┌ */ case 'm': return 0x2514; /* └ */
22+	case 'n': return 0x253c; /* ┼ */ case 'q': return 0x2500; /* ─ */
23+	case 't': return 0x251c; /* ├ */ case 'u': return 0x2524; /* ┤ */
24+	case 'v': return 0x2534; /* ┴ */ case 'w': return 0x252c; /* ┬ */
25+	case 'x': return 0x2502; /* │ */ case 'y': return 0x2264; /* ≤ */
26+	case 'z': return 0x2265; /* ≥ */ case '{': return 0x03c0; /* π */
27+	case '|': return 0x2260; /* ≠ */ case '}': return 0x00a3; /* £ */
28+	case '~': return 0x00b7; /* · */ default:  return ch;
29+	}
30+}
31+
32 /** TODO
33  */
34 static int csi_arg(Term* t, int i, int fallback)
35@@ -485,7 +505,7 @@ static void utf8_putc(Term* t, Caret* c, unsigned char ch)
36 
37 	if (ch < 0x80) {
38 		utf8_flush(t, c);
39-		term_putc(t, c, ch);
40+		term_putc(t, c, t->acs[t->charset] ? acs_map(ch) : ch);
41 		return;
42 	}
43 
44@@ -718,6 +738,12 @@ bool term_write(Term* t, Caret* c, const char* s, size_t n)
45 				utf8_flush(t, c);
46 				t->state = TSTATE_ESC;
47 			}
48+			else if (ch == '\x0E') {
49+				t->charset = 1;
50+			}
51+			else if (ch == '\x0F') {
52+				t->charset = 0;
53+			}
54 			else {
55 				utf8_putc(t, c, ch);
56 			}
57@@ -731,6 +757,17 @@ bool term_write(Term* t, Caret* c, const char* s, size_t n)
58 			else if (ch == ']') {
59 				t->state = TSTATE_OSC;
60 			}
61+			else if (ch == '(') {
62+				t->charset_target = 0;
63+				t->state = TSTATE_CHARSET;
64+			}
65+			else if (ch == ')') {
66+				t->charset_target = 1;
67+				t->state = TSTATE_CHARSET;
68+			}
69+			else if (ch == '*' || ch == '+') {
70+				t->state = TSTATE_CHARSET_SKIP;
71+			}
72 			else if (ch == '7') {
73 				t->saved = *c;
74 				t->state = TSTATE_NORMAL;
75@@ -790,6 +827,15 @@ bool term_write(Term* t, Caret* c, const char* s, size_t n)
76 		case TSTATE_OSC_ESC:
77 			t->state = ch == '\\' ? TSTATE_NORMAL : TSTATE_OSC;
78 			break;
79+
80+		case TSTATE_CHARSET:
81+			t->acs[t->charset_target] = ch == '0';
82+			t->state = TSTATE_NORMAL;
83+			break;
84+
85+		case TSTATE_CHARSET_SKIP:
86+			t->state = TSTATE_NORMAL;
87+			break;
88 		}
89 
90 		if (old.x != c->x || old.y != c->y)