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.

toilet.c 6.0 KiB

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