Changeset 915 for libcaca


Ignore:
Timestamp:
Apr 26, 2006, 7:02:37 PM (15 years ago)
Author:
Sam Hocevar
Message:
  • Fixed an ANSI rendering bug related to the bold attribute.
File:
1 edited

Legend:

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

    r913 r915  
    2828#include "cucul_internals.h"
    2929
     30/* ANSI Graphic Rendition Combination Mode */
     31struct ansi_grcm
     32{
     33    uint8_t fg, bg;
     34    uint8_t bold, negative, concealed;
     35};
     36
    3037static cucul_canvas_t *import_caca(void const *, unsigned int);
    3138static cucul_canvas_t *import_text(void const *, unsigned int);
    3239static cucul_canvas_t *import_ansi(void const *, unsigned int);
     40
     41static void ansi_parse_grcm(cucul_canvas_t *, struct ansi_grcm *,
     42                            unsigned int, unsigned int const *);
    3343
    3444/** \brief Import a buffer into a canvas
     
    201211}
    202212
    203 /* Graphic Rendition Combination Mode */
    204 struct grcm
    205 {
    206     uint8_t fg, bg;
    207     uint8_t bold, negative, concealed;
    208 };
    209 
    210 static void manage_modifiers(struct grcm *, int);
    211 
    212213static cucul_canvas_t *import_ansi(void const *data, unsigned int size)
    213214{
    214     struct grcm grcm;
     215    struct ansi_grcm grcm;
    215216    unsigned char const *buffer = (unsigned char const*)data;
    216217    cucul_canvas_t *cv;
    217     unsigned int i, j, skip;
     218    unsigned int i, j, skip, dummy = 0;
    218219    unsigned int width = 80, height = 25;
    219220    int x = 0, y = 0, save_x = 0, save_y = 0;
    220221
    221     manage_modifiers(&grcm, 0);
    222 
    223222    cv = cucul_create_canvas(width, height);
    224     cucul_set_color(cv, CUCUL_COLOR_DEFAULT, CUCUL_COLOR_DEFAULT);
     223    ansi_parse_grcm(cv, &grcm, 1, &dummy);
    225224
    226225    for(i = 0; i < size; i += skip)
     
    277276            if(param < inter && buffer[i + param] >= 0x3c)
    278277            {
    279                 //fprintf(stderr, "private sequence \"^[[%.*s\"\n",
    280                 //                final - param + 1, buffer + i + param);
     278                fprintf(stderr, "private sequence \"^[[%.*s\"\n",
     279                                final - param + 1, buffer + i + param);
    281280                continue; /* Private sequence, skip it entirely */
    282281            }
     
    344343                break;
    345344            case 'm': /* SGR - Select Graphic Rendition */
    346                 for(j = 0; j < argc; j++)
    347                     manage_modifiers(&grcm, argv[j]);
    348                 if(grcm.concealed)
    349                     cucul_set_color(cv, CUCUL_COLOR_TRANSPARENT,
    350                                         CUCUL_COLOR_TRANSPARENT);
    351                 else if(grcm.negative)
    352                     cucul_set_color(cv, (grcm.bold && grcm.bg < 8) ?
    353                                         grcm.bg + 8 : grcm.bg, grcm.fg);
    354                 else
    355                     cucul_set_color(cv, (grcm.bold && grcm.fg < 8) ?
    356                                         grcm.fg + 8 : grcm.fg, grcm.bg);
     345                ansi_parse_grcm(cv, &grcm, argc, argv);
    357346                break;
    358347            default:
     348                fprintf(stderr, "unknown command %c\n", buffer[i + final]);
    359349                break;
    360350            }
     
    378368
    379369        /* Now paste our character */
    380         _cucul_putchar32(cv, x, y,_cucul_cp437_to_utf32(buffer[i]));
     370        _cucul_putchar32(cv, x, y, _cucul_cp437_to_utf32(buffer[i]));
    381371        x++;
    382372    }
     
    387377/* XXX : ANSI loader helper */
    388378
    389 static void manage_modifiers(struct grcm *g, int i)
     379static void ansi_parse_grcm(cucul_canvas_t *cv, struct ansi_grcm *g,
     380                            unsigned int argc, unsigned int const *argv)
    390381{
    391382    static uint8_t const ansi2cucul[] =
     
    397388    };
    398389
    399     /* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */
    400     if(i >= 30 && i <= 37)
    401         g->fg = ansi2cucul[i - 30];
    402     else if(i >= 40 && i <= 47)
    403         g->bg = ansi2cucul[i - 40];
    404     else if(i >= 90 && i <= 97)
    405         g->fg = ansi2cucul[i - 90] + 8;
    406     else if(i >= 100 && i <= 107)
    407         g->bg = ansi2cucul[i - 100] + 8;
    408     else switch(i)
    409     {
    410     case 0: /* default rendition */
    411         g->fg = CUCUL_COLOR_DEFAULT;
    412         g->bg = CUCUL_COLOR_DEFAULT;
    413         g->bold = g->negative = g->concealed = 0;
    414         break;
    415     case 1: /* bold or increased intensity */
    416         g->bold = 1;
    417         break;
    418     case 4: /* singly underlined */
    419         break;
    420     case 5: /* slowly blinking (less then 150 per minute) */
    421         break;
    422     case 7: /* negative image */
    423         g->negative = 1;
    424         break;
    425     case 8: /* concealed characters */
    426         g->concealed = 1;
    427         break;
    428     case 22: /* normal colour or normal intensity (neither bold nor faint) */
    429         g->bold = 0;
    430         break;
    431     case 28: /* revealed characters */
    432         g->concealed = 0;
    433         break;
    434     case 39: /* default display colour (implementation-defined) */
    435         g->fg = CUCUL_COLOR_DEFAULT;
    436         break;
    437     case 49: /* default background colour (implementation-defined) */
    438         g->bg = CUCUL_COLOR_DEFAULT;
    439         break;
    440     default:
    441         //fprintf(stderr, "unknown sgr %i\n", i);
    442         break;
    443     }
    444 }
    445 
     390    unsigned int j;
     391    uint8_t myfg, mybg;
     392
     393    for(j = 0; j < argc; j++)
     394    {
     395        /* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */
     396        if(argv[j] >= 30 && argv[j] <= 37)
     397            g->fg = ansi2cucul[argv[j] - 30];
     398        else if(argv[j] >= 40 && argv[j] <= 47)
     399            g->bg = ansi2cucul[argv[j] - 40];
     400        else if(argv[j] >= 90 && argv[j] <= 97)
     401            g->fg = ansi2cucul[argv[j] - 90] + 8;
     402        else if(argv[j] >= 100 && argv[j] <= 107)
     403            g->bg = ansi2cucul[argv[j] - 100] + 8;
     404        else switch(argv[j])
     405        {
     406        case 0: /* default rendition */
     407            g->fg = CUCUL_COLOR_DEFAULT;
     408            g->bg = CUCUL_COLOR_DEFAULT;
     409            g->bold = g->negative = g->concealed = 0;
     410            break;
     411        case 1: /* bold or increased intensity */
     412            g->bold = 1;
     413            break;
     414        case 4: /* singly underlined */
     415            break;
     416        case 5: /* slowly blinking (less then 150 per minute) */
     417            break;
     418        case 7: /* negative image */
     419            g->negative = 1;
     420            break;
     421        case 8: /* concealed characters */
     422            g->concealed = 1;
     423            break;
     424        case 22: /* normal colour or normal intensity (neither bold nor faint) */
     425            g->bold = 0;
     426            break;
     427        case 28: /* revealed characters */
     428            g->concealed = 0;
     429            break;
     430        case 39: /* default display colour (implementation-defined) */
     431            g->fg = CUCUL_COLOR_DEFAULT;
     432            break;
     433        case 49: /* default background colour (implementation-defined) */
     434            g->bg = CUCUL_COLOR_DEFAULT;
     435            break;
     436        default:
     437            fprintf(stderr, "unknown sgr %i\n", argv[j]);
     438            break;
     439        }
     440    }
     441
     442    if(g->concealed)
     443    {
     444        myfg = mybg = CUCUL_COLOR_TRANSPARENT;
     445    }
     446    else
     447    {
     448        myfg = g->negative ? g->bg : g->fg;
     449        mybg = g->negative ? g->fg : g->bg;
     450
     451        if(g->bold)
     452        {
     453            if(myfg < 8)
     454                myfg += 8;
     455            else if(myfg == CUCUL_COLOR_DEFAULT)
     456                myfg = CUCUL_COLOR_WHITE;
     457        }
     458    }
     459
     460    cucul_set_color(cv, myfg, mybg);
     461}
     462
Note: See TracChangeset for help on using the changeset viewer.