1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
#ifndef WSAP_TERM_PEN_H
#define WSAP_TERM_PEN_H
#include "compat.h"
#include "term.h"
#include <stdbool.h>
#include <stdint.h>
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;
int k = i + 2;
if (k < 16 && k < nparams) {
uint32_t shifted = (~(uint32_t)subparams) >> k;
colon = term_ctz32(shifted);
int max_colon = (nparams < 16 ? nparams : 16) - k;
if (colon > max_colon)
colon = max_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
|