diff options
Diffstat (limited to 'src/fe-text/textbuffer-view.c')
-rw-r--r-- | src/fe-text/textbuffer-view.c | 147 |
1 files changed, 89 insertions, 58 deletions
diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 78509151..81deaf54 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -104,65 +104,78 @@ static void textbuffer_cache_unref(TEXT_BUFFER_CACHE_REC *cache) textbuffer_cache_destroy(cache); } -#define FGATTR (ATTR_NOCOLORS | ATTR_RESETFG | 0xff) -#define BGATTR (ATTR_NOCOLORS | ATTR_RESETBG | 0xff00) +#define FGATTR (ATTR_NOCOLORS | ATTR_RESETFG | FG_MASK | ATTR_FGCOLOR24) +#define BGATTR (ATTR_NOCOLORS | ATTR_RESETBG | BG_MASK | ATTR_BGCOLOR24) static void update_cmd_color(unsigned char cmd, int *color) { - static int next_color_bg = 0; - g_message( "update_cmd_color() color: 0x%08x, cmd: 0x%08x\n", *color, cmd); - - if (cmd & 0x80) { /* cmd message */ - switch (cmd) { - + if ((cmd & 0x80) == 0) { + if (cmd & LINE_COLOR_BG) { + /* set background color */ + *color &= FGATTR; + *color &= ~ATTR_FGCOLOR24; + if ((cmd & LINE_COLOR_DEFAULT) == 0) + *color |= (cmd & 0x0f) << BG_SHIFT; + else { + *color = (*color & FGATTR) | ATTR_RESETBG; + } + } else { + /* set foreground color */ + *color &= BGATTR; + *color &= ~ATTR_BGCOLOR24; + if ((cmd & LINE_COLOR_DEFAULT) == 0) + *color |= cmd & 0x0f; + else { + *color = (*color & BGATTR) | ATTR_RESETFG; + } + } + } else switch (cmd) { case LINE_CMD_UNDERLINE: *color ^= ATTR_UNDERLINE; - g_message( "update_cmd_color() toggle underline 0x%08d\n", *color); - break; case LINE_CMD_REVERSE: - *color ^= ATTR_REVERSE; - g_message( "update_cmd_color() toggle reverse 0x%08d\n", *color); - break; case LINE_CMD_BLINK: - *color ^= ATTR_BLINK; - g_message( "update_cmd_color() toggle blink 0x%08d\n", *color); - break; case LINE_CMD_BOLD: - *color ^= ATTR_BOLD; - g_message( "update_cmd_color() toggle bold 0x%08d\n", *color); - break; case LINE_CMD_COLOR0: *color &= BGATTR; - g_message( "update_cmd_color() set BGATTR RESET 0x%08d\n", *color); - - break; - case LINE_CMD_SELECT_FG: - next_color_bg = 0; - g_message( "update_cmd_color() Next color will be FG\n"); - - break; - - case LINE_CMD_SELECT_BG: - next_color_bg = 1; - g_message( "update_cmd_color() Next color will be BG\n"); + *color &= ~ATTR_FGCOLOR24; break; } - } else { - if (next_color_bg == 1) { - *color = cmd << 8; - } else { - *color = cmd; - } - } } +#ifdef TERM_TRUECOLOR +static void unformat_24bit_line_color(const unsigned char **ptr, int off, int *flags, int *fg, int *bg) +{ + unsigned int color; + unsigned char rgbx[4]; + unsigned int i; + for (i = 0; i < 4; ++i) { + rgbx[i] = (*ptr)[i + off]; + } + rgbx[3] -= 0x20; + *ptr += 4; + for (i = 0; i < 3; ++i) { + if (rgbx[3] & (0x10 << i)) + rgbx[i] -= 0x20; + } + color = rgbx[0] << 16 | rgbx[1] << 8 | rgbx[2]; + if (rgbx[3] & 0x1) { + *flags = (*flags & FGATTR) | ATTR_BGCOLOR24; + *bg = color; + } + else { + *flags = (*flags & BGATTR) | ATTR_FGCOLOR24; + *fg = color; + } +} +#endif + static inline unichar read_unichar(const unsigned char *data, const unsigned char **next, int *width) { unichar chr = g_utf8_get_char_validated(data, -1); @@ -188,6 +201,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) unsigned char cmd; const unsigned char *ptr, *next_ptr, *last_space_ptr; int xpos, pos, indent_pos, last_space, last_color, color, linecount; + int last_bg24, last_fg24, bg24, fg24; int char_width; g_return_val_if_fail(line->text != NULL, NULL); @@ -221,7 +235,18 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) /* set indentation position here - don't do it if we're too close to right border */ if (xpos < view->width-5) indent_pos = xpos; - } else + } else if (cmd == LINE_COLOR_EXT) { + color &= ~ATTR_FGCOLOR24; + color = (color & BGATTR) | *ptr++; + } else if (cmd == LINE_COLOR_EXT_BG) { + color &= ~ATTR_BGCOLOR24; + color = (color & FGATTR) | (*ptr++ << BG_SHIFT); + } +#ifdef TERM_TRUECOLOR + else if (cmd == LINE_COLOR_24) + unformat_24bit_line_color(&ptr, 0, &color, &fg24, &bg24); +#endif + else update_cmd_color(cmd, &color); continue; } @@ -253,7 +278,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) sub = g_new0(LINE_CACHE_SUB_REC, 1); if (last_space > indent_pos && last_space > 10) { /* go back to last space */ - color = last_color; + color = last_color; fg24 = last_fg24; bg24 = last_bg24; ptr = last_space_ptr; while (*ptr == ' ') ptr++; } else if (view->longword_noindent) { @@ -266,6 +291,9 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) sub->indent = xpos; sub->indent_func = indent_func; sub->color = color; +#ifdef TERM_TRUECOLOR + sub->fg24 = fg24; sub->bg24 = bg24; +#endif lines = g_slist_append(lines, sub); linecount++; @@ -277,11 +305,11 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) if (!view->utf8 && char_width > 1) { last_space = xpos; last_space_ptr = next_ptr; - last_color = color; + last_color = color; last_fg24 = fg24; last_bg24 = bg24; } else if (*ptr == ' ') { last_space = xpos; last_space_ptr = ptr; - last_color = color; + last_color = color; last_fg24 = fg24; last_bg24 = bg24; } xpos += char_width; @@ -359,7 +387,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, const unsigned char *text, *end, *text_newline; unsigned char *tmp; unichar chr; - int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width; + int xpos, color, fg24, bg24, drawcount, first, need_move, need_clrtoeol, char_width; if (view->dirty) /* don't bother drawing anything - redraw is coming */ return 0; @@ -373,7 +401,6 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, xpos = drawcount = 0; first = TRUE; text_newline = text = subline == 0 ? line->text : cache->lines[subline-1].start; - g_message( "view_line_draw()\n"); for (;;) { if (text == text_newline) { if (need_clrtoeol && xpos < term_width) { @@ -395,6 +422,10 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, if (indent_func == NULL) xpos = cache->lines[subline-1].indent; color = cache->lines[subline-1].color; +#ifdef TERM_TRUECOLOR + fg24 = cache->lines[subline-1].fg24; + bg24 = cache->lines[subline-1].bg24; +#endif } else { indent_func = NULL; } @@ -412,12 +443,10 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, xpos = indent_func(view, line, ypos); } - if (need_move || xpos > 0) { + if (need_move || xpos > 0) term_move(view->window, xpos, ypos); - } - g_message( "view_line_draw(): color: 0x%08x\n", color); - term_set_color(view->window, color); + term_set_color2(view->window, color, fg24, bg24); if (subline == cache->count-1) { text_newline = NULL; @@ -443,11 +472,17 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, text = tmp; continue; } else { - update_cmd_color(*text, &color); - g_message( "post update_cmd_color: 0x%08x\n", - color); - - term_set_color(view->window, color); + if (*text == LINE_COLOR_EXT) + color = (color & BGATTR & ~ATTR_FGCOLOR24) | *++text; + else if (*text == LINE_COLOR_EXT_BG) + color = (color & FGATTR & ~ATTR_BGCOLOR24) | (*++text << BG_SHIFT); +#ifdef TERM_TRUECOLOR + else if (*text == LINE_COLOR_24) + unformat_24bit_line_color(&text, 1, &color, &fg24, &bg24); +#endif + else + update_cmd_color(*text, &color); + term_set_color2(view->window, color, fg24, bg24); } text++; continue; @@ -476,13 +511,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, term_addch(view->window, *text); } else { /* low-ascii */ - g_message( "printing inverse char %c\n", - (chr & 127)+'A'-1); term_set_color(view->window, ATTR_RESET|ATTR_REVERSE); term_addch(view->window, (chr & 127)+'A'-1); - g_message( "setting color back to: 0x%08x\n", - color); - term_set_color(view->window, color); + term_set_color2(view->window, color, fg24, bg24); } } text = end; |