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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 
Note: See TracChangeset for help on using the changeset viewer.