2 * caca2tlf Create a TOIlet font from a libcaca font
3 * Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
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.
16 * This is the main program entry point.
21 #if defined(HAVE_INTTYPES_H)
22 # include <inttypes.h>
29 enum mode
{ GRAY
, HALFBLOCKS
, QUARTERBLOCKS
} mode
;
30 enum charset
{ SPACES
, ASCII
, UTF8
} charset
;
32 static void list_fonts(void);
33 static void add_char(unsigned long int);
36 caca_canvas_t
*out
, *onechar
;
37 uint32_t const *blocks
;
39 unsigned int w
, h
, gw
, fgw
, gh
, iw
, ih
;
41 int main(int argc
, char *argv
[])
49 "Usage: %s [--half|--quarter] [--spaces|--ascii|--utf8] <font>\n",
55 if((!strcmp(argv
[1], "--half") || !strcmp(argv
[1], "-h")) && argc
> 2)
61 else if((!strcmp(argv
[1], "--quarter") || !strcmp(argv
[1], "-q")) && argc
> 2)
73 if((!strcmp(argv
[1], "--spaces") || !strcmp(argv
[1], "-s")) && argc
> 2)
79 else if((!strcmp(argv
[1], "--ascii") || !strcmp(argv
[1], "-a")) && argc
> 2)
85 else if((!strcmp(argv
[1], "--utf8") || !strcmp(argv
[1], "-u")) && argc
> 2)
97 f
= caca_load_font(argv
[1], 0);
100 fprintf(stderr
, "Font \"%s\" not found.\n", argv
[1]);
105 w
= caca_get_font_width(f
);
106 h
= caca_get_font_height(f
);
123 fgw
= (w
* 2 + 1) / 2;
128 blocks
= caca_get_font_blocks(f
);
129 onechar
= caca_create_canvas(0, 0);
130 caca_set_color_ansi(onechar
, CACA_WHITE
, CACA_BLACK
);
131 image
= malloc(4 * iw
* ih
);
133 out
= caca_create_canvas(0, 0);
134 printf("tlf2a$ %u %u %u -1 4 0 0 0\n", gh
, gh
- 1, fgw
+ 2);
136 printf("=============================================="
137 "==================================\n");
138 printf(" This font was automatically generated using:\n");
139 printf(" %% caca2tlf %s%s\"%s\"\n", flag1
, flag2
, argv
[1]);
140 printf("=============================================="
141 "==================================\n");
143 for(i
= 32; i
< 127; i
++)
154 for(b
= 0, i
= 0; blocks
[i
+ 1]; i
+= 2)
156 int j
, n
= (int)(blocks
[i
+ 1] - blocks
[i
]);
158 for(j
= 0; j
< n
; j
++)
162 unsigned long int ch
= blocks
[i
] + j
;
164 if(ch
<= 127 || ch
== 196 || ch
== 214 || ch
== 220
165 || ch
== 228 || ch
== 246 || ch
== 252 || ch
== 223)
168 len
= caca_utf32_to_utf8(buf
, ch
);
170 printf("0x%.04lX %s\n", ch
, buf
);
175 caca_free_canvas(out
);
176 caca_free_canvas(onechar
);
183 static void list_fonts(void)
185 char const * const * fonts
;
188 fprintf(stderr
, "Available fonts:\n");
190 fonts
= caca_get_font_list();
191 for(i
= 0; fonts
[i
]; i
++)
192 fprintf(stderr
, " \"%s\"\n", fonts
[i
]);
195 static void add_char(unsigned long int ch
)
197 static char const * chars
[][16] =
199 { "_", "_", "_", "_", " " },
200 { " ", "_", "_", "_" },
201 { " ", "_", "_", "_", "_", "_", "_", "_",
202 "_", "_", "_", "_", "_", "_", "_", "_" },
203 { "#", "$", ":", ".", " " },
204 { " ", "\"", "m", "#" },
205 { " ", "`", "'", "\"", ",", "[", "/", "P",
206 ".", "\\", "]", "T", "m", "b", "d", "W" },
207 { "█", "▓", "▒", "░", " " },
208 { " ", "▀", "▄", "█" },
209 { " ", "▘", "▝", "▀", "▖", "▌", "▞", "▛",
210 "▗", "▚", "▐", "▜", "▄", "▙", "▟", "█" }
213 static uint8_t fgs
[][4] =
215 { CACA_DEFAULT
, CACA_DARKGRAY
, CACA_LIGHTGRAY
, CACA_WHITE
},
216 { CACA_DEFAULT
, CACA_DEFAULT
, CACA_DEFAULT
, CACA_DEFAULT
},
219 static uint8_t bgs
[][4] =
221 { CACA_DEFAULT
, CACA_DARKGRAY
, CACA_LIGHTGRAY
, CACA_WHITE
},
222 { CACA_DEFAULT
, CACA_DEFAULT
, CACA_DEFAULT
, CACA_DEFAULT
},
228 unsigned int x
, y
, myw
, mygw
;
229 int coff
= 0, aoff
= 0;
230 int full
= caca_utf32_is_fullwidth(ch
);
232 caca_set_canvas_size(onechar
, full
? 2 : 1, 1);
233 caca_put_char(onechar
, 0, 0, ch
);
234 caca_render_canvas(onechar
, f
, image
, iw
, ih
, 4 * iw
);
236 myw
= full
? 2 * w
: w
;
237 mygw
= full
? fgw
: gw
;
239 caca_set_canvas_size(out
, (full
? fgw
: gw
) + 2, gh
);
240 caca_clear_canvas(out
);
259 for(y
= 0; y
< h
; y
++)
260 for(x
= 0; x
< myw
; x
++)
262 uint8_t c
= image
[4 * (x
+ y
* iw
) + 2];
266 caca_set_color_ansi(out
, fgs
[aoff
][3], bgs
[aoff
][3]);
267 caca_put_str(out
, x
, y
, str
[0]);
271 caca_set_color_ansi(out
, fgs
[aoff
][2], bgs
[aoff
][2]);
272 caca_put_str(out
, x
, y
, str
[0]);
276 caca_set_color_ansi(out
, fgs
[aoff
][2], bgs
[aoff
][2]);
277 caca_put_str(out
, x
, y
, str
[1]);
281 caca_set_color_ansi(out
, fgs
[aoff
][1], bgs
[aoff
][1]);
282 caca_put_str(out
, x
, y
, str
[2]);
286 caca_set_color_ansi(out
, fgs
[aoff
][1], bgs
[aoff
][1]);
287 caca_put_str(out
, x
, y
, str
[3]);
291 caca_set_color_ansi(out
, fgs
[aoff
][0], bgs
[aoff
][0]);
292 caca_put_str(out
, x
, y
, str
[4]);
297 str
= chars
[coff
+ 1];
298 for(y
= 0; y
< gh
; y
++)
299 for(x
= 0; x
< mygw
; x
++)
301 uint8_t p1
= image
[4 * (x
+ y
* 2 * iw
) + 2];
302 uint8_t p2
= image
[4 * (x
+ (y
* 2 + 1) * iw
) + 2];
304 caca_put_str(out
, x
, y
, str
[(p1
> 0x80) + 2 * (p2
> 0x80)]);
308 str
= chars
[coff
+ 2];
309 for(y
= 0; y
< gh
; y
++)
310 for(x
= 0; x
< mygw
; x
++)
312 uint8_t p1
= image
[4 * (x
* 2 + y
* 2 * iw
) + 2];
313 uint8_t p2
= image
[4 * (x
* 2 + 1 + y
* 2 * iw
) + 2];
314 uint8_t p3
= image
[4 * (x
* 2 + (y
* 2 + 1) * iw
) + 2];
315 uint8_t p4
= image
[4 * (x
* 2 + 1 + (y
* 2 + 1) * iw
) + 2];
317 caca_put_str(out
, x
, y
, str
[(p1
> 0x80) + 2 * (p2
> 0x80) +
318 4 * (p3
> 0x80) + 8 * (p4
> 0x80)]);
323 caca_set_color_ansi(out
, CACA_DEFAULT
, CACA_DEFAULT
);
325 if(ch
== ' ' || ch
== 0xa0)
327 caca_draw_line(out
, mygw
- 1, 0, mygw
- 1, gh
- 1, '$');
328 caca_draw_line(out
, mygw
/ 2, 0, mygw
/ 2, gh
- 1, '$');
331 caca_draw_line(out
, mygw
, 0, mygw
, gh
- 1, '@');
332 caca_put_char(out
, mygw
+ 1, gh
- 1, '@');
334 buf
= caca_export_canvas_to_memory(out
, "utf8", &len
);
335 fwrite(buf
, len
, 1, stdout
);