Ver código fonte

* Fixed an ANSI rendering bug related to the bold attribute.

tags/v0.99.beta14
Sam Hocevar sam 19 anos atrás
pai
commit
d82754532b
1 arquivos alterados com 89 adições e 72 exclusões
  1. +89
    -72
      cucul/import.c

+ 89
- 72
cucul/import.c Ver arquivo

@@ -27,10 +27,20 @@
#include "cucul.h" #include "cucul.h"
#include "cucul_internals.h" #include "cucul_internals.h"


/* ANSI Graphic Rendition Combination Mode */
struct ansi_grcm
{
uint8_t fg, bg;
uint8_t bold, negative, concealed;
};

static cucul_canvas_t *import_caca(void const *, unsigned int); static cucul_canvas_t *import_caca(void const *, unsigned int);
static cucul_canvas_t *import_text(void const *, unsigned int); static cucul_canvas_t *import_text(void const *, unsigned int);
static cucul_canvas_t *import_ansi(void const *, unsigned int); static cucul_canvas_t *import_ansi(void const *, unsigned int);


static void ansi_parse_grcm(cucul_canvas_t *, struct ansi_grcm *,
unsigned int, unsigned int const *);

/** \brief Import a buffer into a canvas /** \brief Import a buffer into a canvas
* *
* This function imports a libcucul buffer (cucul_load_memory()/cucul_load_file()) * This function imports a libcucul buffer (cucul_load_memory()/cucul_load_file())
@@ -200,28 +210,17 @@ static cucul_canvas_t *import_text(void const *data, unsigned int size)
return cv; return cv;
} }


/* Graphic Rendition Combination Mode */
struct grcm
{
uint8_t fg, bg;
uint8_t bold, negative, concealed;
};

static void manage_modifiers(struct grcm *, int);

static cucul_canvas_t *import_ansi(void const *data, unsigned int size) static cucul_canvas_t *import_ansi(void const *data, unsigned int size)
{ {
struct grcm grcm; struct ansi_grcm grcm;
unsigned char const *buffer = (unsigned char const*)data; unsigned char const *buffer = (unsigned char const*)data;
cucul_canvas_t *cv; cucul_canvas_t *cv;
unsigned int i, j, skip; unsigned int i, j, skip, dummy = 0;
unsigned int width = 80, height = 25; unsigned int width = 80, height = 25;
int x = 0, y = 0, save_x = 0, save_y = 0; int x = 0, y = 0, save_x = 0, save_y = 0;


manage_modifiers(&grcm, 0);

cv = cucul_create_canvas(width, height); cv = cucul_create_canvas(width, height);
cucul_set_color(cv, CUCUL_COLOR_DEFAULT, CUCUL_COLOR_DEFAULT); ansi_parse_grcm(cv, &grcm, 1, &dummy);


for(i = 0; i < size; i += skip) for(i = 0; i < size; i += skip)
{ {
@@ -276,8 +275,8 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size)
/* Sanity checks */ /* Sanity checks */
if(param < inter && buffer[i + param] >= 0x3c) if(param < inter && buffer[i + param] >= 0x3c)
{ {
//fprintf(stderr, "private sequence \"^[[%.*s\"\n", fprintf(stderr, "private sequence \"^[[%.*s\"\n",
// final - param + 1, buffer + i + param); final - param + 1, buffer + i + param);
continue; /* Private sequence, skip it entirely */ continue; /* Private sequence, skip it entirely */
} }


@@ -343,19 +342,10 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size)
x = width; x = width;
break; break;
case 'm': /* SGR - Select Graphic Rendition */ case 'm': /* SGR - Select Graphic Rendition */
for(j = 0; j < argc; j++) ansi_parse_grcm(cv, &grcm, argc, argv);
manage_modifiers(&grcm, argv[j]);
if(grcm.concealed)
cucul_set_color(cv, CUCUL_COLOR_TRANSPARENT,
CUCUL_COLOR_TRANSPARENT);
else if(grcm.negative)
cucul_set_color(cv, (grcm.bold && grcm.bg < 8) ?
grcm.bg + 8 : grcm.bg, grcm.fg);
else
cucul_set_color(cv, (grcm.bold && grcm.fg < 8) ?
grcm.fg + 8 : grcm.fg, grcm.bg);
break; break;
default: default:
fprintf(stderr, "unknown command %c\n", buffer[i + final]);
break; break;
} }


@@ -377,7 +367,7 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size)
} }


/* Now paste our character */ /* Now paste our character */
_cucul_putchar32(cv, x, y,_cucul_cp437_to_utf32(buffer[i])); _cucul_putchar32(cv, x, y, _cucul_cp437_to_utf32(buffer[i]));
x++; x++;
} }


@@ -386,7 +376,8 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size)


/* XXX : ANSI loader helper */ /* XXX : ANSI loader helper */


static void manage_modifiers(struct grcm *g, int i) static void ansi_parse_grcm(cucul_canvas_t *cv, struct ansi_grcm *g,
unsigned int argc, unsigned int const *argv)
{ {
static uint8_t const ansi2cucul[] = static uint8_t const ansi2cucul[] =
{ {
@@ -396,50 +387,76 @@ static void manage_modifiers(struct grcm *g, int i)
CUCUL_COLOR_CYAN, CUCUL_COLOR_LIGHTGRAY CUCUL_COLOR_CYAN, CUCUL_COLOR_LIGHTGRAY
}; };


/* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */ unsigned int j;
if(i >= 30 && i <= 37) uint8_t myfg, mybg;
g->fg = ansi2cucul[i - 30]; for(j = 0; j < argc; j++)
else if(i >= 40 && i <= 47) {
g->bg = ansi2cucul[i - 40]; /* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */
else if(i >= 90 && i <= 97) if(argv[j] >= 30 && argv[j] <= 37)
g->fg = ansi2cucul[i - 90] + 8; g->fg = ansi2cucul[argv[j] - 30];
else if(i >= 100 && i <= 107) else if(argv[j] >= 40 && argv[j] <= 47)
g->bg = ansi2cucul[i - 100] + 8; g->bg = ansi2cucul[argv[j] - 40];
else switch(i) else if(argv[j] >= 90 && argv[j] <= 97)
g->fg = ansi2cucul[argv[j] - 90] + 8;
else if(argv[j] >= 100 && argv[j] <= 107)
g->bg = ansi2cucul[argv[j] - 100] + 8;
else switch(argv[j])
{
case 0: /* default rendition */
g->fg = CUCUL_COLOR_DEFAULT;
g->bg = CUCUL_COLOR_DEFAULT;
g->bold = g->negative = g->concealed = 0;
break;
case 1: /* bold or increased intensity */
g->bold = 1;
break;
case 4: /* singly underlined */
break;
case 5: /* slowly blinking (less then 150 per minute) */
break;
case 7: /* negative image */
g->negative = 1;
break;
case 8: /* concealed characters */
g->concealed = 1;
break;
case 22: /* normal colour or normal intensity (neither bold nor faint) */
g->bold = 0;
break;
case 28: /* revealed characters */
g->concealed = 0;
break;
case 39: /* default display colour (implementation-defined) */
g->fg = CUCUL_COLOR_DEFAULT;
break;
case 49: /* default background colour (implementation-defined) */
g->bg = CUCUL_COLOR_DEFAULT;
break;
default:
fprintf(stderr, "unknown sgr %i\n", argv[j]);
break;
}
}

if(g->concealed)
{ {
case 0: /* default rendition */ myfg = mybg = CUCUL_COLOR_TRANSPARENT;
g->fg = CUCUL_COLOR_DEFAULT;
g->bg = CUCUL_COLOR_DEFAULT;
g->bold = g->negative = g->concealed = 0;
break;
case 1: /* bold or increased intensity */
g->bold = 1;
break;
case 4: /* singly underlined */
break;
case 5: /* slowly blinking (less then 150 per minute) */
break;
case 7: /* negative image */
g->negative = 1;
break;
case 8: /* concealed characters */
g->concealed = 1;
break;
case 22: /* normal colour or normal intensity (neither bold nor faint) */
g->bold = 0;
break;
case 28: /* revealed characters */
g->concealed = 0;
break;
case 39: /* default display colour (implementation-defined) */
g->fg = CUCUL_COLOR_DEFAULT;
break;
case 49: /* default background colour (implementation-defined) */
g->bg = CUCUL_COLOR_DEFAULT;
break;
default:
//fprintf(stderr, "unknown sgr %i\n", i);
break;
} }
else
{
myfg = g->negative ? g->bg : g->fg;
mybg = g->negative ? g->fg : g->bg;

if(g->bold)
{
if(myfg < 8)
myfg += 8;
else if(myfg == CUCUL_COLOR_DEFAULT)
myfg = CUCUL_COLOR_WHITE;
}
}

cucul_set_color(cv, myfg, mybg);
} }



||||||
x
 
000:0
Carregando…
Cancelar
Salvar