(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_WHOISUSER 311
#define RPL_ENDOFWHO 315

View File

@ -1,5 +1,6 @@
/*
* 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.
*/
@ -990,10 +991,22 @@ IrcProtocol::_IsChannelName(BString name)
#define disable_all_faces(current) { \
if (bold > -1) _ToggleAndAdd(msg, B_BOLD_FACE, &bold, current); \
if (italics > -1) _ToggleAndAdd(msg, B_ITALIC_FACE, &italics, current); \
if (strike > -1) _ToggleAndAdd(msg, B_STRIKEOUT_FACE, &strike, current); \
if (underline > -1) _ToggleAndAdd(msg, B_UNDERSCORE_FACE, &underline, current); \
if (bold > -1) _FormatToggleFace(msg, B_BOLD_FACE, &bold, current); \
if (italics > -1) _FormatToggleFace(msg, B_ITALIC_FACE, &italics, current); \
if (strike > -1) _FormatToggleFace(msg, B_STRIKEOUT_FACE, &strike, 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;
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());
for (int32 j=0, i=0; j < length; j++) {
char c = text.ByteAt(j);
switch (c) {
case 0x02:
_ToggleAndAdd(msg, B_BOLD_FACE, &bold, i);
case FORMAT_COLOR:
{
// 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;
// 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;
case 0x1d:
_ToggleAndAdd(msg, B_ITALIC_FACE, &italics, i);
}
case FORMAT_BOLD:
_FormatToggleFace(msg, B_BOLD_FACE, &bold, i);
break;
case 0x1f:
_ToggleAndAdd(msg, B_UNDERSCORE_FACE, &underline, i);
case FORMAT_ITALIC:
_FormatToggleFace(msg, B_ITALIC_FACE, &italics, i);
break;
case 0x1e:
_ToggleAndAdd(msg, B_STRIKEOUT_FACE, &strike, i);
case FORMAT_UNDERSCORE:
_FormatToggleFace(msg, B_UNDERSCORE_FACE, &underline, i);
break;
case 0x0f:
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_color(i);
break;
default:
newText << c;
@ -1029,12 +1088,13 @@ IrcProtocol::_AddFormatted(BMessage* msg, const char* name, BString text)
}
}
disable_all_faces(length);
disable_color(length);
msg->AddString(name, newText);
}
void
IrcProtocol::_ToggleAndAdd(BMessage* msg, uint16 face, int32* start,
IrcProtocol::_FormatToggleFace(BMessage* msg, uint16 face, int32* start,
int32 current)
{
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
IrcProtocol::_AccountTemplate()
{

View File

@ -1,5 +1,6 @@
/*
* 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.
*/
#ifndef _IRC_PROTOCOL_H
@ -88,8 +89,8 @@ private:
void _AddFormatted(BMessage* msg, const char* name,
BString text);
void _ToggleAndAdd(BMessage* msg, uint16 face, int32* start,
int32 current);
void _FormatToggleFace(BMessage* msg, uint16 face,
int32* start, int32 current);
void _UpdateContact(BString nick, BString ident, bool online);
void _AddContact(BString nick);
@ -110,6 +111,9 @@ private:
// Trim given string until newline hit, return trimmed part
BString _TrimStringToNewline(BString* str);
// Borrowed from Calendar's ColorConverter
rgb_color _IntToRgb(int rgb);
// GUI templates
BMessage _AccountTemplate();
BMessage _RoomTemplate();