diff --git a/src/figlet.c b/src/figlet.c index e43fdcd..fad2c3e 100644 --- a/src/figlet.c +++ b/src/figlet.c @@ -44,16 +44,17 @@ struct figfont unsigned int *lookup; }; -static struct figfont *open_font(void); +static struct figfont *open_font(context_t *cx); static void free_font(struct figfont *); -cucul_canvas_t *render_figlet(uint32_t const *string, unsigned int length) +cucul_canvas_t *render_figlet(context_t *cx, uint32_t const *string, + unsigned int length) { cucul_canvas_t *cv; struct figfont *font; unsigned int x, i, c; - font = open_font(); + font = open_font(cx); if(!font) return NULL; @@ -81,7 +82,7 @@ cucul_canvas_t *render_figlet(uint32_t const *string, unsigned int length) return cv; } -static struct figfont *open_font(void) +static struct figfont *open_font(context_t *cx) { char *data = NULL; char path[2048]; @@ -92,12 +93,12 @@ static struct figfont *open_font(void) unsigned int i, j, size, comment_lines; /* Open font: try .tlf, then .flf */ - snprintf(path, 2047, "%s/%s.tlf", toilet_dir, toilet_font); + snprintf(path, 2047, "%s/%s.tlf", cx->dir, cx->font); path[2047] = '\0'; f = fopen(path, "r"); if(!f) { - snprintf(path, 2047, "%s/%s.flf", toilet_dir, toilet_font); + snprintf(path, 2047, "%s/%s.flf", cx->dir, cx->font); path[2047] = '\0'; f = fopen(path, "r"); if(!f) @@ -227,8 +228,10 @@ static struct figfont *open_font(void) { ch = cucul_getchar(font->image, i, j); + /* Replace hardblanks with U+00A0 NO-BREAK SPACE */ if(ch == font->hardblank) cucul_putchar(font->image, i, j, ch = ' '); + //cucul_putchar(font->image, i, j, ch = 0xa0); if(oldch && ch != oldch) { diff --git a/src/figlet.h b/src/figlet.h index aab93f0..dd0f702 100644 --- a/src/figlet.h +++ b/src/figlet.h @@ -14,5 +14,6 @@ /* * This header defines functions for handling FIGlet fonts. */ -extern cucul_canvas_t *render_figlet(uint32_t const *, unsigned int); +extern cucul_canvas_t *render_figlet(context_t *, uint32_t const *, + unsigned int); diff --git a/src/main.c b/src/main.c index 95981e7..b733c0f 100644 --- a/src/main.c +++ b/src/main.c @@ -36,10 +36,6 @@ #include "figlet.h" #include "filters.h" -char const *toilet_export = "utf8"; -char const *toilet_font = "mono9"; -char const *toilet_dir = "/usr/share/figlet/"; - static void version(void); #if defined(HAVE_GETOPT_H) static void usage(void); @@ -47,19 +43,23 @@ static void usage(void); int main(int argc, char *argv[]) { - cucul_canvas_t *cv; - cucul_buffer_t *buffer; + context_t struct_cx; + context_t *cx = &struct_cx; - uint32_t *string = NULL; - unsigned int length; + cucul_buffer_t *buffer; - int i; + int i, j; unsigned int flag_gay = 0; unsigned int flag_metal = 0; - unsigned int term_width = 80; int infocode = -1; + cx->export = "utf8"; + cx->font = "mono9"; + cx->dir = "/usr/share/figlet/"; + + cx->term_width = 80; + #if defined(HAVE_GETOPT_H) for(;;) { @@ -103,10 +103,10 @@ int main(int argc, char *argv[]) version(); return 0; case 'f': /* --font */ - toilet_font = optarg; + cx->font = optarg; break; case 'd': /* --directory */ - toilet_dir = optarg; + cx->dir = optarg; break; case 'g': /* --gay */ flag_gay = 1; @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) flag_metal = 1; break; case 'w': /* --width */ - term_width = atoi(optarg); + cx->term_width = atoi(optarg); break; case 't': /* --termwidth */ { @@ -125,12 +125,12 @@ int main(int argc, char *argv[]) if((ioctl(1, TIOCGWINSZ, &ws) != -1 || ioctl(2, TIOCGWINSZ, &ws) != -1 || ioctl(0, TIOCGWINSZ, &ws) != -1) && ws.ws_col != 0) - term_width = ws.ws_col; + cx->term_width = ws.ws_col; #endif break; } case 'i': /* --irc */ - toilet_export = "irc"; + cx->export = "irc"; break; case '?': printf(MOREINFO, argv[0]); @@ -157,96 +157,125 @@ int main(int argc, char *argv[]) printf("20201\n"); return 0; case 2: - printf("%s\n", toilet_dir); + printf("%s\n", cx->dir); return 0; case 3: - printf("%s\n", toilet_font); + printf("%s\n", cx->font); return 0; case 4: - printf("%u\n", term_width); + printf("%u\n", cx->term_width); return 0; default: return 0; } +#if 0 if(optind >= argc) - { - printf("%s: too few arguments\n", argv[0]); - printf(MOREINFO, argv[0]); - return 1; - } +#endif - /* Load rest of commandline into a UTF-32 string */ - for(i = optind, length = 0; i < argc; i++) +#if 0 + /* Render string to canvas */ + if(!strcasecmp(cx->font, "mono9")) { - unsigned int k, guessed_len, real_len; + cv = render_big(string, length); + filter_autocrop(cv); + } + else if(!strcasecmp(cx->font, "term")) + cv = render_tiny(string, length); + else + cv = render_figlet(cx, string, length); +#endif - guessed_len = strlen(argv[i]); + init_tiny(cx); - if(i > optind) - string[length++] = (uint32_t)' '; + if(optind >= argc) + { + char buf[10]; + unsigned int len; + uint32_t ch; - string = realloc(string, (length + guessed_len + 1) * 4); + i = 0; - for(k = 0, real_len = 0; k < guessed_len; real_len++) + /* Read from stdin */ + while(!feof(stdin)) { - unsigned int char_len; + buf[i++] = getchar(); + buf[i] = '\0'; - string[length + real_len] = - cucul_utf8_to_utf32(argv[i] + k, &char_len); + ch = cucul_utf8_to_utf32(buf, &len); - k += char_len; - } + if(!len) + continue; - length += real_len; + cx->feed(cx, ch); + i = 0; + } } - - /* Render string to canvas */ - if(!strcasecmp(toilet_font, "mono9")) + else for(i = optind; i < argc; i++) { - cv = render_big(string, length); - filter_autocrop(cv); - } - else if(!strcasecmp(toilet_font, "term")) - cv = render_tiny(string, length); - else - cv = render_figlet(string, length); + /* Read from commandline */ + unsigned int len; - free(string); + if(i != optind) + cx->feed(cx, ' '); - if(!cv) - return -1; + 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 */ if(flag_metal) - filter_metal(cv); + filter_metal(cx->cv); if(flag_gay) - filter_gay(cv); + filter_gay(cx->cv); /* Output char */ - buffer = cucul_export_canvas(cv, toilet_export); + 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(cv); + cucul_free_canvas(cx->cv); return 0; } +#if defined(HAVE_GETOPT_H) +# define USAGE \ + "Usage: toilet [ -ghimtv ] [ -d fontdirectory ]\n" \ + " [ -f fontfile ] [ -w outputwidth ]\n" \ + " [ -I infocode ] [ message ]\n" +#else +# define USAGE "" +#endif + static void version(void) { - printf("TOIlet Copyright 2006 Sam Hocevar %s\n", VERSION); - printf("Internet: Version: 0, date: 21 Sep 2006\n"); - printf("\n"); + printf( + "TOIlet Copyright 2006 Sam Hocevar\n" + "Internet: Version: %s, date: %s\n" + "\n" + "TOIlet, along with the various TOIlet fonts and documentation, may be\n" + "freely copied and distributed.\n" + "\n" + "If you use TOIlet, please send an e-mail message to .\n" + "\n" + "The latest version of TOIlet is available from the web site,\n" + " http://libcaca.zoy.org/toilet.html\n" + "\n" + USAGE, + VERSION, DATE); } #if defined(HAVE_GETOPT_H) static void usage(void) { - printf("Usage: toilet [ -ghimtv ] [ -d fontdirectory ]\n"); - printf(" [ -f fontfile ] [ -w outputwidth ]\n"); - printf(" [ -I infocode ] [ message ]\n"); + printf(USAGE); # ifdef HAVE_GETOPT_LONG printf(" -f, --font select the font\n"); printf(" -d, --directory specify font directory\n"); diff --git a/src/render.c b/src/render.c index f88ce83..b97e9cd 100644 --- a/src/render.c +++ b/src/render.c @@ -23,8 +23,76 @@ #include #include +#include "toilet.h" #include "render.h" +static int feed_tiny(context_t *, uint32_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->end = end_tiny; + + return 0; +} + +static int feed_tiny(context_t *cx, uint32_t ch) +{ + if(cx->x >= cx->w) + cx->w = cx->x + 1; + + if(cx->y >= cx->h) + cx->h = cx->y + 1; + + switch(ch) + { + case (uint32_t)'\r': + return 0; + case (uint32_t)'\n': + cx->x = 0; + cx->y++; + break; + case (uint32_t)'\t': + cx->x = (cx->x & ~7) + 8; + break; + default: + cucul_putchar(cx->cv, cx->x, cx->y, ch); + cx->x++; + break; + } + + if(cx->x >= cx->term_width) + { + cx->x = 0; + cx->y++; + } + + if(cx->x >= cx->ew) + cx->ew = cx->ew + cx->ew / 2; + + if(cx->y >= cx->eh) + cx->eh = cx->eh + cx->eh / 2; + + cucul_set_canvas_size(cx->cv, cx->ew, cx->eh); + + return 0; +} + +static int end_tiny(context_t *cx) +{ + cucul_set_canvas_size(cx->cv, cx->w, cx->h); + + return 0; +} + +#if 0 cucul_canvas_t *render_big(uint32_t const *string, unsigned int length) { cucul_canvas_t *cv; @@ -79,15 +147,5 @@ cucul_canvas_t *render_big(uint32_t const *string, unsigned int length) return cv; } - -cucul_canvas_t *render_tiny(uint32_t const *string, unsigned int length) -{ - unsigned int x; - cucul_canvas_t *cv = cucul_create_canvas(length, 1); - - for(x = 0; x < length; x++) - cucul_putchar(cv, x, 0, string[x]); - - return cv; -} +#endif diff --git a/src/render.h b/src/render.h index e693d10..b46300e 100644 --- a/src/render.h +++ b/src/render.h @@ -15,6 +15,5 @@ * This header defines text to canvas rendering functions. */ -extern cucul_canvas_t *render_big(uint32_t const *, unsigned int); -extern cucul_canvas_t *render_tiny(uint32_t const *, unsigned int); +extern int init_tiny(context_t *); diff --git a/src/toilet.h b/src/toilet.h index a585f31..0aa078c 100644 --- a/src/toilet.h +++ b/src/toilet.h @@ -15,7 +15,20 @@ * This header defines global variables. */ -extern char const *toilet_export; -extern char const *toilet_font; -extern char const *toilet_dir; +struct toilet_context +{ + char const *export; + char const *font; + char const *dir; + + unsigned int term_width; + + cucul_canvas_t *cv; + unsigned int w, h, ew, eh, x, y; + + int (*feed)(struct toilet_context *, uint32_t); + int (*end)(struct toilet_context *); +}; + +typedef struct toilet_context context_t;