Changeset 871 for libcaca


Ignore:
Timestamp:
Apr 25, 2006, 12:14:12 PM (15 years ago)
Author:
Jean-Yves Lamoureux
Message:
  • Added preliminary ANSI importer, added import formats autodection
Location:
libcaca/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/cucul/import.c

    r859 r871  
    3030static cucul_canvas_t *import_caca(void const *, unsigned int);
    3131static cucul_canvas_t *import_text(void const *, unsigned int);
     32static cucul_canvas_t *import_ansi(void const *, unsigned int);
    3233
    3334/** \brief Import a buffer into a canvas
     
    4950                                     char const *format)
    5051{
     52    char const *buf = (char const*) data;
     53
     54    if(size==0 || data==NULL)
     55        return NULL;
     56
    5157    if(!strcasecmp("caca", format))
    5258        return import_caca(data, size);
    5359    if(!strcasecmp("text", format))
    5460        return import_text(data, size);
    55 
    56     /* FIXME: Try to autodetect */
     61    if(!strcasecmp("ansi", format))
     62        return import_ansi(data, size);
     63
    5764    if(!strcasecmp("", format))
    58         return import_caca(data, size);
    59 
     65    {
     66        /* Autodetection */
     67        if(size>=4) /* if 4 first letters are CACA */
     68        {
     69            if(buf[0] == 'C' && buf[1] == 'A' && buf[2] == 'C' && buf[3] != 'A')
     70               return import_caca(data, size);
     71        }
     72        if(size>=2) /* If 2 first characters are ESC[ (not reliable at all) */
     73        {
     74            if((buf[0] == 0x1b) && (buf[1] == '['))
     75               return import_ansi(data, size);
     76        }
     77        /* Otherwise, import it as text */
     78        return import_caca(data, size);
     79    }
    6080    return NULL;
    6181}
     
    7797        "text", "plain text",
    7898        "caca", "native libcaca format",
     99        "ansi", "ANSI coloured text",
    79100        NULL, NULL
    80101    };
     
    175196}
    176197
     198#define IS_ALPHA(x) (x>='A' && x<='z')
     199void updateCanvasSize(cucul_canvas_t *cv, int x, int y, int *max_x, int *max_y);
     200unsigned char get_ansi_command(unsigned char const *buffer, int size);
     201int parse_tuple(unsigned int *ret, unsigned char const *buffer, int size);
     202void manage_modifiers(char c, int *fg, int *bg, int *old_fg, int *old_bg);
     203
     204static cucul_canvas_t *import_ansi(void const *data, unsigned int size)
     205{
     206    cucul_canvas_t *cv;
     207    unsigned char const *buffer = (unsigned char const*)data;
     208    unsigned int i, sent_size=0;
     209    unsigned char c;
     210    unsigned int count=0;
     211    unsigned int tuple[1024]; /* Should be enough. Will it be ? */
     212    int x=0, y=0, max_x = 80, max_y = 25;
     213    int save_x=0, save_y=0;
     214    unsigned int j, add=0;
     215    int fg, bg, old_fg, old_bg;
     216
     217    fg = old_fg = CUCUL_COLOR_LIGHTGRAY;
     218    bg = old_bg = CUCUL_COLOR_BLACK;
     219
     220    cv = cucul_create_canvas(max_x, max_y);
     221
     222    for(i = 0 ;i < size; i++)
     223        {
     224            if((buffer[i] == 0x1b) && (buffer[i+1] == '['))  /* ESC code */
     225                {
     226                    i++; // ESC
     227                    i++; // [
     228                    sent_size = size-i;
     229                    c = get_ansi_command(&buffer[i], sent_size);
     230                    add = parse_tuple(tuple, &buffer[i], sent_size);
     231                    count = 0;
     232
     233                    while(tuple[count] != 0x1337)  count++;  /* Gruik */
     234
     235
     236                    switch(c)
     237                        {
     238                        case 'f':
     239                        case 'H':
     240                            if(tuple[0] != 0x1337)
     241                                {
     242                                    x=tuple[0];
     243                                    if(tuple[1] != 0x1337)
     244                                        y=tuple[1];
     245                                }
     246                            else
     247                                {
     248                                    x = 0;
     249                                    y = 0;
     250                                }
     251                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     252                            break;
     253                        case 'A':
     254                            if(tuple[0] == 0x1337)
     255                                y-=1;
     256                            else
     257                                y-=tuple[0];
     258                            if(y<0) y=0;
     259                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     260                            break;
     261                        case 'B':
     262                            if(tuple[0] == 0x1337)
     263                                y++;
     264                            else
     265                                y+=tuple[0];
     266                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     267                            break;
     268                        case 'C':
     269                            if(tuple[0] == 0x1337)
     270                                x++;
     271                            else
     272                                x+=tuple[0];
     273                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     274                            break;
     275                        case 'D':
     276                            if(tuple[0] == 0x1337)
     277                                x--;
     278                            else
     279                                x-=tuple[0];
     280                            if(x<0) x=0;
     281                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     282                            break;
     283                        case 's':
     284                            save_x = x;
     285                            save_y = y;
     286                            break;
     287                        case 'u':
     288                            x = save_x;
     289                            y = save_y;
     290                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     291                            break;
     292                        case 'J':
     293                            if(tuple[0] == 2)
     294                                {
     295                                    x = 0;
     296                                    y = 0;
     297                                    updateCanvasSize(cv, x, y, &max_x, &max_y);
     298                                }
     299                            break;
     300                        case 'K':
     301                            // CLEAR END OF LINE
     302                            break;
     303                        case 'm':
     304                            for(j=0; j < count; j++)
     305                                manage_modifiers(tuple[j], &fg, &bg, &old_fg, &old_bg);
     306                            cucul_set_color(cv, fg, bg);
     307                            break;
     308                        default:
     309                            /*printf("Unknow command %c (%c)\n", c, IS_ALPHA(c)?c:'.');*/
     310                            break;
     311                        }
     312
     313
     314                } else {
     315                    if(buffer[i] == '\n')
     316                        {
     317                            x = 0;
     318                            y++;
     319                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     320                        }
     321                    else if(buffer[i] == '\r')
     322                        {
     323                            // DOS sucks.
     324                        }
     325                    else
     326                        {
     327                            if((buffer[i]>=0x20) || (buffer[i]<=0x7E))
     328                                {
     329                                    _cucul_putchar32(cv, x, y,_cucul_cp437_to_utf32(buffer[i]));
     330
     331                                    //  cucul_putchar(cv, x, y, buffer[i]);
     332                                }
     333                            else
     334                                cucul_putchar(cv, x, y, '?');
     335                            x++;
     336                            updateCanvasSize(cv, x, y, &max_x, &max_y);
     337                        }
     338                }
     339
     340
     341
     342            i+=add; // add is tuple char count, then +[ +command
     343            add = 0;
     344
     345        }
     346    return cv;
     347}
     348
     349/* XXX : ANSI loader helpers */
     350
     351unsigned char get_ansi_command(unsigned char const *buffer, int size)
     352{
     353    int i = 0;
     354
     355    for(i=0; i < size; i++)
     356        if(IS_ALPHA(buffer[i]))
     357            return buffer[i];
     358
     359    return 0;
     360}
     361
     362int parse_tuple(unsigned int *ret, unsigned char const *buffer, int size)
     363{
     364    int i = 0;
     365    int j = 0;
     366    int t = 0;
     367    unsigned char nbr[1024];
     368
     369
     370    ret[0] = 0x1337;
     371
     372    for(i=0; i < size; i++)
     373        {
     374            if(IS_ALPHA(buffer[i]))
     375                {
     376                    if(j!=0) {
     377                        ret[t] = atoi((char*)nbr);
     378                        t++;
     379                    }
     380                    ret[t] = 0x1337;
     381                    j=0;
     382                    return i;
     383                }
     384            if(buffer[i] != ';')
     385                {
     386                    nbr[j] = buffer[i];
     387                    nbr[j+1] = 0;
     388                    j++;
     389                } else
     390                    {
     391                        ret[t] = atoi((char*)nbr);
     392                        t++;
     393                        ret[t] = 0x1337;
     394                        j=0;
     395                    }
     396        }
     397    return size;
     398}
     399
     400
     401
     402void manage_modifiers(char c, int *fg, int *bg, int *old_fg, int *old_bg)
     403{
     404    switch(c) {
     405    case 0:
     406        *fg = CUCUL_COLOR_LIGHTGRAY;
     407        *bg = CUCUL_COLOR_BLACK;
     408        break;
     409    case 1: // BOLD
     410
     411        break;
     412    case 4: // Underline
     413
     414        break;
     415    case 5: // blink
     416
     417        break;
     418    case 7: // reverse
     419        *fg = 15-*fg;
     420        *bg = 15-*bg;
     421        break;
     422    case 8: // invisible
     423        *old_fg = *fg;
     424        *old_bg = *bg;
     425        *fg = CUCUL_COLOR_TRANSPARENT;
     426        *bg = CUCUL_COLOR_TRANSPARENT;
     427        break;
     428    case 28: // not invisible
     429        *fg = *old_fg;
     430        *bg = *old_bg;
     431        break;
     432    case 30:
     433        *fg = CUCUL_COLOR_BLACK;
     434        break;
     435    case 31:
     436        *fg = CUCUL_COLOR_RED;
     437        break;
     438    case 32:
     439        *fg = CUCUL_COLOR_GREEN;
     440        break;
     441    case 33:
     442        *fg = CUCUL_COLOR_BROWN;
     443        break;
     444    case 34:
     445        *fg = CUCUL_COLOR_BLUE;
     446        break;
     447    case 35:
     448        *fg = CUCUL_COLOR_MAGENTA;
     449        break;
     450    case 36:
     451        *fg = CUCUL_COLOR_CYAN;
     452        break;
     453    case 37:
     454        *fg = CUCUL_COLOR_WHITE;
     455        break;
     456    case 39:
     457        *fg = CUCUL_COLOR_LIGHTGRAY;
     458        break;
     459    case 40:
     460        *bg = CUCUL_COLOR_BLACK;
     461        break;
     462    case 41:
     463        *bg = CUCUL_COLOR_RED;
     464        break;
     465    case 42:
     466        *bg = CUCUL_COLOR_GREEN;
     467        break;
     468    case 43:
     469        *bg = CUCUL_COLOR_BROWN;
     470        break;
     471    case 44:
     472        *bg = CUCUL_COLOR_BLUE;
     473        break;
     474    case 45:
     475        *bg = CUCUL_COLOR_MAGENTA;
     476        break;
     477    case 46:
     478        *bg = CUCUL_COLOR_CYAN;
     479        break;
     480    case 47:
     481        *bg = CUCUL_COLOR_WHITE;
     482        break;
     483    case 49:
     484        *bg = CUCUL_COLOR_BLACK;
     485        break;
     486
     487    case 90:
     488        *fg = CUCUL_COLOR_DARKGRAY;
     489        break;
     490    case 91:
     491        *fg = CUCUL_COLOR_LIGHTRED;
     492        break;
     493    case 92:
     494        *fg = CUCUL_COLOR_LIGHTGREEN;
     495        break;
     496    case 93:
     497        *fg = CUCUL_COLOR_YELLOW;
     498        break;
     499    case 94:
     500        *fg = CUCUL_COLOR_LIGHTBLUE;
     501        break;
     502    case 95:
     503        *fg = CUCUL_COLOR_LIGHTMAGENTA;
     504        break;
     505    case 96:
     506        *fg = CUCUL_COLOR_LIGHTCYAN;
     507        break;
     508    case 97:
     509        *fg = CUCUL_COLOR_WHITE;
     510        break;
     511    case 100:
     512        *bg = CUCUL_COLOR_DARKGRAY;
     513        break;
     514    case 101:
     515        *bg = CUCUL_COLOR_LIGHTRED;
     516        break;
     517    case 102:
     518        *bg = CUCUL_COLOR_LIGHTGREEN;
     519        break;
     520    case 103:
     521        *bg = CUCUL_COLOR_YELLOW;
     522        break;
     523    case 104:
     524        *bg = CUCUL_COLOR_LIGHTBLUE;
     525        break;
     526    case 105:
     527        *bg = CUCUL_COLOR_LIGHTMAGENTA;
     528        break;
     529    case 106:
     530        *bg = CUCUL_COLOR_LIGHTCYAN;
     531        break;
     532    case 107:
     533        *bg = CUCUL_COLOR_WHITE;
     534        break;
     535    default:
     536        /*   printf("Unknow option to 'm' %d (%c)\n", c, IS_ALPHA(c)?c:'.'); */
     537        break;
     538
     539    }
     540}
     541
     542
     543void updateCanvasSize(cucul_canvas_t *cv, int x, int y, int *max_x, int *max_y)
     544{
     545    if(x>*max_x) *max_x = x;
     546    if(y>*max_y) *max_y = y;
     547
     548    cucul_set_canvas_size(cv, *max_x, *max_y);
     549}
  • libcaca/trunk/test/Makefile.am

    r851 r871  
    33AM_CPPFLAGS = -I$(top_srcdir)/cucul -I$(top_srcdir)/caca -DDATADIR=\"$(pkgdatadir)\"
    44
    5 noinst_PROGRAMS = colors demo dithering event export font frames gamma hsv spritedit text transform truecolor unicode
     5noinst_PROGRAMS = colors demo dithering event export font frames gamma hsv spritedit text transform truecolor unicode import
    66
    77colors_SOURCES = colors.c
     
    4747unicode_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@
    4848
     49import_SOURCES = import.c
     50import_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@
Note: See TracChangeset for help on using the changeset viewer.