From c325cb1c8182fb51b1e800f1c22a1aacecfa8fce Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Mon, 13 Nov 2006 01:02:05 +0000 Subject: [PATCH] * Support for ANSI escape codes in the input: http://zoy.org/~sam/toilet-ansi.png http://zoy.org/~sam/toilet-ansi2.png * Empty lines are currently broken. --- src/figlet.c | 15 +++++++--- src/render.c | 82 +++++++++++++++++++++++++++++++++++++--------------- src/term.c | 5 ++-- src/toilet.h | 2 +- 4 files changed, 74 insertions(+), 30 deletions(-) diff --git a/src/figlet.c b/src/figlet.c index 2ee09c7..d8ea556 100644 --- a/src/figlet.c +++ b/src/figlet.c @@ -32,7 +32,7 @@ #define STD_GLYPHS (127 - 32) #define EXT_GLYPHS (STD_GLYPHS + 7) -static int feed_figlet(context_t *, uint32_t); +static int feed_figlet(context_t *, uint32_t, uint32_t); static int flush_figlet(context_t *); static int end_figlet(context_t *); @@ -50,7 +50,7 @@ int init_figlet(context_t *cx) return 0; } -static int feed_figlet(context_t *cx, uint32_t ch) +static int feed_figlet(context_t *cx, uint32_t ch, uint32_t attr) { unsigned int c, w, h, x, y; @@ -90,14 +90,21 @@ static int feed_figlet(context_t *cx, uint32_t ch) if(cx->y + h > cx->h) cx->h = cx->y + h; + if(attr) + cucul_set_attr(cx->cv, attr); cucul_set_canvas_size(cx->cv, cx->w, cx->h); /* Render our char (FIXME: create a rect-aware cucul_blit_canvas?) */ for(y = 0; y < h; y++) for(x = 0; x < w; x++) { - uint32_t tmp = cucul_get_char(cx->image, x, y + c * cx->height); - cucul_put_char(cx->cv, cx->x + x, cx->y + y, tmp); + uint32_t tmpch = cucul_get_char(cx->image, x, y + c * cx->height); + //uint32_t tmpat = cucul_get_attr(cx->image, x, y + c * cx->height); + /* FIXME: this could be changed to cucul_put_attr() when the + * function is fixed in libcucul */ + //cucul_set_attr(cx->cv, tmpat); + cucul_put_char(cx->cv, cx->x + x, cx->y + y, tmpch); + //cucul_put_attr(cx->cv, cx->x + x, cx->y + y, tmpat); } /* Advance cursor */ diff --git a/src/render.c b/src/render.c index 936086f..1cfa978 100644 --- a/src/render.c +++ b/src/render.c @@ -46,47 +46,83 @@ int render_init(context_t *cx) int render_stdin(context_t *cx) { - char buf[10]; - unsigned int i = 0, len; - uint32_t ch; + cucul_canvas_t *cv; + char *line; + unsigned int i, len; + + /* FIXME: we can't read longer lines */ + len = 1024; + line = malloc(len); + cv = cucul_create_canvas(0, 0); /* Read from stdin */ while(!feof(stdin)) { - buf[i++] = getchar(); - buf[i] = '\0'; - - ch = cucul_utf8_to_utf32(buf, &len); - - if(!len) - continue; + if(!fgets(line, len, stdin)) + break; - cx->feed(cx, ch); - i = 0; + cucul_set_canvas_size(cv, 0, 0); + cucul_import_memory(cv, line, strlen(line), "utf8"); + for(i = 0; i < cucul_get_canvas_width(cv); i++) + { + uint32_t ch = cucul_get_char(cv, i, 0); + uint32_t at = cucul_get_attr(cv, i, 0); + cx->feed(cx, ch, at); + if(cucul_utf32_is_fullwidth(ch)) i++; + } - if(ch == '\n') - render_flush(cx); + render_flush(cx); } + free(line); + return 0; } int render_list(context_t *cx, unsigned int argc, char *argv[]) { - unsigned int i, j; + cucul_canvas_t *cv; + unsigned int i, j, len; + char *parser = NULL; - for(i = 0; i < argc; i++) + cv = cucul_create_canvas(0, 0); + + for(j = 0; j < argc; ) { - /* Read from commandline */ - unsigned int len; + char *cr; - if(i) - cx->feed(cx, ' '); + if(!parser) + { + if(j) + cx->feed(cx, ' ', 0); + parser = argv[j]; + } + + cr = strchr(parser, '\n'); + if(cr) + len = (cr - parser) + 1; + else + len = strlen(parser); + + cucul_set_canvas_size(cv, 0, 0); + cucul_import_memory(cv, parser, len, "utf8"); + for(i = 0; i < cucul_get_canvas_width(cv); i++) + { + uint32_t ch = cucul_get_char(cv, i, 0); + uint32_t at = cucul_get_attr(cv, i, 0); + cx->feed(cx, ch, at); + if(cucul_utf32_is_fullwidth(ch)) i++; + } - for(j = 0; argv[i][j];) + if(cr) + { + parser += len; + render_flush(cx); + } + else { - cx->feed(cx, cucul_utf8_to_utf32(argv[i] + j, &len)); - j += len; + parser = NULL; + j++; } } diff --git a/src/term.c b/src/term.c index 131ce88..97b5f57 100644 --- a/src/term.c +++ b/src/term.c @@ -26,7 +26,7 @@ #include "toilet.h" #include "render.h" -static int feed_tiny(context_t *, uint32_t); +static int feed_tiny(context_t *, uint32_t, uint32_t); static int flush_tiny(context_t *); static int end_tiny(context_t *); @@ -42,7 +42,7 @@ int init_tiny(context_t *cx) return 0; } -static int feed_tiny(context_t *cx, uint32_t ch) +static int feed_tiny(context_t *cx, uint32_t ch, uint32_t attr) { switch(ch) { @@ -79,6 +79,7 @@ static int feed_tiny(context_t *cx, uint32_t ch) cx->eh = cx->eh + cx->eh / 2; } + cucul_set_attr(cx->cv, attr); cucul_set_canvas_size(cx->cv, cx->ew, cx->eh); cucul_put_char(cx->cv, cx->x, cx->y, ch); diff --git a/src/toilet.h b/src/toilet.h index 1128462..3723240 100644 --- a/src/toilet.h +++ b/src/toilet.h @@ -28,7 +28,7 @@ struct toilet_context unsigned int w, h, ew, eh, x, y, lines; /* Render methods */ - int (*feed)(struct toilet_context *, uint32_t); + int (*feed)(struct toilet_context *, uint32_t, uint32_t); int (*flush)(struct toilet_context *); int (*end)(struct toilet_context *);