From 96a292d40e7f6fe505c4a0f686d35132ffac8208 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 9 Jan 2014 15:20:29 +0100 Subject: Finish 256 colour support for Irssi 256 colour patch is cleaned up and the remaining cases are made work, this includes especially Theme support, which was not implemented before. Changes not related to colours were reverted again, making a review of the two patches against master easier to follow. As a byproduct of the Hex-colour code parser, the 24bit colours are also implemented. Actually using them in the terminal is guarded by a compile time switch (as well as a run time switch), as it breaks the existing colour protocol and requires additional storage. To make a seamless usage, down-conversion is provided for 8 and 16 colours. Diverging from Tom's approach, the colour protocol is reverted back to the original one. Unfortunately, the changes required in the Theme engine will break the API. For more details, please refer to the patch documentation at either http://irssi-docs.wikispaces.com/Notes-256-Colour or https://github.com/shabble/irssi-docs/wiki/Notes-256-Colour --- src/fe-text/textbuffer.c | 153 +++++++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 66 deletions(-) (limited to 'src/fe-text/textbuffer.c') diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 35f52a16..ad1b06f6 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -39,8 +39,8 @@ TEXT_BUFFER_REC *textbuffer_create(void) buffer = g_slice_new0(TEXT_BUFFER_REC); buffer->last_eol = TRUE; - buffer->last_fg = LINE_COLOR_DEFAULT; - buffer->last_bg = LINE_COLOR_DEFAULT | LINE_COLOR_BG; + buffer->last_fg = -1; + buffer->last_bg = -1; return buffer; } @@ -148,6 +148,7 @@ static void text_chunk_append(TEXT_BUFFER_REC *buffer, { TEXT_CHUNK_REC *chunk; int left; + int i; if (len == 0) return; @@ -166,8 +167,12 @@ static void text_chunk_append(TEXT_BUFFER_REC *buffer, } } - if (left > 0 && data[left-1] == 0) - left--; /* don't split the commands */ + for (i = 5; i > 0; --i) { + if (left >= i && data[left-i] == 0) { + left -= i; /* don't split the commands */ + break; + } + } memcpy(chunk->buffer + chunk->pos, data, left); chunk->pos += left; @@ -238,84 +243,92 @@ int textbuffer_line_exists_after(LINE_REC *line, LINE_REC *search) return FALSE; } +#ifdef TERM_TRUECOLOR +static void format_24bit_line_color(unsigned char *out, int *pos, int bg, unsigned int color) +{ + unsigned char rgb[] = { color >> 16, color >> 8, color }; + unsigned char x = bg ? 0x1 : 0; + unsigned int i; + out[(*pos)++] = LINE_COLOR_24; + for (i = 0; i < 3; ++i) { + if (rgb[i] > 0x20) + out[(*pos)++] = rgb[i]; + else { + out[(*pos)++] = 0x20 + rgb[i]; + x |= 0x10 << i; + } + } + out[(*pos)++] = 0x20 + x; +} +#endif + void textbuffer_line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line, int fg, int bg, int flags) { - unsigned char data[20]; - memset(data, 0, 20); - - int pos = 0; - int i = 0; - /* get the fg & bg command chars */ - /* TODO: These things are adding additional data to colours. */ - g_message( "TBLAC1: fg: 0x%08x, bg: 0x%08x, flags: 0x%08x, last_flags: 0x%08x\n", - fg, bg, flags, buffer->last_flags); + unsigned char data[22]; + int pos; - /* fg = fg < 0 ? LINE_COLOR_DEFAULT : fg & 0xff; */ - /* bg = LINE_COLOR_BG | (bg < 0 ? LINE_COLOR_DEFAULT : bg & 0xff); */ - g_message( "TBLAC2: fg: 0x%02x, bg: 0x%02x\n", fg, bg); - - if (fg != buffer->last_fg) { + pos = 0; + if (fg != buffer->last_fg + || (flags & GUI_PRINT_FLAG_COLOR_24_FG) != (buffer->last_flags & GUI_PRINT_FLAG_COLOR_24_FG)) { buffer->last_fg = fg; data[pos++] = 0; - data[pos++] = LINE_CMD_SELECT_FG; - data[pos++] = 0; - data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg; - g_message( "TBLAC2: fg: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]); - +#ifdef TERM_TRUECOLOR + if (flags & GUI_PRINT_FLAG_COLOR_24_FG) + format_24bit_line_color(data, &pos, 0, fg); + else +#endif + if (fg < 0) + data[pos++] = LINE_COLOR_DEFAULT; + else if (fg < 16) + data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg; + else if (fg < 256) { + data[pos++] = LINE_COLOR_EXT; + data[pos++] = fg; + } } - if (bg != buffer->last_bg) { + if (bg != buffer->last_bg + || (flags & GUI_PRINT_FLAG_COLOR_24_BG) != (buffer->last_flags & GUI_PRINT_FLAG_COLOR_24_BG)) { buffer->last_bg = bg; data[pos++] = 0; - data[pos++] = LINE_CMD_SELECT_BG; - data[pos++] = 0; - data[pos++] = bg; - g_message( "TBLAC2: bg: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]); - +#ifdef TERM_TRUECOLOR + if (flags & GUI_PRINT_FLAG_COLOR_24_BG) + format_24bit_line_color(data, &pos, 1, bg); + else +#endif + if (bg < 0) + data[pos++] = LINE_COLOR_BG | LINE_COLOR_DEFAULT; + else if (bg < 16) + data[pos++] = LINE_COLOR_BG | bg; + else if (bg < 256) { + data[pos++] = LINE_COLOR_EXT_BG; + data[pos++] = bg; + } } if ((flags & GUI_PRINT_FLAG_UNDERLINE) != (buffer->last_flags & GUI_PRINT_FLAG_UNDERLINE)) { data[pos++] = 0; data[pos++] = LINE_CMD_UNDERLINE; - g_message( "TBLAC2: underline: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]); - } if ((flags & GUI_PRINT_FLAG_REVERSE) != (buffer->last_flags & GUI_PRINT_FLAG_REVERSE)) { data[pos++] = 0; data[pos++] = LINE_CMD_REVERSE; - g_message( "TBLAC2: reverse: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]); - } if ((flags & GUI_PRINT_FLAG_BLINK) != (buffer->last_flags & GUI_PRINT_FLAG_BLINK)) { data[pos++] = 0; data[pos++] = LINE_CMD_BLINK; - g_message( "TBLAC2: blink: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]); - } if ((flags & GUI_PRINT_FLAG_BOLD) != (buffer->last_flags & GUI_PRINT_FLAG_BOLD)) { data[pos++] = 0; data[pos++] = LINE_CMD_BOLD; - g_message( "TBLAC2: bold: data[%d}=%d(0x%02x)\n", pos,data[pos-1],data[pos-1]); - } if (flags & GUI_PRINT_FLAG_INDENT) { data[pos++] = 0; data[pos++] = LINE_CMD_INDENT; - g_message( "TBLAC2: indent: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]); - } - g_message( "TBLAC data:\n"); - - for (i=0; i < 20; i++) { - g_message( "%02x\n", data[i]); - } - g_message( "\n"); - - if (pos > 0) { - g_message( "calling textbuffer_insert()\n"); + if (pos > 0) *line = textbuffer_insert(buffer, *line, data, pos, NULL); - } buffer->last_flags = flags; } @@ -351,14 +364,11 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after, data[len-2] == 0 && data[len-1] == LINE_CMD_EOL; if (buffer->last_eol) { - buffer->last_fg = LINE_COLOR_DEFAULT; - buffer->last_bg = LINE_COLOR_DEFAULT | LINE_COLOR_BG; + buffer->last_fg = -1; + buffer->last_bg = -1; buffer->last_flags = 0; } - g_message( "line created: '%s' %d\n", line->text, line->info.time); - g_message( "Buffer %p\n", buffer); - return line; } @@ -413,22 +423,18 @@ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer) static void set_color(GString *str, int cmd) { - int color = ATTR_COLOR_UNDEFINED; + int color = -1; if (!(cmd & LINE_COLOR_DEFAULT)) - color = (cmd & 0xff) + '0'; - - g_message( "textbuffer.c:set_color color: %d (%02x)\n", color, color); + color = (cmd & 0x0f)+'0'; if ((cmd & LINE_COLOR_BG) == 0) { /* change foreground color */ - g_string_append_printf(str, "%c%c%c", - LINE_FORMAT_MARKER, + g_string_append_printf(str, "\004%c%c", color, FORMAT_COLOR_NOCHANGE); } else { /* change background color */ - g_string_append_printf(str, "%c%c%c", - LINE_FORMAT_MARKER, + g_string_append_printf(str, "\004%c%c", FORMAT_COLOR_NOCHANGE, color); } } @@ -467,13 +473,17 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str) if (!coloring) { /* no colors, skip coloring commands */ + if (cmd == LINE_COLOR_EXT || cmd == LINE_COLOR_EXT_BG) + ptr++; +#ifdef TERM_TRUECOLOR + else if (cmd == LINE_COLOR_24) + ptr+=4; +#endif + continue; } - /* these magic numbers correspond with some of IS_COLOR_CODE in - * formats.c:843 (31 and 22) */ - - if ((cmd & 0x80) == 0) { + if ((cmd & LINE_CMD_EOL) == 0) { /* set color */ set_color(str, cmd); } else switch (cmd) { @@ -499,6 +509,17 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str) g_string_append_printf(str, "\004%c", FORMAT_STYLE_INDENT); break; + case LINE_COLOR_EXT: + format_ext_color(str, 0, *ptr++); + break; + case LINE_COLOR_EXT_BG: + format_ext_color(str, 1, *ptr++); + break; +#ifdef TERM_TRUECOLOR + case LINE_COLOR_24: + g_string_append_printf(str, "\004%c", FORMAT_COLOR_24); + break; +#endif } } } -- cgit v1.2.3