Ignore:
Timestamp:
Apr 26, 2006, 9:57:26 AM (15 years ago)
Author:
Sam Hocevar
Message:
  • More cleaning up of the ANSI loader. Fixed reverse video.
File:
1 edited

Legend:

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

    r884 r886  
    203203#define IS_ALPHA(x) (x>='A' && x<='z')
    204204#define END_TUP 0x1337
    205 unsigned char _get_ansi_command(unsigned char const *buffer, int size);
    206 int _parse_tuple(unsigned int *ret, unsigned char const *buffer, int size);
    207 void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int *bold);
     205static int parse_tuple(unsigned int *, unsigned char const *, int);
     206static void manage_modifiers(int, uint8_t *, uint8_t *, uint8_t *, uint8_t *, uint8_t *, uint8_t *);
    208207
    209208static cucul_canvas_t *import_ansi(void const *data, unsigned int size)
     
    211210    cucul_canvas_t *cv;
    212211    unsigned char const *buffer = (unsigned char const*)data;
    213     unsigned int i, sent_size = 0;
    214     unsigned char c;
     212    unsigned int i;
    215213    unsigned int count = 0;
    216214    unsigned int tuple[1024]; /* Should be enough. Will it be ? */
    217     int x = 0, y = 0, width = 80, height = 25;
     215    int x = 0, y = 0;
     216    unsigned int width = 80, height = 25;
    218217    int save_x = 0, save_y = 0;
    219     unsigned int j, add = 0;
    220     int fg, bg, save_fg, save_bg, bold;
     218    unsigned int j, skip;
     219    uint8_t fg, bg, save_fg, save_bg, bold, reverse;
    221220
    222221    fg = save_fg = CUCUL_COLOR_LIGHTGRAY;
    223222    bg = save_bg = CUCUL_COLOR_BLACK;
    224     bold = 0;
     223    bold = reverse = 0;
    225224
    226225    cv = cucul_create_canvas(width, height);
    227 
    228     for(i = 0; i < size; i++)
    229     {
    230         if((buffer[i] == 0x1b) && (buffer[i + 1] == '['))  /* ESC code */
    231         {
     226    cucul_set_color(cv, fg, bg);
     227
     228    for(i = 0; i < size; i += skip)
     229    {
     230        skip = 1;
     231
     232        if(buffer[i] == '\x1a' && size - i >= 8
     233           && !memcmp(buffer + i + 1, "SAUCE00", 7))
     234            break; /* End before SAUCE data */
     235
     236        if(buffer[i] == '\r')
     237            continue; /* DOS sucks */
     238
     239        if(buffer[i] == '\n')
     240        {
     241            x = 0;
     242            y++;
     243            continue;
     244        }
     245
     246        if(buffer[i] == '\x1b' && buffer[i + 1] == '[')  /* ESC code */
     247        {
     248            unsigned char c = '\0';
     249
    232250            i++; // ESC
    233251            i++; // [
    234             sent_size = size - i;
    235             c = _get_ansi_command(&buffer[i], sent_size);
    236             add = _parse_tuple(tuple, &buffer[i], sent_size);
     252
     253            for(j = i; j < size; j++)
     254                if(IS_ALPHA(buffer[j]))
     255                {
     256                    c = buffer[j];
     257                    break;
     258                }
     259
     260            skip += parse_tuple(tuple, buffer + i, size - i);
    237261            count = 0;
    238262
     
    244268            case 'f':
    245269            case 'H':
    246                 if(tuple[0] != END_TUP)
     270                if(tuple[0] == END_TUP)
     271                    x = y = 0;
     272                else
    247273                {
    248274                    y = tuple[0] - 1;
    249275                    x = tuple[1] == END_TUP ? 0 : tuple[1] - 1;
    250276                }
    251                 else
    252                 {
    253                     y = 0;
    254                     x = 0;
    255                 }
    256277                break;
    257278            case 'A':
     
    281302            case 'J':
    282303                if(tuple[0] == 2)
    283                 {
    284                     x = 0;
    285                     y = 0;
    286                 }
     304                    x = y = 0;
    287305                break;
    288306            case 'K':
    289307                // CLEAR END OF LINE
     308                for(j = x; j < width; j++)
     309                    _cucul_putchar32(cv, j, y, (uint32_t)' ');
     310                x = width;
    290311                break;
    291312            case 'm':
    292313                for(j = 0; j < count; j++)
    293                     _manage_modifiers(tuple[j], &fg, &bg, &save_fg, &save_bg, &bold);
     314                    manage_modifiers(tuple[j], &fg, &bg, &save_fg, &save_bg, &bold, &reverse);
    294315                if(bold && fg < 8)
    295316                    fg += 8;
    296317                if(bold && bg < 8)
    297318                    bg += 8;
    298                 cucul_set_color(cv, fg, bg);
     319                if(reverse)
     320                    cucul_set_color(cv, bg, fg);
     321                else
     322                    cucul_set_color(cv, fg, bg);
    299323                break;
    300324            default:
    301325                break;
    302326            }
    303         }
    304         else
    305         {
    306             if(buffer[i] == '\n')
    307             {
    308                 x = 0;
    309                 y++;
    310             }
    311             else if(buffer[i] == '\r')
    312             {
    313                     // DOS sucks.
    314             }
    315             else
    316             {
    317 
    318                 _cucul_putchar32(cv, x, y,_cucul_cp437_to_utf32(buffer[i]));
    319 
    320                 x++;
    321             }
    322         }
    323 
    324         if(x >= width || y >= height)
    325         {
    326             if(x >= width)
    327                 width = x + 1;
    328 
    329             if(y >= height)
    330                 height = y + 1;
    331 
     327
     328            continue;
     329        }
     330
     331        /* We're going to paste a character. First make sure the canvas
     332         * is big enough. */
     333        if(x >= width)
     334        {
     335            x = 0;
     336            y++;
     337        }
     338
     339        if(y >= height)
     340        {
     341            height = y + 1;
    332342            cucul_set_canvas_size(cv, width, height);
    333343        }
    334344
    335         i += add; // add is tuple char count
    336         add = 0;
     345        /* Now paste our character */
     346        _cucul_putchar32(cv, x, y,_cucul_cp437_to_utf32(buffer[i]));
     347        x++;
    337348    }
    338349
     
    342353/* XXX : ANSI loader helpers */
    343354
    344 unsigned char _get_ansi_command(unsigned char const *buffer, int size)
    345 {
    346     int i;
    347 
    348     for(i = 0; i < size; i++)
    349         if(IS_ALPHA(buffer[i]))
    350             return buffer[i];
    351 
    352     return 0;
    353 }
    354 
    355 int _parse_tuple(unsigned int *ret, unsigned char const *buffer, int size)
     355static int parse_tuple(unsigned int *ret, unsigned char const *buffer, int size)
    356356{
    357357    int i = 0;
     
    393393}
    394394
    395 
    396 
    397 void _manage_modifiers(int i, int *fg, int *bg, int *save_fg, int *save_bg, int *bold)
     395static 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)
    398396{
    399397    static uint8_t const ansi2cucul[] =
     
    411409    if(i >= 30 && i <= 37)
    412410        *fg = ansi2cucul[i - 30];
    413     else if(i == 39)
    414         *fg = CUCUL_COLOR_DEFAULT;
    415411    else if(i >= 40 && i <= 47)
    416412        *bg = ansi2cucul[i - 40];
    417     else if(i == 49)
    418         *bg = CUCUL_COLOR_DEFAULT;
    419413    else if(i >= 90 && i <= 97)
    420414        *fg = ansi2cucul[i - 90] + 8;
     
    427421        *bg = CUCUL_COLOR_DEFAULT;
    428422        *bold = 0;
     423        *reverse = 0;
    429424        break;
    430425    case 1: /* BOLD */
     
    436431        break;
    437432    case 7: // reverse
    438         *fg = 15 - *fg;
    439         *bg = 15 - *bg;
     433        *reverse = 1;
    440434        break;
    441435    case 8: // invisible
     
    449443        *bg = *save_bg;
    450444        break;
     445    case 39:
     446        *fg = CUCUL_COLOR_DEFAULT;
     447        break;
     448    case 49:
     449        *bg = CUCUL_COLOR_DEFAULT;
     450        break;
    451451    default:
    452452        break;
Note: See TracChangeset for help on using the changeset viewer.