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:
parent
6c7fbaeeaa
commit
17f82a3e21
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user