Changeset 609


Ignore:
Timestamp:
Mar 14, 2006, 11:05:34 PM (15 years ago)
Author:
Sam Hocevar
Message:
  • Replaced all cucul_get_* exporters with a generic cucul_export() function.
  • Got rid of static buffers; we now use cucul_free() to free exported buffers.
  • Fixed light background in the ANSI exporter by adding escape sequences for most terminal emulators.
Location:
libcaca/trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/caca/driver_network.c

    r605 r609  
    8686    char prefix[sizeof(INIT_PREFIX)];
    8787
    88     char *buffer;
    89     int size;
     88    struct cucul_buffer *ex;
    9089
    9190    int client_count;
     
    170169    }
    171170
    172     kk->drv.p->buffer = NULL;
    173     kk->drv.p->size = 0;
     171    kk->drv.p->ex = NULL;
    174172
    175173    /* Ignore SIGPIPE */
     
    192190    }
    193191
     192    if(kk->drv.p->ex)
     193        cucul_free(kk->drv.p->ex);
     194
    194195    /* Restore SIGPIPE handler */
    195196    signal(SIGPIPE, kk->drv.p->sigpipe_handler);
     
    220221    int i;
    221222
     223    /* Free the previous export buffer, if any */
     224    if(kk->drv.p->ex)
     225    {
     226        cucul_free(kk->drv.p->ex);
     227        kk->drv.p->ex = NULL;
     228    }
     229
    222230    /* Get ANSI representation of the image and skip the end-of buffer
    223231     * linefeed ("\r\n\0", 3 bytes) */
    224     kk->drv.p->buffer = cucul_get_ansi(kk->qq, 0, &kk->drv.p->size);
    225     kk->drv.p->size -= 3;
     232    kk->drv.p->ex = cucul_export(kk->qq, CUCUL_FORMAT_ANSI);
     233    kk->drv.p->ex->size -= 3;
    226234
    227235    for(i = 0; i < kk->drv.p->client_count; i++)
     
    371379
    372380    /* No error, there's just nothing to send yet */
    373     if(!kk->drv.p->buffer)
     381    if(!kk->drv.p->ex)
    374382        return 0;
    375383
     
    396404            c->start += ret;
    397405
    398             if(c->stop - c->start + strlen(ANSI_PREFIX) + kk->drv.p->size
     406            if(c->stop - c->start + strlen(ANSI_PREFIX) + kk->drv.p->ex->size
    399407                > OUTBUFFER)
    400408            {
     
    407415
    408416            /* Need to move? */
    409             if(c->stop + strlen(ANSI_PREFIX) + kk->drv.p->size > OUTBUFFER)
     417            if(c->stop + strlen(ANSI_PREFIX) + kk->drv.p->ex->size > OUTBUFFER)
    410418            {
    411419                memmove(c->outbuf, c->outbuf + c->start, c->stop - c->start);
     
    416424            memcpy(c->outbuf + c->stop, ANSI_PREFIX, strlen(ANSI_PREFIX));
    417425            c->stop += strlen(ANSI_PREFIX);
    418             memcpy(c->outbuf + c->stop, kk->drv.p->buffer, kk->drv.p->size);
    419             c->stop += kk->drv.p->size;
     426            memcpy(c->outbuf + c->stop, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
     427            c->stop += kk->drv.p->ex->size;
    420428
    421429            return 0;
     
    437445    if(ret < (ssize_t)strlen(ANSI_PREFIX))
    438446    {
    439         if(strlen(ANSI_PREFIX) + kk->drv.p->size > OUTBUFFER)
     447        if(strlen(ANSI_PREFIX) + kk->drv.p->ex->size > OUTBUFFER)
    440448        {
    441449            /* Overflow! Empty buffer and start again */
     
    448456        memcpy(c->outbuf, ANSI_PREFIX, strlen(ANSI_PREFIX) - ret);
    449457        c->stop = strlen(ANSI_PREFIX) - ret;
    450         memcpy(c->outbuf + c->stop, kk->drv.p->buffer, kk->drv.p->size);
    451         c->stop += kk->drv.p->size;
     458        memcpy(c->outbuf + c->stop, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
     459        c->stop += kk->drv.p->ex->size;
    452460
    453461        return 0;
     
    455463
    456464    /* Send actual data */
    457     ret = nonblock_write(c->fd, kk->drv.p->buffer, kk->drv.p->size);
     465    ret = nonblock_write(c->fd, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
    458466    if(ret == -1)
    459467    {
     
    464472    }
    465473
    466     if(ret < kk->drv.p->size)
    467     {
    468         if(kk->drv.p->size > OUTBUFFER)
     474    if(ret < (int)kk->drv.p->ex->size)
     475    {
     476        if(kk->drv.p->ex->size > OUTBUFFER)
    469477        {
    470478            /* Overflow! Empty buffer and start again */
     
    475483        }
    476484
    477         memcpy(c->outbuf, kk->drv.p->buffer, kk->drv.p->size - ret);
    478         c->stop = kk->drv.p->size - ret;
     485        memcpy(c->outbuf, kk->drv.p->ex->buffer, kk->drv.p->ex->size - ret);
     486        c->stop = kk->drv.p->ex->size - ret;
    479487
    480488        return 0;
  • libcaca/trunk/cucul/cucul.c

    r602 r609  
    7474        return NULL;
    7575    }
    76 
    77     qq->ansi_buffer = NULL;
    78     qq->irc_buffer = NULL;
    79     qq->html3_buffer = NULL;
    80     qq->html_buffer = NULL;
    8176
    8277    return qq;
     
    278273    free(qq->attr);
    279274
    280     if(qq->ansi_buffer)
    281         free(qq->ansi_buffer);
    282     if(qq->irc_buffer)
    283         free(qq->irc_buffer);
    284     if(qq->html3_buffer)
    285         free(qq->html3_buffer);
    286     if(qq->html_buffer)
    287         free(qq->html_buffer);
    288     if(qq->ps_buffer)
    289         free(qq->ps_buffer);
    290 
    291 
    292275    free(qq);
     276}
     277
     278struct cucul_buffer * cucul_export(cucul_t *qq, enum cucul_format format)
     279{
     280    struct cucul_buffer *ex;
     281
     282    ex = malloc(sizeof(struct cucul_buffer));
     283
     284    switch(format)
     285    {
     286        case CUCUL_FORMAT_ANSI:
     287            _cucul_get_ansi(qq, ex);
     288            break;
     289        case CUCUL_FORMAT_HTML:
     290            _cucul_get_html(qq, ex);
     291            break;
     292        case CUCUL_FORMAT_HTML3:
     293            _cucul_get_html3(qq, ex);
     294            break;
     295        case CUCUL_FORMAT_IRC:
     296            _cucul_get_irc(qq, ex);
     297            break;
     298        case CUCUL_FORMAT_PS:
     299            _cucul_get_ps(qq, ex);
     300            break;
     301        default:
     302            free(ex);
     303            return NULL;
     304    }
     305
     306    return ex;
     307}
     308
     309void cucul_free(struct cucul_buffer *ex)
     310{
     311    free(ex->buffer);
     312    free(ex);
    293313}
    294314
  • libcaca/trunk/cucul/cucul.h

    r602 r609  
    2929/** \brief Colour definitions.
    3030 *
    31  *  Colours that can be used with caca_set_color().
     31 *  Colours that can be used with cucul_set_color().
    3232 */
    3333enum cucul_color
     
    5151};
    5252
     53/** \brief Export formats
     54 *
     55 *  Export formats understood by libcucul.
     56 */
     57enum cucul_format
     58{
     59    CUCUL_FORMAT_ANSI = 0, /**< Export to ANSI format. */
     60    CUCUL_FORMAT_HTML = 1, /**< Export to HTML format. */
     61    CUCUL_FORMAT_HTML3 = 2, /**< Export to old HTMLv3 format. */
     62    CUCUL_FORMAT_IRC = 3, /**< Export to text with mIRC colours. */
     63    CUCUL_FORMAT_PS = 4, /**< Export to PostScript. */
     64};
     65
    5366/** \brief Internal features.
    5467 *
     
    201214/** \defgroup exporter Exporters to various formats
    202215 *
    203  *  These functions exports current image to various text formats
    204  *  Returned buffer will be freed() each you'll call the exporter function.
    205  *
    206  *  @{ */
    207 char* cucul_get_html(cucul_t *, int *size);
    208 char* cucul_get_html3(cucul_t *, int *size);
    209 char* cucul_get_irc(cucul_t *, int *size);
    210 char* cucul_get_ansi(cucul_t *, int trailing, int *size);
    211 char* cucul_get_ps(cucul_t *qq, int *size);
     216 *  These functions export the current canvas to various text formats. It
     217 *  is necessary to call cucul_free() to dispose of the data.
     218 *
     219 *  @{ */
     220struct cucul_buffer
     221{
     222    unsigned int size;
     223    char *buffer;
     224};
     225
     226struct cucul_buffer * cucul_export(cucul_t *, enum cucul_format);
     227void cucul_free(struct cucul_buffer *);
    212228
    213229/*  @} */
  • libcaca/trunk/cucul/cucul_internals.h

    r602 r609  
    4848
    4949    unsigned int refcount;
    50 
    51     /* Exporters facilities */
    52     char *ansi_buffer;
    53     char *irc_buffer;
    54     char *html3_buffer;
    55     char *html_buffer;
    56     char *ps_buffer;
    5750};
    5851
  • libcaca/trunk/cucul/export_ansi.c

    r595 r609  
    1111
    1212/** \file export.c
    13  *  \version \$Id: export.c 361 2006-03-09 13:24:06Z jylam $
     13 *  \version \$Id$
    1414 *  \author Sam Hocevar <sam@zoy.org>
    1515 *  \author Jean-Yves Lamoureux <jylam@lnxscene.org>
     
    4040 *  \return buffer containing generated ANSI codes as a big string
    4141 */
    42 char * cucul_get_ansi(cucul_t *qq, int trailing, int *size)
     42void _cucul_get_ansi(cucul_t *qq, struct cucul_buffer *ex)
    4343{
    4444    static int const palette[] =
    4545    {
    46         30, 34, 32, 36, 31, 35, 33, 37, /* Both lines (light and dark) are the same, */
    47         30, 34, 32, 36, 31, 35, 33, 37, /* light colors handling is done later */
     46        0,  4,  2,  6, 1,  5,  3,  7,
     47        8, 12, 10, 14, 9, 13, 11, 15
    4848    };
    4949
     
    5151    unsigned int x, y;
    5252
    53     /* 20 bytes assumed for max length per pixel.
     53    /* 23 bytes assumed for max length per pixel ('\e[5;1;3x;4y;9x;10ym' plus
     54     * 4 max bytes for a UTF-8 character).
    5455     * Add height*9 to that (zeroes color at the end and jump to next line) */
    55     if(qq->ansi_buffer)
    56         free(qq->ansi_buffer);
    57     qq->ansi_buffer = malloc(((qq->height*9) + (qq->width * qq->height * 20)) * sizeof(char));
    58     if(qq->ansi_buffer == NULL)
    59         return NULL;
     56    ex->size = (qq->height * 9) + (qq->width * qq->height * 23);
     57    ex->buffer = malloc(ex->size);
    6058
    61     cur = qq->ansi_buffer;
    62 
    63     // *cur++ = '';
     59    cur = ex->buffer;
    6460
    6561    for(y = 0; y < qq->height; y++)
     
    7470        {
    7571            uint8_t fg = palette[lineattr[x] & 0x0f];
    76             uint8_t bg = (palette[lineattr[x] >> 4])+10;
     72            uint8_t bg = palette[lineattr[x] >> 4];
    7773            uint32_t c = linechar[x];
    7874
    79             if(!trailing)
    80                 cur += sprintf(cur, "\033[");
    81             else
    82                 cur += sprintf(cur, "\\033[");
     75            if(fg != prevfg || bg != prevbg)
     76            {
     77                cur += sprintf(cur, "\033[0;");
    8378
    84             if(fg > 7)
    85                 cur += sprintf(cur, "1;%d;%dm",fg,bg);
    86             else
    87                 cur += sprintf(cur, "0;%d;%dm",fg,bg);
     79                if(fg < 8)
     80                    if(bg < 8)
     81                        cur += sprintf(cur, "3%d;4%dm", fg, bg);
     82                    else
     83                        cur += sprintf(cur, "5;3%d;4%d;10%dm",
     84                                            fg, bg - 8, bg - 8);
     85                else
     86                    if(bg < 8)
     87                        cur += sprintf(cur, "1;3%d;4%d;9%dm",
     88                                            fg - 8, bg, fg - 8);
     89                    else
     90                        cur += sprintf(cur, "5;1;3%d;4%d;9%d;10%dm",
     91                                            fg - 8, bg - 8, fg - 8, bg - 8);
     92            }
     93
    8894            *cur++ = c & 0x7f;
    89             if((c == '%') && trailing)
    90                 *cur++ = c & 0x7f;
     95
    9196            prevfg = fg;
    9297            prevbg = bg;
    9398        }
    94         if(!trailing)
    95             cur += sprintf(cur, "\033[0m\r\n");
    96         else
    97             cur += sprintf(cur, "\\033[0m\\n\n");
     99
     100        cur += sprintf(cur, "\033[0m\r\n");
    98101    }
    99102
    100103    /* Crop to really used size */
    101     *size = (strlen(qq->ansi_buffer) + 1)* sizeof(char);
    102     qq->ansi_buffer = realloc(qq->ansi_buffer, *size);
    103 
    104     return qq->ansi_buffer;
     104    ex->size = strlen(ex->buffer) + 1;
     105    ex->buffer = realloc(ex->buffer, ex->size);
    105106}
    106107
  • libcaca/trunk/cucul/export_html.c

    r595 r609  
    1111
    1212/** \file export.c
    13  *  \version \$Id: export.c 361 2006-03-09 13:24:06Z jylam $
     13 *  \version \$Id$
    1414 *  \author Sam Hocevar <sam@zoy.org>
    1515 *  \author Jean-Yves Lamoureux <jylam@lnxscene.org>
     
    3939 *  the current image.
    4040 */
    41 char* cucul_get_html(cucul_t *qq, int *size)
     41void _cucul_get_html(cucul_t *qq, struct cucul_buffer *ex)
    4242{
    4343    static int const palette[] =
     
    5252     * 40 -> max size used for a pixel (plus 10, never know)*/
    5353    /* FIXME: Check this value */
    54     if(qq->html_buffer)
    55         free(qq->html_buffer);
     54    ex->size = 13000 + (qq->width * qq->height * 40);
     55    ex->buffer = malloc(ex->size);
    5656
    57     qq->html_buffer = malloc((13000 + ((qq->width*qq->height) * 40)) * sizeof(char));
    58     if(qq->html_buffer == NULL)
    59         return NULL;
    60 
    61 
    62     cur = qq->html_buffer;
     57    cur = ex->buffer;
    6358
    6459    /* HTML header */
     
    105100
    106101    /* Crop to really used size */
    107     *size = (strlen(qq->html_buffer) + 1) * sizeof(char);
    108     qq->html_buffer = realloc(qq->html_buffer, *size);
    109 
    110     return qq->html_buffer;
     102    ex->size = strlen(ex->buffer) + 1;
     103    ex->buffer = realloc(ex->buffer, ex->size);
    111104}
    112105
     
    120113 *  a correct header.
    121114 */
    122 char* cucul_get_html3(cucul_t *qq, int *size)
     115void _cucul_get_html3(cucul_t *qq, struct cucul_buffer *ex)
    123116{
    124117    static int const palette[] =
     
    129122        0xff4444, 0xff44ff, 0xffff44, 0xffffff,
    130123    };
     124
    131125    char *cur;
    132126    unsigned int x, y, len;
     
    134128    /* 13000 -> css palette
    135129     * 40 -> max size used for a pixel (plus 10, never know) */
     130    ex->size = 13000 + (qq->width * qq->height * 40);
     131    ex->buffer = malloc(ex->size);
    136132
    137     if(qq->html3_buffer)
    138         free(qq->html3_buffer);
    139 
    140     qq->html3_buffer = malloc((13000 + ((qq->width*qq->height)*40))*sizeof(char));
    141     if(qq->html3_buffer == NULL)
    142         return NULL;
    143 
    144     cur = qq->html3_buffer;
     133    cur = ex->buffer;
    145134
    146135    /* Table */
     
    190179
    191180    /* Crop to really used size */
    192     *size = (strlen(qq->html3_buffer) + 1) * sizeof(char);
    193     qq->html3_buffer = realloc(qq->html3_buffer, *size);
    194    
    195     return qq->html3_buffer;
     181    ex->size = strlen(ex->buffer) + 1;
     182    ex->buffer = realloc(ex->buffer, ex->size);
    196183}
    197184
  • libcaca/trunk/cucul/export_irc.c

    r595 r609  
    1111
    1212/** \file export.c
    13  *  \version \$Id: export.c 361 2006-03-09 13:24:06Z jylam $
     13 *  \version \$Id$
    1414 *  \author Sam Hocevar <sam@zoy.org>
    1515 *  \author Jean-Yves Lamoureux <jylam@lnxscene.org>
     
    3737 *  the current image.
    3838 */
    39 char* cucul_get_irc(cucul_t *qq, int *size)
     39void _cucul_get_irc(cucul_t *qq, struct cucul_buffer *ex)
    4040{
    4141    static int const palette[] =
     
    5656     */
    5757
    58     if(qq->irc_buffer)
    59         free(qq->irc_buffer);
     58    ex->size = 2 + (qq->width * qq->height * 11);
     59    ex->buffer = malloc(ex->size);
    6060
    61     qq->irc_buffer = malloc((2 + (qq->width * qq->height * 11)) * sizeof(char));
    62     if(qq->irc_buffer == NULL)
    63         return NULL;
    64 
    65     cur = qq->irc_buffer;
     61    cur = ex->buffer;
    6662
    6763    *cur++ = '\x0f';
     
    115111
    116112    /* Crop to really used size */
    117     *size = (strlen(qq->irc_buffer) + 1) * sizeof(char);
    118     qq->irc_buffer = realloc(qq->irc_buffer, *size);
    119    
    120     return qq->irc_buffer;
     113    ex->size = strlen(ex->buffer) + 1;
     114    ex->buffer = realloc(ex->buffer, ex->size);
    121115}
  • libcaca/trunk/cucul/export_ps.c

    r606 r609  
    6060 *  the current image.
    6161 */
    62 char* cucul_get_ps(cucul_t *qq, int *size)
     62void _cucul_get_ps(cucul_t *qq, struct cucul_buffer *ex)
    6363{
    6464    char *cur;
     
    8888
    8989
    90     if(qq->ps_buffer)
    91         free(qq->ps_buffer);
     90    /* 200 is arbitrary but should be ok */
     91    ex->size = strlen(ps_header) + (qq->width * qq->height * 200);
     92    ex->buffer = malloc(ex->size);
    9293
    93     /* 200 is arbitrary but should be ok */
    94     qq->ps_buffer = malloc((strlen(ps_header) + (qq->height*qq->width)*200) * sizeof(char));
    95     cur = qq->ps_buffer;
     94    cur = ex->buffer;
    9695
    9796    /* Header */
    9897    cur += sprintf(cur, "%s", ps_header);
    99 
    10098
    10199    /* Background, drawn using csquare macro defined in header */
     
    140138
    141139    /* Crop to really used size */
    142     *size = (strlen(qq->ps_buffer) + 1) * sizeof(char);
    143 
    144     qq->ps_buffer = realloc(qq->ps_buffer, *size);
    145 
    146     return qq->ps_buffer;
    147 
     140    ex->size = strlen(ex->buffer) + 1;
     141    ex->buffer = realloc(ex->buffer, ex->size);
    148142}
    149143
    150 
    151 
Note: See TracChangeset for help on using the changeset viewer.