| @@ -202,38 +202,62 @@ static cucul_canvas_t *import_text(void const *data, unsigned int size) | |||||
| #define IS_ALPHA(x) (x>='A' && x<='z') | #define IS_ALPHA(x) (x>='A' && x<='z') | ||||
| #define END_TUP 0x1337 | #define END_TUP 0x1337 | ||||
| unsigned char _get_ansi_command(unsigned char const *buffer, int size); | |||||
| int _parse_tuple(unsigned int *ret, unsigned char const *buffer, int size); | |||||
| void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int *bold); | |||||
| static int parse_tuple(unsigned int *, unsigned char const *, int); | |||||
| static void manage_modifiers(int, uint8_t *, uint8_t *, uint8_t *, uint8_t *, uint8_t *, uint8_t *); | |||||
| static cucul_canvas_t *import_ansi(void const *data, unsigned int size) | static cucul_canvas_t *import_ansi(void const *data, unsigned int size) | ||||
| { | { | ||||
| cucul_canvas_t *cv; | cucul_canvas_t *cv; | ||||
| unsigned char const *buffer = (unsigned char const*)data; | unsigned char const *buffer = (unsigned char const*)data; | ||||
| unsigned int i, sent_size = 0; | |||||
| unsigned char c; | |||||
| unsigned int i; | |||||
| unsigned int count = 0; | unsigned int count = 0; | ||||
| unsigned int tuple[1024]; /* Should be enough. Will it be ? */ | unsigned int tuple[1024]; /* Should be enough. Will it be ? */ | ||||
| int x = 0, y = 0, width = 80, height = 25; | |||||
| int x = 0, y = 0; | |||||
| unsigned int width = 80, height = 25; | |||||
| int save_x = 0, save_y = 0; | int save_x = 0, save_y = 0; | ||||
| unsigned int j, add = 0; | |||||
| int fg, bg, save_fg, save_bg, bold; | |||||
| unsigned int j, skip; | |||||
| uint8_t fg, bg, save_fg, save_bg, bold, reverse; | |||||
| fg = save_fg = CUCUL_COLOR_LIGHTGRAY; | fg = save_fg = CUCUL_COLOR_LIGHTGRAY; | ||||
| bg = save_bg = CUCUL_COLOR_BLACK; | bg = save_bg = CUCUL_COLOR_BLACK; | ||||
| bold = 0; | |||||
| bold = reverse = 0; | |||||
| cv = cucul_create_canvas(width, height); | cv = cucul_create_canvas(width, height); | ||||
| cucul_set_color(cv, fg, bg); | |||||
| for(i = 0; i < size; i++) | |||||
| for(i = 0; i < size; i += skip) | |||||
| { | { | ||||
| if((buffer[i] == 0x1b) && (buffer[i + 1] == '[')) /* ESC code */ | |||||
| skip = 1; | |||||
| if(buffer[i] == '\x1a' && size - i >= 8 | |||||
| && !memcmp(buffer + i + 1, "SAUCE00", 7)) | |||||
| break; /* End before SAUCE data */ | |||||
| if(buffer[i] == '\r') | |||||
| continue; /* DOS sucks */ | |||||
| if(buffer[i] == '\n') | |||||
| { | |||||
| x = 0; | |||||
| y++; | |||||
| continue; | |||||
| } | |||||
| if(buffer[i] == '\x1b' && buffer[i + 1] == '[') /* ESC code */ | |||||
| { | { | ||||
| unsigned char c = '\0'; | |||||
| i++; // ESC | i++; // ESC | ||||
| i++; // [ | i++; // [ | ||||
| sent_size = size - i; | |||||
| c = _get_ansi_command(&buffer[i], sent_size); | |||||
| add = _parse_tuple(tuple, &buffer[i], sent_size); | |||||
| for(j = i; j < size; j++) | |||||
| if(IS_ALPHA(buffer[j])) | |||||
| { | |||||
| c = buffer[j]; | |||||
| break; | |||||
| } | |||||
| skip += parse_tuple(tuple, buffer + i, size - i); | |||||
| count = 0; | count = 0; | ||||
| while(tuple[count] != END_TUP) | while(tuple[count] != END_TUP) | ||||
| @@ -243,16 +267,13 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) | |||||
| { | { | ||||
| case 'f': | case 'f': | ||||
| case 'H': | case 'H': | ||||
| if(tuple[0] != END_TUP) | |||||
| if(tuple[0] == END_TUP) | |||||
| x = y = 0; | |||||
| else | |||||
| { | { | ||||
| y = tuple[0] - 1; | y = tuple[0] - 1; | ||||
| x = tuple[1] == END_TUP ? 0 : tuple[1] - 1; | x = tuple[1] == END_TUP ? 0 : tuple[1] - 1; | ||||
| } | } | ||||
| else | |||||
| { | |||||
| y = 0; | |||||
| x = 0; | |||||
| } | |||||
| break; | break; | ||||
| case 'A': | case 'A': | ||||
| y -= tuple[0] == END_TUP ? 1 : tuple[0]; | y -= tuple[0] == END_TUP ? 1 : tuple[0]; | ||||
| @@ -280,60 +301,50 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) | |||||
| break; | break; | ||||
| case 'J': | case 'J': | ||||
| if(tuple[0] == 2) | if(tuple[0] == 2) | ||||
| { | |||||
| x = 0; | |||||
| y = 0; | |||||
| } | |||||
| x = y = 0; | |||||
| break; | break; | ||||
| case 'K': | case 'K': | ||||
| // CLEAR END OF LINE | // CLEAR END OF LINE | ||||
| for(j = x; j < width; j++) | |||||
| _cucul_putchar32(cv, j, y, (uint32_t)' '); | |||||
| x = width; | |||||
| break; | break; | ||||
| case 'm': | case 'm': | ||||
| for(j = 0; j < count; j++) | for(j = 0; j < count; j++) | ||||
| _manage_modifiers(tuple[j], &fg, &bg, &save_fg, &save_bg, &bold); | |||||
| manage_modifiers(tuple[j], &fg, &bg, &save_fg, &save_bg, &bold, &reverse); | |||||
| if(bold && fg < 8) | if(bold && fg < 8) | ||||
| fg += 8; | fg += 8; | ||||
| if(bold && bg < 8) | if(bold && bg < 8) | ||||
| bg += 8; | bg += 8; | ||||
| cucul_set_color(cv, fg, bg); | |||||
| if(reverse) | |||||
| cucul_set_color(cv, bg, fg); | |||||
| else | |||||
| cucul_set_color(cv, fg, bg); | |||||
| break; | break; | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| } | |||||
| else | |||||
| { | |||||
| if(buffer[i] == '\n') | |||||
| { | |||||
| x = 0; | |||||
| y++; | |||||
| } | |||||
| else if(buffer[i] == '\r') | |||||
| { | |||||
| // DOS sucks. | |||||
| } | |||||
| else | |||||
| { | |||||
| _cucul_putchar32(cv, x, y,_cucul_cp437_to_utf32(buffer[i])); | |||||
| x++; | |||||
| } | |||||
| continue; | |||||
| } | } | ||||
| if(x >= width || y >= height) | |||||
| /* We're going to paste a character. First make sure the canvas | |||||
| * is big enough. */ | |||||
| if(x >= width) | |||||
| { | { | ||||
| if(x >= width) | |||||
| width = x + 1; | |||||
| if(y >= height) | |||||
| height = y + 1; | |||||
| x = 0; | |||||
| y++; | |||||
| } | |||||
| if(y >= height) | |||||
| { | |||||
| height = y + 1; | |||||
| cucul_set_canvas_size(cv, width, height); | cucul_set_canvas_size(cv, width, height); | ||||
| } | } | ||||
| i += add; // add is tuple char count | |||||
| add = 0; | |||||
| /* Now paste our character */ | |||||
| _cucul_putchar32(cv, x, y,_cucul_cp437_to_utf32(buffer[i])); | |||||
| x++; | |||||
| } | } | ||||
| return cv; | return cv; | ||||
| @@ -341,18 +352,7 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) | |||||
| /* XXX : ANSI loader helpers */ | /* XXX : ANSI loader helpers */ | ||||
| unsigned char _get_ansi_command(unsigned char const *buffer, int size) | |||||
| { | |||||
| int i; | |||||
| for(i = 0; i < size; i++) | |||||
| if(IS_ALPHA(buffer[i])) | |||||
| return buffer[i]; | |||||
| return 0; | |||||
| } | |||||
| int _parse_tuple(unsigned int *ret, unsigned char const *buffer, int size) | |||||
| static int parse_tuple(unsigned int *ret, unsigned char const *buffer, int size) | |||||
| { | { | ||||
| int i = 0; | int i = 0; | ||||
| int j = 0; | int j = 0; | ||||
| @@ -392,9 +392,7 @@ int _parse_tuple(unsigned int *ret, unsigned char const *buffer, int size) | |||||
| return size; | return size; | ||||
| } | } | ||||
| void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int *bold) | |||||
| static void manage_modifiers(int i, uint8_t *fg, uint8_t *bg, uint8_t *save_fg, uint8_t *save_bg, uint8_t *bold, uint8_t *reverse) | |||||
| { | { | ||||
| static uint8_t const ansi2cucul[] = | static uint8_t const ansi2cucul[] = | ||||
| { | { | ||||
| @@ -410,12 +408,8 @@ void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int | |||||
| if(i >= 30 && i <= 37) | if(i >= 30 && i <= 37) | ||||
| *fg = ansi2cucul[i - 30]; | *fg = ansi2cucul[i - 30]; | ||||
| else if(i == 39) | |||||
| *fg = CUCUL_COLOR_DEFAULT; | |||||
| else if(i >= 40 && i <= 47) | else if(i >= 40 && i <= 47) | ||||
| *bg = ansi2cucul[i - 40]; | *bg = ansi2cucul[i - 40]; | ||||
| else if(i == 49) | |||||
| *bg = CUCUL_COLOR_DEFAULT; | |||||
| else if(i >= 90 && i <= 97) | else if(i >= 90 && i <= 97) | ||||
| *fg = ansi2cucul[i - 90] + 8; | *fg = ansi2cucul[i - 90] + 8; | ||||
| else if(i >= 100 && i <= 107) | else if(i >= 100 && i <= 107) | ||||
| @@ -426,6 +420,7 @@ void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int | |||||
| *fg = CUCUL_COLOR_DEFAULT; | *fg = CUCUL_COLOR_DEFAULT; | ||||
| *bg = CUCUL_COLOR_DEFAULT; | *bg = CUCUL_COLOR_DEFAULT; | ||||
| *bold = 0; | *bold = 0; | ||||
| *reverse = 0; | |||||
| break; | break; | ||||
| case 1: /* BOLD */ | case 1: /* BOLD */ | ||||
| *bold = 1; | *bold = 1; | ||||
| @@ -435,8 +430,7 @@ void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int | |||||
| case 5: // blink | case 5: // blink | ||||
| break; | break; | ||||
| case 7: // reverse | case 7: // reverse | ||||
| *fg = 15 - *fg; | |||||
| *bg = 15 - *bg; | |||||
| *reverse = 1; | |||||
| break; | break; | ||||
| case 8: // invisible | case 8: // invisible | ||||
| *save_fg = *fg; | *save_fg = *fg; | ||||
| @@ -448,6 +442,12 @@ void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int | |||||
| *fg = *save_fg; | *fg = *save_fg; | ||||
| *bg = *save_bg; | *bg = *save_bg; | ||||
| break; | break; | ||||
| case 39: | |||||
| *fg = CUCUL_COLOR_DEFAULT; | |||||
| break; | |||||
| case 49: | |||||
| *bg = CUCUL_COLOR_DEFAULT; | |||||
| break; | |||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||