source: libcaca/trunk/test/toilet.c @ 1075

Last change on this file since 1075 was 1075, checked in by Sam Hocevar, 14 years ago
  • Added getopt support to toilet.
  • Property svn:keywords set to Id
File size: 5.9 KB
Line 
1/*
2 *  TOIlet        The Other Implementation’s letters
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: toilet.c 1075 2006-09-21 17:32:27Z sam $
7 *
8 *  This program is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14#include "config.h"
15#include "common.h"
16
17#if !defined(__KERNEL__)
18#   if defined(HAVE_INTTYPES_H)
19#      include <inttypes.h>
20#   endif
21#   if defined(HAVE_GETOPT_H)
22#      include <getopt.h>
23#   endif
24#   include <stdio.h>
25#   include <string.h>
26#   include <stdlib.h>
27#endif
28
29#include "cucul.h"
30#include "caca.h"
31
32/* String to canvas transformations */
33static cucul_canvas_t *cuculize_big(char const *);
34static cucul_canvas_t *cuculize_tiny(char const *);
35
36/* Canvas special effects */
37static void make_gay(cucul_canvas_t *);
38
39int main(int argc, char *argv[])
40{
41    cucul_canvas_t *cv;
42    cucul_buffer_t *buffer;
43
44    char *string = NULL;
45    unsigned int n;
46    int i;
47
48    unsigned flag_gay = 0;
49
50    for(;;)
51    {
52#ifdef HAVE_GETOPT_LONG
53#   define MOREINFO "Try `%s --help' for more information.\n"
54        int option_index = 0;
55        static struct option long_options[] =
56        {
57            /* Long option, needs arg, flag, short option */
58            { "gay", 0, NULL, 'g' },
59            { "help", 0, NULL, 'h' },
60            { "version", 0, NULL, 'v' },
61            { NULL, 0, NULL, 0 }
62        };
63
64        int c = getopt_long(argc, argv, "ghv", long_options, &option_index);
65#else
66#   define MOREINFO "Try `%s -h' for more information.\n"
67        int c = getopt(argc, argv, "ghv");
68#endif
69        if(c == -1)
70            break;
71
72        switch(c)
73        {
74        case 'h': /* --help */
75            printf("Usage: %s [ -ghv ] [ message ]\n", argv[0]);
76#ifdef HAVE_GETOPT_LONG
77            printf("  -g, --gay        add a rainbow effect to the text\n");
78            printf("  -h, --help       display this help and exit\n");
79            printf("  -v, --version    output version information and exit\n");
80#else
81            printf("  -g    add a rainbow effect to the text\n");
82            printf("  -h    display this help and exit\n");
83            printf("  -v    output version information and exit\n");
84#endif
85            return 0;
86        case 'g': /* --gay */
87            flag_gay = 1;
88            break;
89        case 'v': /* --version */
90            printf("TOIlet Copyright 2006 Sam Hocevar %s\n", VERSION);
91            printf("Internet: <sam@zoy.org> Version: 0, date: 21 Sep 2006\n");
92            printf("\n");
93            return 0;
94        case '?':
95            printf(MOREINFO, argv[0]);
96            return 1;
97        default:
98            printf("%s: invalid option -- %i\n", argv[0], c);
99            printf(MOREINFO, argv[0]);
100            return 1;
101        }
102    }
103
104    if(optind >= argc)
105    {
106        printf("%s: too few arguments\n", argv[0]);
107        printf(MOREINFO, argv[0]);
108        return 1;
109    }
110
111    for(i = optind, n = 0; i < argc; i++)
112    {
113        unsigned int l = strlen(argv[i]);
114        if(i > optind)
115            string[n++] = ' ';
116        string = realloc(string, n + l + 1);
117        strcpy(string + n, argv[i]);
118        n += l;
119    }
120
121    /* Do gay stuff with our string (léopard) */
122    cv = cuculize_big(string);
123    if(flag_gay)
124        make_gay(cv);
125
126    /* Output char */
127    buffer = cucul_export_canvas(cv, "utf8");
128    fwrite(cucul_get_buffer_data(buffer),
129           cucul_get_buffer_size(buffer), 1, stdout);
130    cucul_free_buffer(buffer);
131
132    cucul_free_canvas(cv);
133
134    return 0;
135}
136
137static cucul_canvas_t *cuculize_big(char const *string)
138{
139    cucul_canvas_t *cv;
140    cucul_font_t *f;
141    char const * const * fonts;
142    unsigned char *buf;
143    unsigned int n, w, h, x, y, miny, maxy;
144
145    n = strlen(string);
146    cv = cucul_create_canvas(n, 1);
147    cucul_putstr(cv, 0, 0, string);
148
149    fonts = cucul_get_font_list();
150    f = cucul_load_font(fonts[0], 0);
151
152    /* Create our bitmap buffer (32-bit ARGB) */
153    w = cucul_get_canvas_width(cv) * cucul_get_font_width(f);
154    h = cucul_get_canvas_height(cv) * cucul_get_font_height(f);
155    buf = malloc(4 * w * h);
156
157    /* Render the canvas onto our image buffer */
158    cucul_render_canvas(cv, f, buf, w, h, 4 * w);
159
160    /* Free our canvas, and allocate a bigger one */
161    cucul_free_font(f);
162    cucul_free_canvas(cv);
163    cv = cucul_create_canvas(w, h);
164
165    /* Render the image buffer on the canvas */
166    cucul_set_color(cv, CUCUL_COLOR_WHITE, CUCUL_COLOR_TRANSPARENT);
167    cucul_clear_canvas(cv);
168
169    miny = h; maxy = 0;
170
171    for(y = 0; y < h; y++)
172       for(x = 0; x < w; x++)
173    {
174        unsigned char c = buf[4 * (x + y * w) + 2];
175
176        if(c >= 0xa0)
177            cucul_putstr(cv, x, y, "█");
178        else if(c >= 0x80)
179            cucul_putstr(cv, x, y, "▓");
180        else if(c >= 0x40)
181            cucul_putstr(cv, x, y, "▒");
182        else if(c >= 0x20)
183            cucul_putstr(cv, x, y, "░");
184    }
185
186    free(buf);
187
188    return cv;
189}
190
191static cucul_canvas_t *cuculize_tiny(char const *string)
192{
193    unsigned int n = strlen(string);
194    cucul_canvas_t *cv = cucul_create_canvas(n, 1);
195
196    cucul_putstr(cv, 0, 0, string);
197
198    return cv;
199}
200
201static void make_gay(cucul_canvas_t *cv)
202{
203    static unsigned char const rainbow[] =
204    {
205        CUCUL_COLOR_LIGHTMAGENTA,
206        CUCUL_COLOR_LIGHTRED,
207        CUCUL_COLOR_YELLOW,
208        CUCUL_COLOR_LIGHTGREEN,
209        CUCUL_COLOR_LIGHTCYAN,
210        CUCUL_COLOR_LIGHTBLUE,
211    };
212    unsigned int x, y, w, h;
213
214    w = cucul_get_canvas_width(cv);
215    h = cucul_get_canvas_height(cv);
216
217    for(y = 0; y < h; y++)
218        for(x = 0; x < w; x++)
219    {
220        unsigned long int ch = cucul_getchar(cv, x, y);
221        if(ch != (unsigned char)' ')
222        {
223            cucul_set_color(cv, rainbow[(x / 2 + y) % 6],
224                                CUCUL_COLOR_TRANSPARENT);
225            cucul_putchar(cv, x, y, ch);
226        }
227    }
228}
229
Note: See TracBrowser for help on using the repository browser.