source: toilet/trunk/tools/caca2tlf.c @ 2988

Last change on this file since 2988 was 2988, checked in by sam, 5 years ago

Port toilet to the unified libcaca 0.99.beta15 API.

  • Property svn:keywords set to Id
File size: 6.4 KB
Line 
1/*
2 *  caca2tlf      Create a TOIlet font from a libcaca font
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id$
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 * This is the main program entry point.
17 */
18
19#include "config.h"
20
21#if defined(HAVE_INTTYPES_H)
22#   include <inttypes.h>
23#endif
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27#include <caca.h>
28
29enum mode { GRAY, HALFBLOCKS, QUARTERBLOCKS } mode;
30
31static void list_fonts(void);
32static void add_char(unsigned long int);
33
34caca_font_t *f;
35caca_canvas_t *out, *onechar;
36uint32_t const *blocks;
37uint8_t * image;
38unsigned int w, h, gw, fgw, gh, iw, ih;
39
40int main(int argc, char *argv[])
41{
42    char *fontname, *extraflag;
43    unsigned int b, i;
44
45    if(argc < 2)
46    {
47        fprintf(stderr, "Usage: %s [--half|--quarter] <font>\n", argv[0]);
48        list_fonts();
49        return -1;
50    }
51
52    if(!strcmp(argv[1], "--half") && argc >= 3)
53    {
54        extraflag = "--half ";
55        mode = HALFBLOCKS;
56        fontname = argv[2];
57    }
58    else if(!strcmp(argv[1], "--quarter") && argc >= 3)
59    {
60        extraflag = "--quarter ";
61        mode = QUARTERBLOCKS;
62        fontname = argv[2];
63    }
64    else
65    {
66        extraflag = "";
67        mode = GRAY;
68        fontname = argv[1];
69    }
70
71    f = caca_load_font(fontname, 0);
72
73    if(!f)
74    {
75        fprintf(stderr, "Font \"%s\" not found.\n", argv[1]);
76        list_fonts();
77        return -2;
78    }
79
80    w = caca_get_font_width(f);
81    h = caca_get_font_height(f);
82    iw = w * 2 + 1;
83    ih = h + 1;
84    switch(mode)
85    {
86    case GRAY:
87        gw = w;
88        fgw = w * 2;
89        gh = h;
90        break;
91    case HALFBLOCKS:
92        gw = w;
93        fgw = w * 2;
94        gh = (h + 1) / 2;
95        break;
96    case QUARTERBLOCKS:
97        gw = (w + 1) / 2;
98        fgw = (w * 2 + 1) / 2;
99        gh = (h + 1) / 2;
100        break;
101    }
102
103    blocks = caca_get_font_blocks(f);
104    onechar = caca_create_canvas(0, 0);
105    caca_set_color_ansi(onechar, CACA_WHITE, CACA_BLACK);
106    image = malloc(4 * iw * ih);
107
108    out = caca_create_canvas(0, 0);
109    printf("tlf2a$ %u %u %u -1 4 0 0 0\n", gh, gh - 1, fgw + 2);
110
111    printf("=============================================="
112                                       "==================================\n");
113    printf("  This font was automatically generated using:\n");
114    printf("   %% caca2tlf %s\"%s\"\n", extraflag, fontname);
115    printf("=============================================="
116                                       "==================================\n");
117
118    for(i = 32; i < 127; i++)
119        add_char(i);
120
121    add_char(196);
122    add_char(214);
123    add_char(220);
124    add_char(228);
125    add_char(246);
126    add_char(252);
127    add_char(223);
128
129    for(b = 0, i = 0; blocks[i + 1]; i += 2)
130    {
131        int j, n = (int)(blocks[i + 1] - blocks[i]);
132
133        for(j = 0; j < n; j++)
134        {
135            char buf[7];
136            unsigned int len;
137            unsigned long int ch = blocks[i] + j;
138
139            if(ch <= 127 || ch == 196 || ch == 214 || ch == 220
140               || ch == 228 || ch == 246 || ch == 252 || ch == 223)
141                continue;
142
143            len = caca_utf32_to_utf8(buf, ch);
144            buf[len] = '\0';
145            printf("0x%.04lX %s\n", ch, buf);
146            add_char(ch);
147        }
148    }
149
150    caca_free_canvas(out);
151    caca_free_canvas(onechar);
152    free(image);
153    caca_free_font(f);
154
155    return 0;
156}
157
158static void list_fonts(void)
159{
160    char const * const * fonts;
161    unsigned int i;
162
163    fprintf(stderr, "Available fonts:\n");
164
165    fonts = caca_get_font_list();
166    for(i = 0; fonts[i]; i++)
167        fprintf(stderr, \"%s\"\n", fonts[i]);
168}
169
170static void add_char(unsigned long int ch)
171{
172    void *buf;
173    unsigned long int len;
174    unsigned int x, y, myw, mygw;
175    int full = caca_utf32_is_fullwidth(ch);
176
177    caca_set_canvas_size(onechar, full ? 2 : 1, 1);
178    caca_put_char(onechar, 0, 0, ch);
179    caca_render_canvas(onechar, f, image, iw, ih, 4 * iw);
180
181    myw = full ? 2 * w : w;
182    mygw = full ? fgw : gw;
183
184    caca_set_canvas_size(out, (full ? fgw : gw) + 2, gh);
185
186    switch(mode)
187    {
188    case GRAY:
189        for(y = 0; y < h; y++)
190            for(x = 0; x < myw; x++)
191        {
192            uint8_t c = image[4 * (x + y * iw) + 2];
193
194            if(c >= 0xa0)
195                caca_put_str(out, x, y, "█");
196            else if(c >= 0x80)
197                caca_put_str(out, x, y, "▓");
198            else if(c >= 0x40)
199                caca_put_str(out, x, y, "▒");
200            else if(c >= 0x20)
201                caca_put_str(out, x, y, "░");
202            else
203                caca_put_char(out, x, y, ' ');
204        }
205        break;
206    case HALFBLOCKS:
207        for(y = 0; y < gh; y++)
208            for(x = 0; x < mygw; x++)
209        {
210            static char const *str[] = { " ", "▀", "▄", "█" };
211
212            uint8_t p1 = image[4 * (x + y * 2 * iw) + 2];
213            uint8_t p2 = image[4 * (x + (y * 2 + 1) * iw) + 2];
214
215            caca_put_str(out, x, y, str[(p1 > 0x80) + 2 * (p2 > 0x80)]);
216        }
217        break;
218    case QUARTERBLOCKS:
219        for(y = 0; y < gh; y++)
220            for(x = 0; x < mygw; x++)
221        {
222            static char const *str[] =
223            {
224                " ", "▘", "▝", "▀", "▖", "▌", "▞", "▛",
225                "▗", "▚", "▐", "▜", "▄", "▙", "▟", "█"
226            };
227
228            uint8_t p1 = image[4 * (x * 2 + y * 2 * iw) + 2];
229            uint8_t p2 = image[4 * (x * 2 + 1 + y * 2 * iw) + 2];
230            uint8_t p3 = image[4 * (x * 2 + (y * 2 + 1) * iw) + 2];
231            uint8_t p4 = image[4 * (x * 2 + 1 + (y * 2 + 1) * iw) + 2];
232
233            caca_put_str(out, x, y, str[(p1 > 0x80) + 2 * (p2 > 0x80) +
234                                         4 * (p3 > 0x80) + 8 * (p4 > 0x80)]);
235        }
236        break;
237    }
238
239    if(ch == ' ' || ch == 0xa0)
240    {
241        caca_draw_line(out, mygw - 1, 0, mygw - 1, gh - 1, '$');
242        caca_draw_line(out, mygw / 2, 0, mygw / 2, gh - 1, '$');
243    }
244
245    caca_draw_line(out, mygw, 0, mygw, gh - 1, '@');
246    caca_put_char(out, mygw + 1, gh - 1, '@');
247
248    buf = caca_export_memory(out, "utf8", &len);
249    fwrite(buf, len, 1, stdout);
250    free(buf);
251}
252
Note: See TracBrowser for help on using the repository browser.