| @@ -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", | |||||
| // final - param + 1, buffer + i + param); | |||||
| fprintf(stderr, "private sequence \"^[[%.*s\"\n", | |||||
| 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++) | |||||
| 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; | 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 */ | |||||
| 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); | |||||
| } | } | ||||