Changeset 1241 for toilet


Ignore:
Timestamp:
Oct 26, 2006, 3:07:58 PM (13 years ago)
Author:
Sam Hocevar
Message:
  • Make stdin input line-aware so that we don't have to wait until EOF to display stuff.
  • Reorganise stuff and fix memory leaks.
Location:
toilet/trunk/src
Files:
1 deleted
8 edited
2 copied

Legend:

Unmodified
Added
Removed
  • toilet/trunk/src/Makefile.am

    r1227 r1241  
    66        render.c render.h \
    77        filter.c filter.h \
    8         figlet.c figlet.h
     8        term.c mono9.c figlet.c
    99toilet_CFLAGS = `pkg-config --cflags cucul`
    1010toilet_LDFLAGS = `pkg-config --libs cucul` @GETOPT_LIBS@ @ZLIB_LIBS@
  • toilet/trunk/src/figlet.c

    r1204 r1241  
    2727
    2828#include "toilet.h"
     29#include "render.h"
    2930#include "io.h"
    30 #include "figlet.h"
    3131
    3232#define STD_GLYPHS (127 - 32)
     
    3434
    3535static int feed_figlet(context_t *, uint32_t);
     36static int flush_figlet(context_t *);
    3637static int end_figlet(context_t *);
    3738
     
    4849
    4950    cx->feed = feed_figlet;
     51    cx->flush = flush_figlet;
    5052    cx->end = end_figlet;
    5153
     
    109111}
    110112
     113static int flush_figlet(context_t *cx)
     114{
     115    cx->torender = cx->cv;
     116    cucul_set_canvas_size(cx->torender, cx->w, cx->h);
     117
     118    cx->x = cx->y = 0;
     119    cx->w = cx->h = 0;
     120    cx->cv = cucul_create_canvas(1, 1);
     121
     122    return 0;
     123}
     124
    111125static int end_figlet(context_t *cx)
    112126{
    113127    cucul_free_canvas(cx->image);
     128    cucul_free_canvas(cx->cv);
    114129    free(cx->lookup);
    115130
  • toilet/trunk/src/filter.c

    r1228 r1241  
    9393
    9494    for(i = 0; i < cx->nfilters; i++)
    95         cx->filters[i](cx->cv);
     95        cx->filters[i](cx->torender);
     96
     97    return 0;
     98}
     99
     100int filter_end(context_t *cx)
     101{
     102    free(cx->filters);
    96103
    97104    return 0;
  • toilet/trunk/src/filter.h

    r1228 r1241  
    1818extern int filter_add(context_t *, char const *);
    1919extern int filter_do(context_t *);
     20extern int filter_end(context_t *);
    2021
  • toilet/trunk/src/main.c

    r1240 r1241  
    2828#endif
    2929#include <stdio.h>
    30 #include <string.h>
    3130#include <stdlib.h>
    3231#include <cucul.h>
     
    3433#include "toilet.h"
    3534#include "render.h"
    36 #include "figlet.h"
    3735#include "filter.h"
    3836
     
    4644    context_t struct_cx;
    4745    context_t *cx = &struct_cx;
    48 
    49     cucul_buffer_t *buffer;
    50 
    51     int i, j, ret;
    5246
    5347    int infocode = -1;
     
    184178    }
    185179
    186     if(!strcasecmp(cx->font, "mono9"))
    187         ret = init_big(cx);
    188     else if(!strcasecmp(cx->font, "term"))
    189         ret = init_tiny(cx);
     180    if(render_init(cx) < 0)
     181        return -1;
     182
     183    if(optind >= argc)
     184        render_stdin(cx);
    190185    else
    191         ret = init_figlet(cx);
    192 
    193     if(ret)
    194         return -1;
    195 
    196     if(optind >= argc)
    197     {
    198         char buf[10];
    199         unsigned int len;
    200         uint32_t ch;
    201 
    202         i = 0;
    203 
    204         /* Read from stdin */
    205         while(!feof(stdin))
    206         {
    207             buf[i++] = getchar();
    208             buf[i] = '\0';
    209 
    210             ch = cucul_utf8_to_utf32(buf, &len);
    211 
    212             if(!len)
    213                 continue;
    214 
    215             cx->feed(cx, ch);
    216             i = 0;
    217         }
    218     }
    219     else for(i = optind; i < argc; i++)
    220     {
    221         /* Read from commandline */
    222         unsigned int len;
    223 
    224         if(i != optind)
    225             cx->feed(cx, ' ');
    226 
    227         for(j = 0; argv[i][j];)
    228         {
    229             cx->feed(cx, cucul_utf8_to_utf32(argv[i] + j, &len));
    230             j += len;
    231         }
    232     }
    233 
    234     cx->end(cx);
    235 
    236     /* Apply optional effects to our string */
    237     filter_do(cx);
    238 
    239     /* Output char */
    240     buffer = cucul_export_canvas(cx->cv, cx->export);
    241     fwrite(cucul_get_buffer_data(buffer),
    242            cucul_get_buffer_size(buffer), 1, stdout);
    243     cucul_free_buffer(buffer);
    244 
    245     cucul_free_canvas(cx->cv);
     186        render_list(cx, argc - optind, argv + optind);
     187
     188    render_end(cx);
     189    filter_end(cx);
    246190
    247191    return 0;
  • toilet/trunk/src/mono9.c

    r1240 r1241  
    2727#include "render.h"
    2828
    29 static int feed_tiny(context_t *, uint32_t);
    30 static int end_tiny(context_t *);
    31 
    3229static int feed_big(context_t *, uint32_t);
     30static int flush_big(context_t *);
    3331static int end_big(context_t *);
    34 
    35 int init_tiny(context_t *cx)
    36 {
    37     cx->ew = 16;
    38     cx->eh = 2;
    39     cx->x = cx->y = 0;
    40     cx->w = cx->h = 0;
    41     cx->cv = cucul_create_canvas(cx->ew, cx->eh);
    42 
    43     cx->feed = feed_tiny;
    44     cx->end = end_tiny;
    45 
    46     return 0;
    47 }
    48 
    49 static int feed_tiny(context_t *cx, uint32_t ch)
    50 {
    51     switch(ch)
    52     {
    53         case (uint32_t)'\r':
    54             return 0;
    55         case (uint32_t)'\n':
    56             cx->x = 0;
    57             cx->y++;
    58             return 0;
    59         case (uint32_t)'\t':
    60             cx->x = (cx->x & ~7) + 8;
    61             return 0;
    62     }
    63 
    64     /* Check whether we reached the end of the screen */
    65     if(cx->x && cx->x + 1 > cx->term_width)
    66     {
    67         cx->x = 0;
    68         cx->y++;
    69     }
    70 
    71     /* Check whether the current canvas is large enough */
    72     if(cx->x + 1 > cx->w)
    73     {
    74         cx->w = cx->x + 1 < cx->term_width ? cx->x + 1 : cx->term_width;
    75         if(cx->w > cx->ew)
    76             cx->ew = cx->ew + cx->ew / 2;
    77     }
    78 
    79     if(cx->y + 1 > cx->h)
    80     {
    81         cx->h = cx->y + 1;
    82         if(cx->h > cx->eh)
    83             cx->eh = cx->eh + cx->eh / 2;
    84     }
    85 
    86     cucul_set_canvas_size(cx->cv, cx->ew, cx->eh);
    87 
    88     cucul_putchar(cx->cv, cx->x, cx->y, ch);
    89     cx->x++;
    90 
    91     return 0;
    92 }
    93 
    94 static int end_tiny(context_t *cx)
    95 {
    96     cucul_set_canvas_size(cx->cv, cx->w, cx->h);
    97 
    98     return 0;
    99 }
    10032
    10133int init_big(context_t *cx)
     
    11547
    11648    cx->feed = feed_big;
     49    cx->flush = flush_big;
    11750    cx->end = end_big;
    11851
     
    180113}
    181114
     115static int flush_big(context_t *cx)
     116{
     117    cx->torender = cx->cv;
     118    cucul_set_canvas_size(cx->torender, cx->w, cx->h);
     119
     120    cx->x = cx->y = 0;
     121    cx->w = cx->h = 0;
     122    cx->cv = cucul_create_canvas(1, 1);
     123
     124    return 0;
     125}
     126
    182127static int end_big(context_t *cx)
    183128{
    184129    cucul_free_canvas(cx->onechar);
     130    cucul_free_canvas(cx->cv);
    185131    free(cx->buf);
    186132    cucul_free_font(cx->f);
  • toilet/trunk/src/render.c

    r1195 r1241  
    2222#endif
    2323#include <stdlib.h>
     24#include <string.h>
     25#include <stdio.h>
    2426#include <cucul.h>
    2527
    2628#include "toilet.h"
    2729#include "render.h"
     30#include "filter.h"
    2831
    29 static int feed_tiny(context_t *, uint32_t);
    30 static int end_tiny(context_t *);
     32int render_init(context_t *cx)
     33{
     34    if(!strcasecmp(cx->font, "mono9"))
     35        return init_big(cx);
    3136
    32 static int feed_big(context_t *, uint32_t);
    33 static int end_big(context_t *);
     37    if(!strcasecmp(cx->font, "term"))
     38        return init_tiny(cx);
    3439
    35 int init_tiny(context_t *cx)
     40    return init_figlet(cx);
     41}
     42
     43int render_stdin(context_t *cx)
    3644{
    37     cx->ew = 16;
    38     cx->eh = 2;
    39     cx->x = cx->y = 0;
    40     cx->w = cx->h = 0;
    41     cx->cv = cucul_create_canvas(cx->ew, cx->eh);
     45    char buf[10];
     46    unsigned int i = 0, len;
     47    uint32_t ch;
    4248
    43     cx->feed = feed_tiny;
    44     cx->end = end_tiny;
     49    /* Read from stdin */
     50    while(!feof(stdin))
     51    {
     52        buf[i++] = getchar();
     53        buf[i] = '\0';
     54
     55        ch = cucul_utf8_to_utf32(buf, &len);
     56
     57        if(!len)
     58            continue;
     59
     60        cx->feed(cx, ch);
     61        i = 0;
     62
     63        if(ch == '\n')
     64            render_line(cx);
     65    }
    4566
    4667    return 0;
    4768}
    4869
    49 static int feed_tiny(context_t *cx, uint32_t ch)
     70int render_list(context_t *cx, unsigned int argc, char *argv[])
    5071{
    51     switch(ch)
     72    unsigned int i, j;
     73
     74    for(i = 0; i < argc; i++)
    5275    {
    53         case (uint32_t)'\r':
    54             return 0;
    55         case (uint32_t)'\n':
    56             cx->x = 0;
    57             cx->y++;
    58             return 0;
    59         case (uint32_t)'\t':
    60             cx->x = (cx->x & ~7) + 8;
    61             return 0;
     76        /* Read from commandline */
     77        unsigned int len;
     78
     79        if(i)
     80            cx->feed(cx, ' ');
     81
     82        for(j = 0; argv[i][j];)
     83        {
     84            cx->feed(cx, cucul_utf8_to_utf32(argv[i] + j, &len));
     85            j += len;
     86        }
    6287    }
    6388
    64     /* Check whether we reached the end of the screen */
    65     if(cx->x && cx->x + 1 > cx->term_width)
    66     {
    67         cx->x = 0;
    68         cx->y++;
    69     }
    70 
    71     /* Check whether the current canvas is large enough */
    72     if(cx->x + 1 > cx->w)
    73     {
    74         cx->w = cx->x + 1 < cx->term_width ? cx->x + 1 : cx->term_width;
    75         if(cx->w > cx->ew)
    76             cx->ew = cx->ew + cx->ew / 2;
    77     }
    78 
    79     if(cx->y + 1 > cx->h)
    80     {
    81         cx->h = cx->y + 1;
    82         if(cx->h > cx->eh)
    83             cx->eh = cx->eh + cx->eh / 2;
    84     }
    85 
    86     cucul_set_canvas_size(cx->cv, cx->ew, cx->eh);
    87 
    88     cucul_putchar(cx->cv, cx->x, cx->y, ch);
    89     cx->x++;
     89    render_line(cx);
    9090
    9191    return 0;
    9292}
    9393
    94 static int end_tiny(context_t *cx)
     94int render_line(context_t *cx)
    9595{
    96     cucul_set_canvas_size(cx->cv, cx->w, cx->h);
     96    cucul_buffer_t *buffer;
     97
     98    /* Flush current line */
     99    cx->flush(cx);
     100
     101    /* Apply optional effects to our string */
     102    filter_do(cx);
     103
     104    /* Output line */
     105    buffer = cucul_export_canvas(cx->torender, cx->export);
     106    fwrite(cucul_get_buffer_data(buffer),
     107           cucul_get_buffer_size(buffer), 1, stdout);
     108    cucul_free_buffer(buffer);
     109    cucul_free_canvas(cx->torender);
    97110
    98111    return 0;
    99112}
    100113
    101 int init_big(context_t *cx)
     114int render_end(context_t *cx)
    102115{
    103     char const * const * fonts;
    104 
    105     fonts = cucul_get_font_list();
    106     cx->f = cucul_load_font(fonts[0], 0);
    107     cx->buf = malloc(4 * cucul_get_font_width(cx->f)
    108                        * cucul_get_font_height(cx->f));
    109     cx->onechar = cucul_create_canvas(1, 1);
    110     cucul_set_color(cx->onechar, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
    111 
    112     cx->x = cx->y = 0;
    113     cx->w = cx->h = 0;
    114     cx->cv = cucul_create_canvas(1, 1);
    115 
    116     cx->feed = feed_big;
    117     cx->end = end_big;
     116    cx->end(cx);
    118117
    119118    return 0;
    120119}
    121120
    122 static int feed_big(context_t *cx, uint32_t ch)
    123 {
    124     unsigned int w = cucul_get_font_width(cx->f);
    125     unsigned int h = cucul_get_font_height(cx->f);
    126     unsigned int x, y;
    127 
    128     switch(ch)
    129     {
    130         case (uint32_t)'\r':
    131             return 0;
    132         case (uint32_t)'\n':
    133             cx->x = 0;
    134             cx->y += h;
    135             return 0;
    136         case (uint32_t)'\t':
    137             cx->x = (((cx->x / w) & ~7) + 8) * w;
    138             return 0;
    139     }
    140 
    141     /* Check whether we reached the end of the screen */
    142     if(cx->x && cx->x + w > cx->term_width)
    143     {
    144         cx->x = 0;
    145         cx->y += h;
    146     }
    147 
    148     /* Check whether the current canvas is large enough */
    149     if(cx->x + w > cx->w)
    150         cx->w = cx->x + w < cx->term_width ? cx->x + w : cx->term_width;
    151 
    152     if(cx->y + h > cx->h)
    153         cx->h = cx->y + h;
    154 
    155     cucul_set_canvas_size(cx->cv, cx->w, cx->h);
    156 
    157     /* Render our char */
    158     cucul_putchar(cx->onechar, 0, 0, ch);
    159     cucul_render_canvas(cx->onechar, cx->f, cx->buf, w, h, 4 * w);
    160 
    161     for(y = 0; y < h; y++)
    162        for(x = 0; x < w; x++)
    163     {
    164         unsigned char c = cx->buf[4 * (x + y * w) + 2];
    165 
    166         if(c >= 0xa0)
    167             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "█");
    168         else if(c >= 0x80)
    169             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▓");
    170         else if(c >= 0x40)
    171             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▒");
    172         else if(c >= 0x20)
    173             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "░");
    174     }
    175 
    176     /* Advance cursor */
    177     cx->x += w;
    178 
    179     return 0;
    180 }
    181 
    182 static int end_big(context_t *cx)
    183 {
    184     cucul_free_canvas(cx->onechar);
    185     free(cx->buf);
    186     cucul_free_font(cx->f);
    187 
    188     return 0;
    189 }
    190 
  • toilet/trunk/src/render.h

    r1194 r1241  
    1818extern int init_tiny(context_t *);
    1919extern int init_big(context_t *);
     20extern int init_figlet(context_t *);
    2021
     22extern int render_init(context_t *);
     23extern int render_stdin(context_t *);
     24extern int render_list(context_t *, unsigned int, char *[]);
     25extern int render_line(context_t *);
     26extern int render_end(context_t *);
     27
  • toilet/trunk/src/term.c

    r1240 r1241  
    2828
    2929static int feed_tiny(context_t *, uint32_t);
     30static int flush_tiny(context_t *);
    3031static int end_tiny(context_t *);
    31 
    32 static int feed_big(context_t *, uint32_t);
    33 static int end_big(context_t *);
    3432
    3533int init_tiny(context_t *cx)
     
    4240
    4341    cx->feed = feed_tiny;
     42    cx->flush = flush_tiny;
    4443    cx->end = end_tiny;
    4544
     
    9291}
    9392
    94 static int end_tiny(context_t *cx)
     93static int flush_tiny(context_t *cx)
    9594{
    96     cucul_set_canvas_size(cx->cv, cx->w, cx->h);
     95    cx->torender = cx->cv;
     96    cucul_set_canvas_size(cx->torender, cx->w, cx->h);
     97
     98    cx->ew = 16;
     99    cx->eh = 2;
     100    cx->x = cx->y = 0;
     101    cx->w = cx->h = 0;
     102    cx->cv = cucul_create_canvas(cx->ew, cx->eh);
    97103
    98104    return 0;
    99105}
    100106
    101 int init_big(context_t *cx)
     107static int end_tiny(context_t *cx)
    102108{
    103     char const * const * fonts;
    104 
    105     fonts = cucul_get_font_list();
    106     cx->f = cucul_load_font(fonts[0], 0);
    107     cx->buf = malloc(4 * cucul_get_font_width(cx->f)
    108                        * cucul_get_font_height(cx->f));
    109     cx->onechar = cucul_create_canvas(1, 1);
    110     cucul_set_color(cx->onechar, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
    111 
    112     cx->x = cx->y = 0;
    113     cx->w = cx->h = 0;
    114     cx->cv = cucul_create_canvas(1, 1);
    115 
    116     cx->feed = feed_big;
    117     cx->end = end_big;
     109    cucul_free_canvas(cx->cv);
    118110
    119111    return 0;
    120112}
    121113
    122 static int feed_big(context_t *cx, uint32_t ch)
    123 {
    124     unsigned int w = cucul_get_font_width(cx->f);
    125     unsigned int h = cucul_get_font_height(cx->f);
    126     unsigned int x, y;
    127 
    128     switch(ch)
    129     {
    130         case (uint32_t)'\r':
    131             return 0;
    132         case (uint32_t)'\n':
    133             cx->x = 0;
    134             cx->y += h;
    135             return 0;
    136         case (uint32_t)'\t':
    137             cx->x = (((cx->x / w) & ~7) + 8) * w;
    138             return 0;
    139     }
    140 
    141     /* Check whether we reached the end of the screen */
    142     if(cx->x && cx->x + w > cx->term_width)
    143     {
    144         cx->x = 0;
    145         cx->y += h;
    146     }
    147 
    148     /* Check whether the current canvas is large enough */
    149     if(cx->x + w > cx->w)
    150         cx->w = cx->x + w < cx->term_width ? cx->x + w : cx->term_width;
    151 
    152     if(cx->y + h > cx->h)
    153         cx->h = cx->y + h;
    154 
    155     cucul_set_canvas_size(cx->cv, cx->w, cx->h);
    156 
    157     /* Render our char */
    158     cucul_putchar(cx->onechar, 0, 0, ch);
    159     cucul_render_canvas(cx->onechar, cx->f, cx->buf, w, h, 4 * w);
    160 
    161     for(y = 0; y < h; y++)
    162        for(x = 0; x < w; x++)
    163     {
    164         unsigned char c = cx->buf[4 * (x + y * w) + 2];
    165 
    166         if(c >= 0xa0)
    167             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "█");
    168         else if(c >= 0x80)
    169             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▓");
    170         else if(c >= 0x40)
    171             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▒");
    172         else if(c >= 0x20)
    173             cucul_putstr(cx->cv, cx->x + x, cx->y + y, "░");
    174     }
    175 
    176     /* Advance cursor */
    177     cx->x += w;
    178 
    179     return 0;
    180 }
    181 
    182 static int end_big(context_t *cx)
    183 {
    184     cucul_free_canvas(cx->onechar);
    185     free(cx->buf);
    186     cucul_free_font(cx->f);
    187 
    188     return 0;
    189 }
    190 
  • toilet/trunk/src/toilet.h

    r1228 r1241  
    2525
    2626    cucul_canvas_t *cv;
     27    cucul_canvas_t *torender;
    2728    unsigned int w, h, ew, eh, x, y;
    2829
    2930    /* Render methods */
    3031    int (*feed)(struct toilet_context *, uint32_t);
     32    int (*flush)(struct toilet_context *);
    3133    int (*end)(struct toilet_context *);
    3234
Note: See TracChangeset for help on using the changeset viewer.