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.
 
 
 
 
 
 

230 rivejä
5.9 KiB

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