From d82754532be279d9b6d1f688c7255c880386784a Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 26 Apr 2006 17:02:37 +0000 Subject: [PATCH] * Fixed an ANSI rendering bug related to the bold attribute. --- cucul/import.c | 161 +++++++++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 72 deletions(-) diff --git a/cucul/import.c b/cucul/import.c index 2a7ef72..102cf0d 100644 --- a/cucul/import.c +++ b/cucul/import.c @@ -27,10 +27,20 @@ #include "cucul.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_text(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 * * 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; } -/* 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) { - struct grcm grcm; + struct ansi_grcm grcm; unsigned char const *buffer = (unsigned char const*)data; cucul_canvas_t *cv; - unsigned int i, j, skip; + unsigned int i, j, skip, dummy = 0; unsigned int width = 80, height = 25; int x = 0, y = 0, save_x = 0, save_y = 0; - manage_modifiers(&grcm, 0); - 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) { @@ -276,8 +275,8 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) /* Sanity checks */ if(param < inter && buffer[i + param] >= 0x3c) { - //fprintf(stderr, "private sequence \"^[[%.*s\"\n", - // final - param + 1, buffer + i + param); + fprintf(stderr, "private sequence \"^[[%.*s\"\n", + final - param + 1, buffer + i + param); continue; /* Private sequence, skip it entirely */ } @@ -343,19 +342,10 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) x = width; break; case 'm': /* SGR - Select Graphic Rendition */ - for(j = 0; j < argc; j++) - 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); + ansi_parse_grcm(cv, &grcm, argc, argv); break; default: + fprintf(stderr, "unknown command %c\n", buffer[i + final]); break; } @@ -377,7 +367,7 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) } /* 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++; } @@ -386,7 +376,8 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) /* 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[] = { @@ -396,50 +387,76 @@ static void manage_modifiers(struct grcm *g, int i) CUCUL_COLOR_CYAN, CUCUL_COLOR_LIGHTGRAY }; - /* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */ - if(i >= 30 && i <= 37) - g->fg = ansi2cucul[i - 30]; - else if(i >= 40 && i <= 47) - g->bg = ansi2cucul[i - 40]; - else if(i >= 90 && i <= 97) - g->fg = ansi2cucul[i - 90] + 8; - else if(i >= 100 && i <= 107) - g->bg = ansi2cucul[i - 100] + 8; - else switch(i) + unsigned int j; + uint8_t myfg, mybg; + + for(j = 0; j < argc; j++) + { + /* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */ + if(argv[j] >= 30 && argv[j] <= 37) + g->fg = ansi2cucul[argv[j] - 30]; + else if(argv[j] >= 40 && argv[j] <= 47) + g->bg = ansi2cucul[argv[j] - 40]; + 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 */ - 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; + myfg = mybg = CUCUL_COLOR_TRANSPARENT; } + 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); }