You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 15 години
преди 18 години
преди 18 години
преди 15 години
преди 15 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 15 години
преди 15 години
преди 18 години
преди 15 години
преди 18 години
преди 15 години
преди 15 години
преди 15 години
преди 18 години
преди 15 години
преди 18 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 15 години
преди 18 години
преди 15 години
преди 18 години
преди 15 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /*
  2. * caca2tlf Create a TOIlet font from a libcaca font
  3. * Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
  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. * This is the main program entry point.
  16. */
  17. #include "config.h"
  18. #if defined(HAVE_INTTYPES_H)
  19. # include <inttypes.h>
  20. #endif
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <caca.h>
  25. enum mode { GRAY, HALFBLOCKS, QUARTERBLOCKS } mode;
  26. enum charset { SPACES, ASCII, UTF8 } charset;
  27. static void list_fonts(void);
  28. static void add_char(unsigned long int);
  29. caca_font_t *f;
  30. caca_canvas_t *out, *onechar;
  31. uint32_t const *blocks;
  32. uint8_t * image;
  33. unsigned int w, h, gw, fgw, gh, iw, ih;
  34. int main(int argc, char *argv[])
  35. {
  36. char *flag1, *flag2;
  37. unsigned int b, i;
  38. if(argc < 2)
  39. {
  40. fprintf(stderr,
  41. "Usage: %s [--half|--quarter] [--spaces|--ascii|--utf8] <font>\n",
  42. argv[0]);
  43. list_fonts();
  44. return -1;
  45. }
  46. if((!strcmp(argv[1], "--half") || !strcmp(argv[1], "-h")) && argc > 2)
  47. {
  48. flag1 = "--half ";
  49. mode = HALFBLOCKS;
  50. argv++; argc--;
  51. }
  52. else if((!strcmp(argv[1], "--quarter") || !strcmp(argv[1], "-q")) && argc > 2)
  53. {
  54. flag1 = "--quarter ";
  55. mode = QUARTERBLOCKS;
  56. argv++; argc--;
  57. }
  58. else
  59. {
  60. flag1 = "";
  61. mode = GRAY;
  62. }
  63. if((!strcmp(argv[1], "--spaces") || !strcmp(argv[1], "-s")) && argc > 2)
  64. {
  65. flag2 = "--spaces ";
  66. charset = SPACES;
  67. argv++; argc--;
  68. }
  69. else if((!strcmp(argv[1], "--ascii") || !strcmp(argv[1], "-a")) && argc > 2)
  70. {
  71. flag2 = "--ascii ";
  72. charset = ASCII;
  73. argv++; argc--;
  74. }
  75. else if((!strcmp(argv[1], "--utf8") || !strcmp(argv[1], "-u")) && argc > 2)
  76. {
  77. flag2 = "--utf8 ";
  78. charset = UTF8;
  79. argv++; argc--;
  80. }
  81. else
  82. {
  83. flag2 = "";
  84. charset = ASCII;
  85. }
  86. f = caca_load_font(argv[1], 0);
  87. if(!f)
  88. {
  89. fprintf(stderr, "Font \"%s\" not found.\n", argv[1]);
  90. list_fonts();
  91. return -2;
  92. }
  93. w = caca_get_font_width(f);
  94. h = caca_get_font_height(f);
  95. iw = w * 2 + 1;
  96. ih = h + 1;
  97. switch(mode)
  98. {
  99. case GRAY:
  100. gw = w;
  101. fgw = w * 2;
  102. gh = h;
  103. break;
  104. case HALFBLOCKS:
  105. gw = w;
  106. fgw = w * 2;
  107. gh = (h + 1) / 2;
  108. break;
  109. case QUARTERBLOCKS:
  110. gw = (w + 1) / 2;
  111. fgw = (w * 2 + 1) / 2;
  112. gh = (h + 1) / 2;
  113. break;
  114. }
  115. blocks = caca_get_font_blocks(f);
  116. onechar = caca_create_canvas(0, 0);
  117. caca_set_color_ansi(onechar, CACA_WHITE, CACA_BLACK);
  118. image = malloc(4 * iw * ih);
  119. out = caca_create_canvas(0, 0);
  120. printf("tlf2a$ %u %u %u -1 4 0 0 0\n", gh, gh - 1, fgw + 2);
  121. printf("=============================================="
  122. "==================================\n");
  123. printf(" This font was automatically generated using:\n");
  124. printf(" %% caca2tlf %s%s\"%s\"\n", flag1, flag2, argv[1]);
  125. printf("=============================================="
  126. "==================================\n");
  127. for(i = 32; i < 127; i++)
  128. add_char(i);
  129. add_char(196);
  130. add_char(214);
  131. add_char(220);
  132. add_char(228);
  133. add_char(246);
  134. add_char(252);
  135. add_char(223);
  136. for(b = 0, i = 0; blocks[i + 1]; i += 2)
  137. {
  138. int j, n = (int)(blocks[i + 1] - blocks[i]);
  139. for(j = 0; j < n; j++)
  140. {
  141. char buf[7];
  142. unsigned int len;
  143. unsigned long int ch = blocks[i] + j;
  144. if(ch <= 127 || ch == 196 || ch == 214 || ch == 220
  145. || ch == 228 || ch == 246 || ch == 252 || ch == 223)
  146. continue;
  147. len = caca_utf32_to_utf8(buf, ch);
  148. buf[len] = '\0';
  149. printf("0x%.04lX %s\n", ch, buf);
  150. add_char(ch);
  151. }
  152. }
  153. caca_free_canvas(out);
  154. caca_free_canvas(onechar);
  155. free(image);
  156. caca_free_font(f);
  157. return 0;
  158. }
  159. static void list_fonts(void)
  160. {
  161. char const * const * fonts;
  162. unsigned int i;
  163. fprintf(stderr, "Available fonts:\n");
  164. fonts = caca_get_font_list();
  165. for(i = 0; fonts[i]; i++)
  166. fprintf(stderr, " \"%s\"\n", fonts[i]);
  167. }
  168. static void add_char(unsigned long int ch)
  169. {
  170. static char const * chars[][16] =
  171. {
  172. { "_", "_", "_", "_", " " },
  173. { " ", "_", "_", "_" },
  174. { " ", "_", "_", "_", "_", "_", "_", "_",
  175. "_", "_", "_", "_", "_", "_", "_", "_" },
  176. { "#", "$", ":", ".", " " },
  177. { " ", "\"", "m", "#" },
  178. { " ", "`", "'", "\"", ",", "[", "/", "P",
  179. ".", "\\", "]", "T", "m", "b", "d", "W" },
  180. { "█", "▓", "▒", "░", " " },
  181. { " ", "▀", "▄", "█" },
  182. { " ", "▘", "▝", "▀", "▖", "▌", "▞", "▛",
  183. "▗", "▚", "▐", "▜", "▄", "▙", "▟", "█" }
  184. };
  185. static uint8_t fgs[][4] =
  186. {
  187. { CACA_DEFAULT, CACA_DARKGRAY, CACA_LIGHTGRAY, CACA_WHITE },
  188. { CACA_DEFAULT, CACA_DEFAULT, CACA_DEFAULT, CACA_DEFAULT },
  189. };
  190. static uint8_t bgs[][4] =
  191. {
  192. { CACA_DEFAULT, CACA_DARKGRAY, CACA_LIGHTGRAY, CACA_WHITE },
  193. { CACA_DEFAULT, CACA_DEFAULT, CACA_DEFAULT, CACA_DEFAULT },
  194. };
  195. char const **str;
  196. void *buf;
  197. size_t len;
  198. unsigned int x, y, myw, mygw;
  199. int coff = 0, aoff = 0;
  200. int full = caca_utf32_is_fullwidth(ch);
  201. caca_set_canvas_size(onechar, full ? 2 : 1, 1);
  202. caca_put_char(onechar, 0, 0, ch);
  203. caca_render_canvas(onechar, f, image, iw, ih, 4 * iw);
  204. myw = full ? 2 * w : w;
  205. mygw = full ? fgw : gw;
  206. caca_set_canvas_size(out, (full ? fgw : gw) + 2, gh);
  207. caca_clear_canvas(out);
  208. switch(charset)
  209. {
  210. case SPACES:
  211. coff = 0; aoff = 0;
  212. break;
  213. case ASCII:
  214. coff = 3; aoff = 1;
  215. break;
  216. case UTF8:
  217. coff = 6; aoff = 1;
  218. break;
  219. }
  220. switch(mode)
  221. {
  222. case GRAY:
  223. str = chars[coff];
  224. for(y = 0; y < h; y++)
  225. for(x = 0; x < myw; x++)
  226. {
  227. uint8_t c = image[4 * (x + y * iw) + 2];
  228. if(c >= 0xc0)
  229. {
  230. caca_set_color_ansi(out, fgs[aoff][3], bgs[aoff][3]);
  231. caca_put_str(out, x, y, str[0]);
  232. }
  233. else if(c >= 0x90)
  234. {
  235. caca_set_color_ansi(out, fgs[aoff][2], bgs[aoff][2]);
  236. caca_put_str(out, x, y, str[0]);
  237. }
  238. else if(c >= 0x80)
  239. {
  240. caca_set_color_ansi(out, fgs[aoff][2], bgs[aoff][2]);
  241. caca_put_str(out, x, y, str[1]);
  242. }
  243. else if(c >= 0x40)
  244. {
  245. caca_set_color_ansi(out, fgs[aoff][1], bgs[aoff][1]);
  246. caca_put_str(out, x, y, str[2]);
  247. }
  248. else if(c >= 0x20)
  249. {
  250. caca_set_color_ansi(out, fgs[aoff][1], bgs[aoff][1]);
  251. caca_put_str(out, x, y, str[3]);
  252. }
  253. else
  254. {
  255. caca_set_color_ansi(out, fgs[aoff][0], bgs[aoff][0]);
  256. caca_put_str(out, x, y, str[4]);
  257. }
  258. }
  259. break;
  260. case HALFBLOCKS:
  261. str = chars[coff + 1];
  262. for(y = 0; y < gh; y++)
  263. for(x = 0; x < mygw; x++)
  264. {
  265. uint8_t p1 = image[4 * (x + y * 2 * iw) + 2];
  266. uint8_t p2 = image[4 * (x + (y * 2 + 1) * iw) + 2];
  267. caca_put_str(out, x, y, str[(p1 > 0x80) + 2 * (p2 > 0x80)]);
  268. }
  269. break;
  270. case QUARTERBLOCKS:
  271. str = chars[coff + 2];
  272. for(y = 0; y < gh; y++)
  273. for(x = 0; x < mygw; x++)
  274. {
  275. uint8_t p1 = image[4 * (x * 2 + y * 2 * iw) + 2];
  276. uint8_t p2 = image[4 * (x * 2 + 1 + y * 2 * iw) + 2];
  277. uint8_t p3 = image[4 * (x * 2 + (y * 2 + 1) * iw) + 2];
  278. uint8_t p4 = image[4 * (x * 2 + 1 + (y * 2 + 1) * iw) + 2];
  279. caca_put_str(out, x, y, str[(p1 > 0x80) + 2 * (p2 > 0x80) +
  280. 4 * (p3 > 0x80) + 8 * (p4 > 0x80)]);
  281. }
  282. break;
  283. }
  284. caca_set_color_ansi(out, CACA_DEFAULT, CACA_DEFAULT);
  285. if(ch == ' ' || ch == 0xa0)
  286. {
  287. caca_draw_line(out, mygw - 1, 0, mygw - 1, gh - 1, '$');
  288. caca_draw_line(out, mygw / 2, 0, mygw / 2, gh - 1, '$');
  289. }
  290. caca_draw_line(out, mygw, 0, mygw, gh - 1, '@');
  291. caca_put_char(out, mygw + 1, gh - 1, '@');
  292. buf = caca_export_canvas_to_memory(out, "utf8", &len);
  293. fwrite(buf, len, 1, stdout);
  294. free(buf);
  295. }