Factor out mIRC color parsing

master
Curtis McEnroe 2018-08-04 16:36:25 -04:00
parent ea23dcec3b
commit aca376bc89
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
1 changed files with 42 additions and 39 deletions

69
ui.c
View File

@ -34,6 +34,7 @@
#endif #endif
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
static const int TOPIC_COLS = 512; static const int TOPIC_COLS = 512;
static const int CHAT_LINES = 100; static const int CHAT_LINES = 100;
@ -105,9 +106,9 @@ void uiDraw(void) {
doupdate(); doupdate();
} }
static const struct { static const struct AttrColor {
attr_t attr; attr_t attr;
short color; short pair;
} MIRC_COLORS[16] = { } MIRC_COLORS[16] = {
{ A_BOLD, COLOR_WHITE }, // white { A_BOLD, COLOR_WHITE }, // white
{ A_NORMAL, COLOR_BLACK }, // black { A_NORMAL, COLOR_BLACK }, // black
@ -127,54 +128,56 @@ static const struct {
{ A_NORMAL, COLOR_WHITE }, // light grey { A_NORMAL, COLOR_WHITE }, // light grey
}; };
static void uiAdd(WINDOW *win, const char *str) { static const char *parseColor(struct AttrColor *color, const char *str) {
attr_t attr = A_NORMAL;
short colorPair = -1;
attr_t colorAttr = A_NORMAL;
for (;;) {
size_t cc = strcspn(str, "\2\3\35\37");
wattr_set(win, attr | colorAttr, 1 + colorPair, NULL);
waddnstr(win, str, cc);
if (!str[cc]) break;
str = &str[cc];
switch (*str++) {
break; case '\2': attr ^= A_BOLD;
break; case '\35': attr ^= A_ITALIC;
break; case '\37': attr ^= A_UNDERLINE;
break; case '\3': {
short fg = 0; short fg = 0;
short bg = 0; size_t fgLen = MIN(strspn(str, "0123456789"), 2);
size_t fgLen = strspn(str, "0123456789");
if (!fgLen) { if (!fgLen) {
colorPair = -1; color->attr = A_NORMAL;
colorAttr = A_NORMAL; color->pair = -1;
break; return str;
} }
if (fgLen > 2) fgLen = 2;
for (size_t i = 0; i < fgLen; ++i) { for (size_t i = 0; i < fgLen; ++i) {
fg *= 10; fg *= 10;
fg += str[i] - '0'; fg += str[i] - '0';
} }
str = &str[fgLen]; str = &str[fgLen];
size_t bgLen = (str[0] == ',') ? strspn(&str[1], "0123456789") : 0; short bg = 0;
if (bgLen > 2) bgLen = 2; size_t bgLen = 0;
if (str[0] == ',') {
bgLen = MIN(strspn(&str[1], "0123456789"), 2);
}
for (size_t i = 0; i < bgLen; ++i) { for (size_t i = 0; i < bgLen; ++i) {
bg *= 10; bg *= 10;
bg += str[1 + i] - '0'; bg += str[1 + i] - '0';
} }
if (bgLen) str = &str[1 + bgLen]; if (bgLen) str = &str[1 + bgLen];
if (colorPair == -1) colorPair = 0; if (color->pair == -1) color->pair = 0;
colorPair = (colorPair & 070) | MIRC_COLORS[fg].color; color->attr = MIRC_COLORS[fg].attr;
colorAttr = MIRC_COLORS[fg].attr; color->pair = (color->pair & 070) | MIRC_COLORS[fg].pair;
if (bgLen) { if (bgLen) {
colorPair = (colorPair & 007) | (MIRC_COLORS[bg].color << 3); color->pair = (color->pair & 007) | (MIRC_COLORS[bg].pair << 3);
}
} }
return str;
}
static void uiAdd(WINDOW *win, const char *str) {
attr_t attr = A_NORMAL;
struct AttrColor color = { A_NORMAL, -1 };
for (;;) {
size_t cc = strcspn(str, "\2\3\35\37");
wattr_set(win, attr | color.attr, 1 + color.pair, NULL);
waddnstr(win, str, cc);
if (!str[cc]) break;
str = &str[cc];
switch (*str++) {
break; case '\2': attr ^= A_BOLD;
break; case '\3': str = parseColor(&color, str);
break; case '\35': attr ^= A_ITALIC;
break; case '\37': attr ^= A_UNDERLINE;
} }
} }
} }