* Make stdin input line-aware so that we don't have to wait until EOF to
display stuff. * Reorganise stuff and fix memory leaks.
This commit is contained in:
parent
3549ea3988
commit
99f3252c73
11 changed files with 358 additions and 221 deletions
|
@ -5,7 +5,7 @@ toilet_SOURCES = main.c \
|
||||||
io.c io.h \
|
io.c io.h \
|
||||||
render.c render.h \
|
render.c render.h \
|
||||||
filter.c filter.h \
|
filter.c filter.h \
|
||||||
figlet.c figlet.h
|
term.c mono9.c figlet.c
|
||||||
toilet_CFLAGS = `pkg-config --cflags cucul`
|
toilet_CFLAGS = `pkg-config --cflags cucul`
|
||||||
toilet_LDFLAGS = `pkg-config --libs cucul` @GETOPT_LIBS@ @ZLIB_LIBS@
|
toilet_LDFLAGS = `pkg-config --libs cucul` @GETOPT_LIBS@ @ZLIB_LIBS@
|
||||||
|
|
||||||
|
|
17
src/figlet.c
17
src/figlet.c
|
@ -26,13 +26,14 @@
|
||||||
#include <cucul.h>
|
#include <cucul.h>
|
||||||
|
|
||||||
#include "toilet.h"
|
#include "toilet.h"
|
||||||
|
#include "render.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "figlet.h"
|
|
||||||
|
|
||||||
#define STD_GLYPHS (127 - 32)
|
#define STD_GLYPHS (127 - 32)
|
||||||
#define EXT_GLYPHS (STD_GLYPHS + 7)
|
#define EXT_GLYPHS (STD_GLYPHS + 7)
|
||||||
|
|
||||||
static int feed_figlet(context_t *, uint32_t);
|
static int feed_figlet(context_t *, uint32_t);
|
||||||
|
static int flush_figlet(context_t *);
|
||||||
static int end_figlet(context_t *);
|
static int end_figlet(context_t *);
|
||||||
|
|
||||||
static int open_font(context_t *cx);
|
static int open_font(context_t *cx);
|
||||||
|
@ -47,6 +48,7 @@ int init_figlet(context_t *cx)
|
||||||
cx->cv = cucul_create_canvas(1, 1);
|
cx->cv = cucul_create_canvas(1, 1);
|
||||||
|
|
||||||
cx->feed = feed_figlet;
|
cx->feed = feed_figlet;
|
||||||
|
cx->flush = flush_figlet;
|
||||||
cx->end = end_figlet;
|
cx->end = end_figlet;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -108,9 +110,22 @@ static int feed_figlet(context_t *cx, uint32_t ch)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int flush_figlet(context_t *cx)
|
||||||
|
{
|
||||||
|
cx->torender = cx->cv;
|
||||||
|
cucul_set_canvas_size(cx->torender, cx->w, cx->h);
|
||||||
|
|
||||||
|
cx->x = cx->y = 0;
|
||||||
|
cx->w = cx->h = 0;
|
||||||
|
cx->cv = cucul_create_canvas(1, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int end_figlet(context_t *cx)
|
static int end_figlet(context_t *cx)
|
||||||
{
|
{
|
||||||
cucul_free_canvas(cx->image);
|
cucul_free_canvas(cx->image);
|
||||||
|
cucul_free_canvas(cx->cv);
|
||||||
free(cx->lookup);
|
free(cx->lookup);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
18
src/figlet.h
18
src/figlet.h
|
@ -1,18 +0,0 @@
|
||||||
/*
|
|
||||||
* TOIlet The Other Implementation’s letters
|
|
||||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the Do What The Fuck You Want To
|
|
||||||
* Public License, Version 2, as published by Sam Hocevar. See
|
|
||||||
* http://sam.zoy.org/wtfpl/COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This header defines functions for handling FIGlet fonts.
|
|
||||||
*/
|
|
||||||
extern int init_figlet(context_t *);
|
|
||||||
|
|
|
@ -92,7 +92,14 @@ int filter_do(context_t *cx)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for(i = 0; i < cx->nfilters; i++)
|
for(i = 0; i < cx->nfilters; i++)
|
||||||
cx->filters[i](cx->cv);
|
cx->filters[i](cx->torender);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filter_end(context_t *cx)
|
||||||
|
{
|
||||||
|
free(cx->filters);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,5 @@
|
||||||
|
|
||||||
extern int filter_add(context_t *, char const *);
|
extern int filter_add(context_t *, char const *);
|
||||||
extern int filter_do(context_t *);
|
extern int filter_do(context_t *);
|
||||||
|
extern int filter_end(context_t *);
|
||||||
|
|
||||||
|
|
68
src/main.c
68
src/main.c
|
@ -27,13 +27,11 @@
|
||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <cucul.h>
|
#include <cucul.h>
|
||||||
|
|
||||||
#include "toilet.h"
|
#include "toilet.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "figlet.h"
|
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
|
||||||
static void version(void);
|
static void version(void);
|
||||||
|
@ -46,10 +44,6 @@ int main(int argc, char *argv[])
|
||||||
context_t struct_cx;
|
context_t struct_cx;
|
||||||
context_t *cx = &struct_cx;
|
context_t *cx = &struct_cx;
|
||||||
|
|
||||||
cucul_buffer_t *buffer;
|
|
||||||
|
|
||||||
int i, j, ret;
|
|
||||||
|
|
||||||
int infocode = -1;
|
int infocode = -1;
|
||||||
|
|
||||||
cx->export = "utf8";
|
cx->export = "utf8";
|
||||||
|
@ -183,66 +177,16 @@ int main(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcasecmp(cx->font, "mono9"))
|
if(render_init(cx) < 0)
|
||||||
ret = init_big(cx);
|
|
||||||
else if(!strcasecmp(cx->font, "term"))
|
|
||||||
ret = init_tiny(cx);
|
|
||||||
else
|
|
||||||
ret = init_figlet(cx);
|
|
||||||
|
|
||||||
if(ret)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(optind >= argc)
|
if(optind >= argc)
|
||||||
{
|
render_stdin(cx);
|
||||||
char buf[10];
|
else
|
||||||
unsigned int len;
|
render_list(cx, argc - optind, argv + optind);
|
||||||
uint32_t ch;
|
|
||||||
|
|
||||||
i = 0;
|
render_end(cx);
|
||||||
|
filter_end(cx);
|
||||||
/* Read from stdin */
|
|
||||||
while(!feof(stdin))
|
|
||||||
{
|
|
||||||
buf[i++] = getchar();
|
|
||||||
buf[i] = '\0';
|
|
||||||
|
|
||||||
ch = cucul_utf8_to_utf32(buf, &len);
|
|
||||||
|
|
||||||
if(!len)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cx->feed(cx, ch);
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else for(i = optind; i < argc; i++)
|
|
||||||
{
|
|
||||||
/* Read from commandline */
|
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
if(i != optind)
|
|
||||||
cx->feed(cx, ' ');
|
|
||||||
|
|
||||||
for(j = 0; argv[i][j];)
|
|
||||||
{
|
|
||||||
cx->feed(cx, cucul_utf8_to_utf32(argv[i] + j, &len));
|
|
||||||
j += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cx->end(cx);
|
|
||||||
|
|
||||||
/* Apply optional effects to our string */
|
|
||||||
filter_do(cx);
|
|
||||||
|
|
||||||
/* Output char */
|
|
||||||
buffer = cucul_export_canvas(cx->cv, cx->export);
|
|
||||||
fwrite(cucul_get_buffer_data(buffer),
|
|
||||||
cucul_get_buffer_size(buffer), 1, stdout);
|
|
||||||
cucul_free_buffer(buffer);
|
|
||||||
|
|
||||||
cucul_free_canvas(cx->cv);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
136
src/mono9.c
Normal file
136
src/mono9.c
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* TOIlet The Other Implementation’s letters
|
||||||
|
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the Do What The Fuck You Want To
|
||||||
|
* Public License, Version 2, as published by Sam Hocevar. See
|
||||||
|
* http://sam.zoy.org/wtfpl/COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains text to canvas rendering functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_INTTYPES_H)
|
||||||
|
# include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cucul.h>
|
||||||
|
|
||||||
|
#include "toilet.h"
|
||||||
|
#include "render.h"
|
||||||
|
|
||||||
|
static int feed_big(context_t *, uint32_t);
|
||||||
|
static int flush_big(context_t *);
|
||||||
|
static int end_big(context_t *);
|
||||||
|
|
||||||
|
int init_big(context_t *cx)
|
||||||
|
{
|
||||||
|
char const * const * fonts;
|
||||||
|
|
||||||
|
fonts = cucul_get_font_list();
|
||||||
|
cx->f = cucul_load_font(fonts[0], 0);
|
||||||
|
cx->buf = malloc(4 * cucul_get_font_width(cx->f)
|
||||||
|
* cucul_get_font_height(cx->f));
|
||||||
|
cx->onechar = cucul_create_canvas(1, 1);
|
||||||
|
cucul_set_color(cx->onechar, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
|
||||||
|
|
||||||
|
cx->x = cx->y = 0;
|
||||||
|
cx->w = cx->h = 0;
|
||||||
|
cx->cv = cucul_create_canvas(1, 1);
|
||||||
|
|
||||||
|
cx->feed = feed_big;
|
||||||
|
cx->flush = flush_big;
|
||||||
|
cx->end = end_big;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int feed_big(context_t *cx, uint32_t ch)
|
||||||
|
{
|
||||||
|
unsigned int w = cucul_get_font_width(cx->f);
|
||||||
|
unsigned int h = cucul_get_font_height(cx->f);
|
||||||
|
unsigned int x, y;
|
||||||
|
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case (uint32_t)'\r':
|
||||||
|
return 0;
|
||||||
|
case (uint32_t)'\n':
|
||||||
|
cx->x = 0;
|
||||||
|
cx->y += h;
|
||||||
|
return 0;
|
||||||
|
case (uint32_t)'\t':
|
||||||
|
cx->x = (((cx->x / w) & ~7) + 8) * w;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether we reached the end of the screen */
|
||||||
|
if(cx->x && cx->x + w > cx->term_width)
|
||||||
|
{
|
||||||
|
cx->x = 0;
|
||||||
|
cx->y += h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether the current canvas is large enough */
|
||||||
|
if(cx->x + w > cx->w)
|
||||||
|
cx->w = cx->x + w < cx->term_width ? cx->x + w : cx->term_width;
|
||||||
|
|
||||||
|
if(cx->y + h > cx->h)
|
||||||
|
cx->h = cx->y + h;
|
||||||
|
|
||||||
|
cucul_set_canvas_size(cx->cv, cx->w, cx->h);
|
||||||
|
|
||||||
|
/* Render our char */
|
||||||
|
cucul_putchar(cx->onechar, 0, 0, ch);
|
||||||
|
cucul_render_canvas(cx->onechar, cx->f, cx->buf, w, h, 4 * w);
|
||||||
|
|
||||||
|
for(y = 0; y < h; y++)
|
||||||
|
for(x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
unsigned char c = cx->buf[4 * (x + y * w) + 2];
|
||||||
|
|
||||||
|
if(c >= 0xa0)
|
||||||
|
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "█");
|
||||||
|
else if(c >= 0x80)
|
||||||
|
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▓");
|
||||||
|
else if(c >= 0x40)
|
||||||
|
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▒");
|
||||||
|
else if(c >= 0x20)
|
||||||
|
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "░");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance cursor */
|
||||||
|
cx->x += w;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flush_big(context_t *cx)
|
||||||
|
{
|
||||||
|
cx->torender = cx->cv;
|
||||||
|
cucul_set_canvas_size(cx->torender, cx->w, cx->h);
|
||||||
|
|
||||||
|
cx->x = cx->y = 0;
|
||||||
|
cx->w = cx->h = 0;
|
||||||
|
cx->cv = cucul_create_canvas(1, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int end_big(context_t *cx)
|
||||||
|
{
|
||||||
|
cucul_free_canvas(cx->onechar);
|
||||||
|
cucul_free_canvas(cx->cv);
|
||||||
|
free(cx->buf);
|
||||||
|
cucul_free_font(cx->f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
206
src/render.c
206
src/render.c
|
@ -21,169 +21,99 @@
|
||||||
# include <inttypes.h>
|
# include <inttypes.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <cucul.h>
|
#include <cucul.h>
|
||||||
|
|
||||||
#include "toilet.h"
|
#include "toilet.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
static int feed_tiny(context_t *, uint32_t);
|
int render_init(context_t *cx)
|
||||||
static int end_tiny(context_t *);
|
|
||||||
|
|
||||||
static int feed_big(context_t *, uint32_t);
|
|
||||||
static int end_big(context_t *);
|
|
||||||
|
|
||||||
int init_tiny(context_t *cx)
|
|
||||||
{
|
{
|
||||||
cx->ew = 16;
|
if(!strcasecmp(cx->font, "mono9"))
|
||||||
cx->eh = 2;
|
return init_big(cx);
|
||||||
cx->x = cx->y = 0;
|
|
||||||
cx->w = cx->h = 0;
|
|
||||||
cx->cv = cucul_create_canvas(cx->ew, cx->eh);
|
|
||||||
|
|
||||||
cx->feed = feed_tiny;
|
if(!strcasecmp(cx->font, "term"))
|
||||||
cx->end = end_tiny;
|
return init_tiny(cx);
|
||||||
|
|
||||||
|
return init_figlet(cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int render_stdin(context_t *cx)
|
||||||
|
{
|
||||||
|
char buf[10];
|
||||||
|
unsigned int i = 0, len;
|
||||||
|
uint32_t ch;
|
||||||
|
|
||||||
|
/* Read from stdin */
|
||||||
|
while(!feof(stdin))
|
||||||
|
{
|
||||||
|
buf[i++] = getchar();
|
||||||
|
buf[i] = '\0';
|
||||||
|
|
||||||
|
ch = cucul_utf8_to_utf32(buf, &len);
|
||||||
|
|
||||||
|
if(!len)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cx->feed(cx, ch);
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
if(ch == '\n')
|
||||||
|
render_line(cx);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int feed_tiny(context_t *cx, uint32_t ch)
|
int render_list(context_t *cx, unsigned int argc, char *argv[])
|
||||||
{
|
{
|
||||||
switch(ch)
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for(i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
case (uint32_t)'\r':
|
/* Read from commandline */
|
||||||
return 0;
|
unsigned int len;
|
||||||
case (uint32_t)'\n':
|
|
||||||
cx->x = 0;
|
if(i)
|
||||||
cx->y++;
|
cx->feed(cx, ' ');
|
||||||
return 0;
|
|
||||||
case (uint32_t)'\t':
|
for(j = 0; argv[i][j];)
|
||||||
cx->x = (cx->x & ~7) + 8;
|
{
|
||||||
return 0;
|
cx->feed(cx, cucul_utf8_to_utf32(argv[i] + j, &len));
|
||||||
|
j += len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether we reached the end of the screen */
|
render_line(cx);
|
||||||
if(cx->x && cx->x + 1 > cx->term_width)
|
|
||||||
{
|
|
||||||
cx->x = 0;
|
|
||||||
cx->y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether the current canvas is large enough */
|
|
||||||
if(cx->x + 1 > cx->w)
|
|
||||||
{
|
|
||||||
cx->w = cx->x + 1 < cx->term_width ? cx->x + 1 : cx->term_width;
|
|
||||||
if(cx->w > cx->ew)
|
|
||||||
cx->ew = cx->ew + cx->ew / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cx->y + 1 > cx->h)
|
|
||||||
{
|
|
||||||
cx->h = cx->y + 1;
|
|
||||||
if(cx->h > cx->eh)
|
|
||||||
cx->eh = cx->eh + cx->eh / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
cucul_set_canvas_size(cx->cv, cx->ew, cx->eh);
|
|
||||||
|
|
||||||
cucul_putchar(cx->cv, cx->x, cx->y, ch);
|
|
||||||
cx->x++;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int end_tiny(context_t *cx)
|
int render_line(context_t *cx)
|
||||||
{
|
{
|
||||||
cucul_set_canvas_size(cx->cv, cx->w, cx->h);
|
cucul_buffer_t *buffer;
|
||||||
|
|
||||||
|
/* Flush current line */
|
||||||
|
cx->flush(cx);
|
||||||
|
|
||||||
|
/* Apply optional effects to our string */
|
||||||
|
filter_do(cx);
|
||||||
|
|
||||||
|
/* Output line */
|
||||||
|
buffer = cucul_export_canvas(cx->torender, cx->export);
|
||||||
|
fwrite(cucul_get_buffer_data(buffer),
|
||||||
|
cucul_get_buffer_size(buffer), 1, stdout);
|
||||||
|
cucul_free_buffer(buffer);
|
||||||
|
cucul_free_canvas(cx->torender);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_big(context_t *cx)
|
int render_end(context_t *cx)
|
||||||
{
|
{
|
||||||
char const * const * fonts;
|
cx->end(cx);
|
||||||
|
|
||||||
fonts = cucul_get_font_list();
|
|
||||||
cx->f = cucul_load_font(fonts[0], 0);
|
|
||||||
cx->buf = malloc(4 * cucul_get_font_width(cx->f)
|
|
||||||
* cucul_get_font_height(cx->f));
|
|
||||||
cx->onechar = cucul_create_canvas(1, 1);
|
|
||||||
cucul_set_color(cx->onechar, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
|
|
||||||
|
|
||||||
cx->x = cx->y = 0;
|
|
||||||
cx->w = cx->h = 0;
|
|
||||||
cx->cv = cucul_create_canvas(1, 1);
|
|
||||||
|
|
||||||
cx->feed = feed_big;
|
|
||||||
cx->end = end_big;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int feed_big(context_t *cx, uint32_t ch)
|
|
||||||
{
|
|
||||||
unsigned int w = cucul_get_font_width(cx->f);
|
|
||||||
unsigned int h = cucul_get_font_height(cx->f);
|
|
||||||
unsigned int x, y;
|
|
||||||
|
|
||||||
switch(ch)
|
|
||||||
{
|
|
||||||
case (uint32_t)'\r':
|
|
||||||
return 0;
|
|
||||||
case (uint32_t)'\n':
|
|
||||||
cx->x = 0;
|
|
||||||
cx->y += h;
|
|
||||||
return 0;
|
|
||||||
case (uint32_t)'\t':
|
|
||||||
cx->x = (((cx->x / w) & ~7) + 8) * w;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether we reached the end of the screen */
|
|
||||||
if(cx->x && cx->x + w > cx->term_width)
|
|
||||||
{
|
|
||||||
cx->x = 0;
|
|
||||||
cx->y += h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether the current canvas is large enough */
|
|
||||||
if(cx->x + w > cx->w)
|
|
||||||
cx->w = cx->x + w < cx->term_width ? cx->x + w : cx->term_width;
|
|
||||||
|
|
||||||
if(cx->y + h > cx->h)
|
|
||||||
cx->h = cx->y + h;
|
|
||||||
|
|
||||||
cucul_set_canvas_size(cx->cv, cx->w, cx->h);
|
|
||||||
|
|
||||||
/* Render our char */
|
|
||||||
cucul_putchar(cx->onechar, 0, 0, ch);
|
|
||||||
cucul_render_canvas(cx->onechar, cx->f, cx->buf, w, h, 4 * w);
|
|
||||||
|
|
||||||
for(y = 0; y < h; y++)
|
|
||||||
for(x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
unsigned char c = cx->buf[4 * (x + y * w) + 2];
|
|
||||||
|
|
||||||
if(c >= 0xa0)
|
|
||||||
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "█");
|
|
||||||
else if(c >= 0x80)
|
|
||||||
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▓");
|
|
||||||
else if(c >= 0x40)
|
|
||||||
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▒");
|
|
||||||
else if(c >= 0x20)
|
|
||||||
cucul_putstr(cx->cv, cx->x + x, cx->y + y, "░");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance cursor */
|
|
||||||
cx->x += w;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int end_big(context_t *cx)
|
|
||||||
{
|
|
||||||
cucul_free_canvas(cx->onechar);
|
|
||||||
free(cx->buf);
|
|
||||||
cucul_free_font(cx->f);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,11 @@
|
||||||
|
|
||||||
extern int init_tiny(context_t *);
|
extern int init_tiny(context_t *);
|
||||||
extern int init_big(context_t *);
|
extern int init_big(context_t *);
|
||||||
|
extern int init_figlet(context_t *);
|
||||||
|
|
||||||
|
extern int render_init(context_t *);
|
||||||
|
extern int render_stdin(context_t *);
|
||||||
|
extern int render_list(context_t *, unsigned int, char *[]);
|
||||||
|
extern int render_line(context_t *);
|
||||||
|
extern int render_end(context_t *);
|
||||||
|
|
||||||
|
|
113
src/term.c
Normal file
113
src/term.c
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* TOIlet The Other Implementation’s letters
|
||||||
|
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the Do What The Fuck You Want To
|
||||||
|
* Public License, Version 2, as published by Sam Hocevar. See
|
||||||
|
* http://sam.zoy.org/wtfpl/COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains text to canvas rendering functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_INTTYPES_H)
|
||||||
|
# include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cucul.h>
|
||||||
|
|
||||||
|
#include "toilet.h"
|
||||||
|
#include "render.h"
|
||||||
|
|
||||||
|
static int feed_tiny(context_t *, uint32_t);
|
||||||
|
static int flush_tiny(context_t *);
|
||||||
|
static int end_tiny(context_t *);
|
||||||
|
|
||||||
|
int init_tiny(context_t *cx)
|
||||||
|
{
|
||||||
|
cx->ew = 16;
|
||||||
|
cx->eh = 2;
|
||||||
|
cx->x = cx->y = 0;
|
||||||
|
cx->w = cx->h = 0;
|
||||||
|
cx->cv = cucul_create_canvas(cx->ew, cx->eh);
|
||||||
|
|
||||||
|
cx->feed = feed_tiny;
|
||||||
|
cx->flush = flush_tiny;
|
||||||
|
cx->end = end_tiny;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int feed_tiny(context_t *cx, uint32_t ch)
|
||||||
|
{
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case (uint32_t)'\r':
|
||||||
|
return 0;
|
||||||
|
case (uint32_t)'\n':
|
||||||
|
cx->x = 0;
|
||||||
|
cx->y++;
|
||||||
|
return 0;
|
||||||
|
case (uint32_t)'\t':
|
||||||
|
cx->x = (cx->x & ~7) + 8;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether we reached the end of the screen */
|
||||||
|
if(cx->x && cx->x + 1 > cx->term_width)
|
||||||
|
{
|
||||||
|
cx->x = 0;
|
||||||
|
cx->y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether the current canvas is large enough */
|
||||||
|
if(cx->x + 1 > cx->w)
|
||||||
|
{
|
||||||
|
cx->w = cx->x + 1 < cx->term_width ? cx->x + 1 : cx->term_width;
|
||||||
|
if(cx->w > cx->ew)
|
||||||
|
cx->ew = cx->ew + cx->ew / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cx->y + 1 > cx->h)
|
||||||
|
{
|
||||||
|
cx->h = cx->y + 1;
|
||||||
|
if(cx->h > cx->eh)
|
||||||
|
cx->eh = cx->eh + cx->eh / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
cucul_set_canvas_size(cx->cv, cx->ew, cx->eh);
|
||||||
|
|
||||||
|
cucul_putchar(cx->cv, cx->x, cx->y, ch);
|
||||||
|
cx->x++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flush_tiny(context_t *cx)
|
||||||
|
{
|
||||||
|
cx->torender = cx->cv;
|
||||||
|
cucul_set_canvas_size(cx->torender, cx->w, cx->h);
|
||||||
|
|
||||||
|
cx->ew = 16;
|
||||||
|
cx->eh = 2;
|
||||||
|
cx->x = cx->y = 0;
|
||||||
|
cx->w = cx->h = 0;
|
||||||
|
cx->cv = cucul_create_canvas(cx->ew, cx->eh);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int end_tiny(context_t *cx)
|
||||||
|
{
|
||||||
|
cucul_free_canvas(cx->cv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -24,10 +24,12 @@ struct toilet_context
|
||||||
unsigned int term_width;
|
unsigned int term_width;
|
||||||
|
|
||||||
cucul_canvas_t *cv;
|
cucul_canvas_t *cv;
|
||||||
|
cucul_canvas_t *torender;
|
||||||
unsigned int w, h, ew, eh, x, y;
|
unsigned int w, h, ew, eh, x, y;
|
||||||
|
|
||||||
/* Render methods */
|
/* Render methods */
|
||||||
int (*feed)(struct toilet_context *, uint32_t);
|
int (*feed)(struct toilet_context *, uint32_t);
|
||||||
|
int (*flush)(struct toilet_context *);
|
||||||
int (*end)(struct toilet_context *);
|
int (*end)(struct toilet_context *);
|
||||||
|
|
||||||
/* Used by the big driver */
|
/* Used by the big driver */
|
||||||
|
|
Loading…
Reference in a new issue