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.
 
 
 
 
 
 

232 regels
5.9 KiB

  1. /*
  2. * libcaca Colour ASCII-Art library
  3. * Copyright (c) 2002-2009 Sam Hocevar <sam@hocevar.net>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library 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 file contains box drawing functions, both filled and outline.
  16. */
  17. #include "config.h"
  18. #if !defined(__KERNEL__)
  19. # include <stdlib.h>
  20. #endif
  21. #include "caca.h"
  22. #include "caca_internals.h"
  23. static int draw_box(caca_canvas_t *cv, int x, int y, int w, int h,
  24. uint32_t const *chars);
  25. /** \brief Draw a box on the canvas using the given character.
  26. *
  27. * This function never fails.
  28. *
  29. * \param cv The handle to the libcaca canvas.
  30. * \param x X coordinate of the upper-left corner of the box.
  31. * \param y Y coordinate of the upper-left corner of the box.
  32. * \param w Width of the box.
  33. * \param h Height of the box.
  34. * \param ch UTF-32 character to be used to draw the box.
  35. * \return This function always returns 0.
  36. */
  37. int caca_draw_box(caca_canvas_t *cv, int x, int y, int w, int h, uint32_t ch)
  38. {
  39. int x2 = x + w - 1;
  40. int y2 = y + h - 1;
  41. caca_draw_line(cv, x, y, x, y2, ch);
  42. caca_draw_line(cv, x, y2, x2, y2, ch);
  43. caca_draw_line(cv, x2, y2, x2, y, ch);
  44. caca_draw_line(cv, x2, y, x, y, ch);
  45. return 0;
  46. }
  47. /** \brief Draw a thin box on the canvas.
  48. *
  49. * This function never fails.
  50. *
  51. * \param cv The handle to the libcaca canvas.
  52. * \param x X coordinate of the upper-left corner of the box.
  53. * \param y Y coordinate of the upper-left corner of the box.
  54. * \param w Width of the box.
  55. * \param h Height of the box.
  56. * \return This function always returns 0.
  57. */
  58. int caca_draw_thin_box(caca_canvas_t *cv, int x, int y, int w, int h)
  59. {
  60. static uint32_t const ascii_chars[] =
  61. {
  62. '-', '|', ',', '`', '.', '\''
  63. };
  64. return draw_box(cv, x, y, w, h, ascii_chars);
  65. }
  66. /** \brief Draw a box on the canvas using CP437 characters.
  67. *
  68. * This function never fails.
  69. *
  70. * \param cv The handle to the libcaca canvas.
  71. * \param x X coordinate of the upper-left corner of the box.
  72. * \param y Y coordinate of the upper-left corner of the box.
  73. * \param w Width of the box.
  74. * \param h Height of the box.
  75. * \return This function always returns 0.
  76. */
  77. int caca_draw_cp437_box(caca_canvas_t *cv, int x, int y, int w, int h)
  78. {
  79. static uint32_t const cp437_chars[] =
  80. {
  81. /* ─ │ ┌ └ ┐ ┘ */
  82. 0x2500, 0x2502, 0x250c, 0x2514, 0x2510, 0x2518
  83. };
  84. return draw_box(cv, x, y, w, h, cp437_chars);
  85. }
  86. /** \brief Fill a box on the canvas using the given character.
  87. *
  88. * This function never fails.
  89. *
  90. * \param cv The handle to the libcaca canvas.
  91. * \param x X coordinate of the upper-left corner of the box.
  92. * \param y Y coordinate of the upper-left corner of the box.
  93. * \param w Width of the box.
  94. * \param h Height of the box.
  95. * \param ch UTF-32 character to be used to draw the box.
  96. * \return This function always returns 0.
  97. */
  98. int caca_fill_box(caca_canvas_t *cv, int x, int y, int w, int h,
  99. uint32_t ch)
  100. {
  101. int i, j, xmax, ymax;
  102. int x2 = x + w - 1;
  103. int y2 = y + h - 1;
  104. if(x > x2)
  105. {
  106. int tmp = x;
  107. x = x2; x2 = tmp;
  108. }
  109. if(y > y2)
  110. {
  111. int tmp = y;
  112. y = y2; y2 = tmp;
  113. }
  114. xmax = cv->width - 1;
  115. ymax = cv->height - 1;
  116. if(x2 < 0 || y2 < 0 || x > xmax || y > ymax)
  117. return 0;
  118. if(x < 0) x = 0;
  119. if(y < 0) y = 0;
  120. if(x2 > xmax) x2 = xmax;
  121. if(y2 > ymax) y2 = ymax;
  122. #if 0
  123. /* FIXME: this fails with fullwidth character blits. Also, the dirty
  124. * rectangle handling may miss fullwidth cells. */
  125. /* Optimise dirty rectangle handling, part 1 */
  126. cv->dirty_disabled++;
  127. #endif
  128. for(j = y; j <= y2; j++)
  129. for(i = x; i <= x2; i++)
  130. caca_put_char(cv, i, j, ch);
  131. #if 0
  132. /* Optimise dirty rectangle handling, part 2 */
  133. cv->dirty_disabled--;
  134. if(!cv->dirty_disabled)
  135. caca_add_dirty_rect(cv, x, y, x2 - x + 1, y2 - y + 1);
  136. #endif
  137. return 0;
  138. }
  139. /*
  140. * XXX: The following functions are local.
  141. */
  142. static int draw_box(caca_canvas_t *cv, int x, int y, int w, int h,
  143. uint32_t const *chars)
  144. {
  145. int i, j, xmax, ymax;
  146. int x2 = x + w - 1;
  147. int y2 = y + h - 1;
  148. if(x > x2)
  149. {
  150. int tmp = x;
  151. x = x2; x2 = tmp;
  152. }
  153. if(y > y2)
  154. {
  155. int tmp = y;
  156. y = y2; y2 = tmp;
  157. }
  158. xmax = cv->width - 1;
  159. ymax = cv->height - 1;
  160. if(x2 < 0 || y2 < 0 || x > xmax || y > ymax)
  161. return 0;
  162. /* Draw edges */
  163. if(y >= 0)
  164. for(i = x < 0 ? 1 : x + 1; i < x2 && i < xmax; i++)
  165. caca_put_char(cv, i, y, chars[0]);
  166. if(y2 <= ymax)
  167. for(i = x < 0 ? 1 : x + 1; i < x2 && i < xmax; i++)
  168. caca_put_char(cv, i, y2, chars[0]);
  169. if(x >= 0)
  170. for(j = y < 0 ? 1 : y + 1; j < y2 && j < ymax; j++)
  171. caca_put_char(cv, x, j, chars[1]);
  172. if(x2 <= xmax)
  173. for(j = y < 0 ? 1 : y + 1; j < y2 && j < ymax; j++)
  174. caca_put_char(cv, x2, j, chars[1]);
  175. /* Draw corners */
  176. caca_put_char(cv, x, y, chars[2]);
  177. caca_put_char(cv, x, y2, chars[3]);
  178. caca_put_char(cv, x2, y, chars[4]);
  179. caca_put_char(cv, x2, y2, chars[5]);
  180. return 0;
  181. }
  182. /*
  183. * XXX: The following functions are aliases.
  184. */
  185. int cucul_draw_box(cucul_canvas_t *, int, int, int, int, uint32_t)
  186. CACA_ALIAS(caca_draw_box);
  187. int cucul_draw_thin_box(cucul_canvas_t *, int, int, int, int)
  188. CACA_ALIAS(caca_draw_thin_box);
  189. int cucul_draw_cp437_box(cucul_canvas_t *, int, int, int, int)
  190. CACA_ALIAS(caca_draw_cp437_box);
  191. int cucul_fill_box(cucul_canvas_t *, int, int, int, int, uint32_t)
  192. CACA_ALIAS(caca_fill_box);