1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

Decode ESC color sequences in the plain renderer.

Added functions for screen_char->color -> color_T conversion.
This commit is contained in:
Witold Filipczyk 2010-07-31 20:51:24 +02:00 committed by Witold Filipczyk
parent 6c7fbaeeaa
commit 17f82a3e21
3 changed files with 189 additions and 2 deletions

View File

@ -5,6 +5,7 @@
#endif
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
@ -227,6 +228,87 @@ print_document_link(struct plain_renderer *renderer, int lineno,
return len;
}
static void
decode_esc_color(unsigned char *text, int *line_pos, int width,
struct screen_char *template, enum color_mode mode,
int *was_reversed)
{
struct screen_char ch;
struct color_pair color;
char *buf, *tail, *begin, *end;
int k, foreground, background, f1, b1; /* , intensity; */
++(*line_pos);
buf = (char *)&text[*line_pos];
if (*buf != '[') return;
++buf;
++(*line_pos);
k = strspn(buf, "0123456789;");
*line_pos += k;
if (!k || buf[k] != 'm') return;
end = buf + k;
begin = tail = buf;
get_screen_char_color(template, &color, 0, mode);
set_term_color(&ch, &color, 0, COLOR_MODE_16);
b1 = background = (ch.color[0] >> 4) & 7;
f1 = foreground = ch.color[0] & 7;
while (tail < end) {
unsigned char kod = (unsigned char)strtol(begin, &tail, 10);
begin = tail + 1;
switch (kod) {
case 0:
background = 0;
foreground = 7;
break;
case 7:
if (*was_reversed == 0) {
background = f1 & 7;
foreground = b1;
*was_reversed = 1;
}
break;
case 27:
if (*was_reversed == 1) {
background = f1 & 7;
foreground = b1;
*was_reversed = 0;
}
break;
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
foreground = kod - 30;
break;
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
background = kod - 40;
break;
default:
break;
}
}
color.background = get_term_color16(background);
color.foreground = get_term_color16(foreground);
set_term_color(template, &color, 0, mode);
}
static inline int
add_document_line(struct plain_renderer *renderer,
unsigned char *line, int line_width)
@ -235,8 +317,11 @@ add_document_line(struct plain_renderer *renderer,
struct screen_char *template = &renderer->template;
struct screen_char saved_renderer_template = *template;
struct screen_char *pos, *startpos;
struct document_options *doc_opts = &document->options;
int was_reversed = 0;
#ifdef CONFIG_UTF8
int utf8 = document->options.utf8;
int utf8 = doc_opts->utf8;
#endif /* CONFIG_UTF8 */
int cells = 0;
int lineno = renderer->lineno;
@ -411,6 +496,11 @@ add_document_line(struct plain_renderer *renderer,
/* Handle _^Hx^Hx as both bold and underlined */
if (template->attr)
template->attr |= pos->attr;
} else if (line_char == 27) {
decode_esc_color(line, &line_pos, width,
&saved_renderer_template,
doc_opts->color_mode, &was_reversed);
*template = saved_renderer_template;
} else {
int added_chars = 0;

View File

@ -288,6 +288,92 @@ set_term_color16(struct screen_char *schar, enum color_flags flags,
schar->color[0] = (bg << 4 | fg);
}
color_T
get_term_color16(unsigned int index)
{
if (index > 15) return 0;
return ((palette16[index].r << 16) |
(palette16[index].g << 8) |
palette16[index].b);
}
#ifdef CONFIG_88_COLORS
color_T
get_term_color88(unsigned int index)
{
if (index > 87) return 0;
return ((palette88[index].r << 16) |
(palette88[index].g << 8) |
palette88[index].b);
}
#endif
#ifdef CONFIG_256_COLORS
color_T
get_term_color256(unsigned int index)
{
if (index > 255) return 0;
return ((palette256[index].r << 16) |
(palette256[index].g << 8) |
palette256[index].b);
}
#endif
void
get_screen_char_color(struct screen_char *schar, struct color_pair *pair,
enum color_flags flags, enum color_mode color_mode)
{
unsigned char fg, bg;
assert(color_mode >= COLOR_MODE_DUMP && color_mode < COLOR_MODES);
/* Options for the various color modes. */
switch (color_mode) {
case COLOR_MODE_MONO:
break;
default:
/* If the desired color mode was not compiled in,
* use 16 colors. */
case COLOR_MODE_16:
bg = (schar->color[0] >> 4) & 7;
fg = schar->color[0];
pair->foreground = get_term_color16(fg);
pair->background = get_term_color16(bg);
break;
#ifdef CONFIG_88_COLORS
case COLOR_MODE_88:
pair->foreground = get_term_color88(schar->color[0]);
pair->background = get_term_color88(schar->color[1]);
break;
#endif
#ifdef CONFIG_256_COLORS
case COLOR_MODE_256:
pair->foreground = get_term_color256(schar->color[0]);
pair->background = get_term_color256(schar->color[1]);
break;
#endif
#ifdef CONFIG_TRUE_COLOR
case COLOR_MODE_TRUE_COLOR:
pair->foreground = ((schar->color[0] << 16)
| (schar->color[1] << 8)
| schar->color[2]);
pair->background = ((schar->color[3] << 16)
| (schar->color[4] << 8)
| schar->color[5]);
break;
#endif
case COLOR_MODE_DUMP:
break;
case COLOR_MODES:
/* This is caught by the assert() above. */
break;
}
}
void
set_term_color(struct screen_char *schar, struct color_pair *pair,
enum color_flags flags, enum color_mode color_mode)

View File

@ -1,7 +1,7 @@
#ifndef EL__TERMINAL_COLOR_H
#define EL__TERMINAL_COLOR_H
struct color_pair;
#include "util/color.h"
struct screen_char;
/* Terminal color encoding: */
@ -72,6 +72,17 @@ void set_term_color16(struct screen_char *schar, enum color_flags flags,
*
* XXX: @a schar may not be NULL and is modified adding stuff like
* boldness. */
color_T get_term_color16(unsigned int index);
#ifdef CONFIG_88_COLORS
color_T get_term_color88(unsigned int index);
#endif
#ifdef CONFIG_256_COLORS
color_T get_term_color256(unsigned int index);
#endif
void get_screen_char_color(struct screen_char *schar, struct color_pair *pair,
enum color_flags flags, enum color_mode color_mode);
void set_term_color(struct screen_char *schar, struct color_pair *pair,
enum color_flags flags, enum color_mode mode);