(irc) Color-formatting support

This commit is contained in:
Jaidyn Ann 2021-08-16 21:52:28 -05:00
parent ab4881f2f0
commit 4bb6cfee7c
3 changed files with 118 additions and 16 deletions

View File

@ -9,6 +9,34 @@ enum UserRole {
}; };
// Formatting information from https://modern.ircdocs.horse/formatting.html
#define FORMAT_BOLD 0x02
#define FORMAT_COLOR 0x03
#define FORMAT_RESET 0x0f
#define FORMAT_REVERSE 0x16
#define FORMAT_ITALIC 0x1d
#define FORMAT_STRIKEOUT 0x1e
#define FORMAT_UNDERSCORE 0x1f
#define FORMAT_COLOR_COUNT 99
#define FORMAT_COLORS { 0xFFFFFF, 0x000000, 0x00007F, 0x009300, \
0xFF0000, 0x7F0000, 0x9C009C, 0xFC7F00, 0xFFFF00, 0x00FC00, 0x009393, \
0x00FFFF, 0x0000FC, 0xFF00FF, 0x7F7F7F, 0xD2D2D2, \
0x470000, 0x472100, 0x474700, 0x324700, 0x004700, 0x00472c, 0x004747, \
0x002747, 0x000047, 0x2e0047, 0x470047, 0x47002a, 0x740000, 0x743a00, \
0x747400, 0x517400, 0x007400, 0x007449, 0x007474, 0x004074, 0x000074, \
0x4b0074, 0x740074, 0x740045, 0xb50000, 0xb56300, 0xb5b500, 0x7db500, \
0x00b500, 0x00b571, 0x00b5b5, 0x0063b5, 0x0000b5, 0x7500b5, 0xb500b5, \
0xb5006b, 0xff0000, 0xff8c00, 0xffff00, 0xb2ff00, 0x00ff00, 0x00ffa0, \
0x00ffff, 0x008cff, 0x0000ff, 0xa500ff, 0xff00ff, 0xff0098, 0xff5959, \
0xffb459, 0xffff71, 0xcfff60, 0x6fff6f, 0x65ffc9, 0x6dffff, 0x59b4ff, \
0x5959ff, 0xc459ff, 0xff66ff, 0xff59bc, 0xff9c9c, 0xffd39c, 0xffff9c, \
0xe2ff9c, 0x9cff9c, 0x9cffdb, 0x9cffff, 0x9cd3ff, 0x9c9cff, 0xdc9cff, \
0xff9cff, 0xff94d3, 0x000000, 0x131313, 0x282828, 0x363636, 0x4d4d4d, \
0x656565, 0x818181, 0x9f9f9f, 0xbcbcbc, 0xe2e2e2, 0xffffff };
// From RFC 2812
#define RPL_WELCOME 1 #define RPL_WELCOME 1
#define RPL_WHOISUSER 311 #define RPL_WHOISUSER 311
#define RPL_ENDOFWHO 315 #define RPL_ENDOFWHO 315

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io> * Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* Copyright 2017, Akshay Agarwal <agarwal.akshay.akshay8@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license. * All rights reserved. Distributed under the terms of the MIT license.
*/ */
@ -990,10 +991,22 @@ IrcProtocol::_IsChannelName(BString name)
#define disable_all_faces(current) { \ #define disable_all_faces(current) { \
if (bold > -1) _ToggleAndAdd(msg, B_BOLD_FACE, &bold, current); \ if (bold > -1) _FormatToggleFace(msg, B_BOLD_FACE, &bold, current); \
if (italics > -1) _ToggleAndAdd(msg, B_ITALIC_FACE, &italics, current); \ if (italics > -1) _FormatToggleFace(msg, B_ITALIC_FACE, &italics, current); \
if (strike > -1) _ToggleAndAdd(msg, B_STRIKEOUT_FACE, &strike, current); \ if (strike > -1) _FormatToggleFace(msg, B_STRIKEOUT_FACE, &strike, current); \
if (underline > -1) _ToggleAndAdd(msg, B_UNDERSCORE_FACE, &underline, current); \ if (underline > -1) _FormatToggleFace(msg, B_UNDERSCORE_FACE, &underline, current); \
if (reverse > -1) _FormatToggleFace(msg, B_NEGATIVE_FACE, &reverse, current); \
};
#define disable_color(current) { \
if (colorStart > -1) { \
msg->AddInt32("color_start", colorStart); \
msg->AddInt32("color_length", current - colorStart); \
msg->AddColor("color", _IntToRgb(color)); \
colorStart = -1; \
color = -1; \
} \
}; };
@ -1002,26 +1015,72 @@ IrcProtocol::_AddFormatted(BMessage* msg, const char* name, BString text)
{ {
BString newText; BString newText;
int32 italics = -1, bold = -1, underline = -1, strike = -1, mono = -1; int32 italics = -1, bold = -1, underline = -1, strike = -1, mono = -1;
int32 reverse = -1;
int32 color = -1, colorStart = -1;
int32 length = text.CountBytes(0, text.CountChars()); int32 length = text.CountBytes(0, text.CountChars());
for (int32 j=0, i=0; j < length; j++) { for (int32 j=0, i=0; j < length; j++) {
char c = text.ByteAt(j); char c = text.ByteAt(j);
switch (c) { switch (c) {
case 0x02: case FORMAT_COLOR:
_ToggleAndAdd(msg, B_BOLD_FACE, &bold, i); {
// Apply and reset previous color, if existant
disable_color(i);
char one = text.ByteAt(j + 1);
char two = text.ByteAt(j + 2);
// Try and get colors from either two-digits or one-digits
int32 colorIndex = -1;
if (isdigit(one) == true && isdigit(two) == true) {
char num[3] = { one, two, '\0' };
colorIndex = atoi(num);
if (colorIndex >= 0 && colorIndex <= 99)
j += 2;
}
else if (isdigit(one) == true) {
char num[2] = { one, '\0' };
colorIndex = atoi(num);
if (colorIndex >= 0 && colorIndex <= 99)
j++;
}
else
break; break;
case 0x1d:
_ToggleAndAdd(msg, B_ITALIC_FACE, &italics, i); // Use color if valid
if (colorIndex >= 0 && colorIndex <= 99) {
int colors[FORMAT_COLOR_COUNT] = FORMAT_COLORS;
color = colors[colorIndex];
colorStart = i;
}
// Ignore setting of background
if (text.ByteAt(j + 1) == ',')
if (isdigit(text.ByteAt(j+2)) && isdigit(text.ByteAt(j+3)))
j += 3;
else if (isdigit(text.ByteAt(j + 2)))
j += 2;
break; break;
case 0x1f: }
_ToggleAndAdd(msg, B_UNDERSCORE_FACE, &underline, i); case FORMAT_BOLD:
_FormatToggleFace(msg, B_BOLD_FACE, &bold, i);
break; break;
case 0x1e: case FORMAT_ITALIC:
_ToggleAndAdd(msg, B_STRIKEOUT_FACE, &strike, i); _FormatToggleFace(msg, B_ITALIC_FACE, &italics, i);
break; break;
case 0x0f: case FORMAT_UNDERSCORE:
_FormatToggleFace(msg, B_UNDERSCORE_FACE, &underline, i);
break;
case FORMAT_STRIKEOUT:
_FormatToggleFace(msg, B_STRIKEOUT_FACE, &strike, i);
break;
case FORMAT_REVERSE:
_FormatToggleFace(msg, B_NEGATIVE_FACE, &reverse, i);
break;
case FORMAT_RESET:
disable_all_faces(i); disable_all_faces(i);
disable_color(i);
break; break;
default: default:
newText << c; newText << c;
@ -1029,12 +1088,13 @@ IrcProtocol::_AddFormatted(BMessage* msg, const char* name, BString text)
} }
} }
disable_all_faces(length); disable_all_faces(length);
disable_color(length);
msg->AddString(name, newText); msg->AddString(name, newText);
} }
void void
IrcProtocol::_ToggleAndAdd(BMessage* msg, uint16 face, int32* start, IrcProtocol::_FormatToggleFace(BMessage* msg, uint16 face, int32* start,
int32 current) int32 current)
{ {
if (*start == -1) if (*start == -1)
@ -1234,6 +1294,16 @@ IrcProtocol::_TrimStringToNewline(BString* str)
} }
rgb_color
IrcProtocol::_IntToRgb(int rgb)
{
uint8 r = rgb >> 16;
uint8 g = rgb >> 8 & 0xFF;
uint8 b = rgb & 0xFF;
return (rgb_color){r, g, b};
}
BMessage BMessage
IrcProtocol::_AccountTemplate() IrcProtocol::_AccountTemplate()
{ {

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io> * Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* Copyright 2017, Akshay Agarwal <agarwal.akshay.akshay8@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license. * All rights reserved. Distributed under the terms of the MIT license.
*/ */
#ifndef _IRC_PROTOCOL_H #ifndef _IRC_PROTOCOL_H
@ -88,8 +89,8 @@ private:
void _AddFormatted(BMessage* msg, const char* name, void _AddFormatted(BMessage* msg, const char* name,
BString text); BString text);
void _ToggleAndAdd(BMessage* msg, uint16 face, int32* start, void _FormatToggleFace(BMessage* msg, uint16 face,
int32 current); int32* start, int32 current);
void _UpdateContact(BString nick, BString ident, bool online); void _UpdateContact(BString nick, BString ident, bool online);
void _AddContact(BString nick); void _AddContact(BString nick);
@ -110,6 +111,9 @@ private:
// Trim given string until newline hit, return trimmed part // Trim given string until newline hit, return trimmed part
BString _TrimStringToNewline(BString* str); BString _TrimStringToNewline(BString* str);
// Borrowed from Calendar's ColorConverter
rgb_color _IntToRgb(int rgb);
// GUI templates // GUI templates
BMessage _AccountTemplate(); BMessage _AccountTemplate();
BMessage _RoomTemplate(); BMessage _RoomTemplate();