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.

преди 18 години
преди 21 години
преди 21 години
преди 21 години
преди 21 години
преди 21 години
преди 21 години
преди 21 години
преди 21 години
преди 21 години
преди 21 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * libcucul Canvas for ultrafast compositing of Unicode letters
  3. * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
  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 ellipse and circle drawing functions, both filled
  16. * and outline.
  17. */
  18. #include "config.h"
  19. #include "common.h"
  20. #if !defined(__KERNEL__)
  21. # include <stdlib.h>
  22. #endif
  23. #include "cucul.h"
  24. #include "cucul_internals.h"
  25. static void ellipsepoints(cucul_canvas_t *, int, int, int, int, uint32_t);
  26. /** \brief Draw a circle on the canvas using the given character.
  27. *
  28. * This function never fails.
  29. *
  30. * \param cv The handle to the libcucul canvas.
  31. * \param x Center X coordinate.
  32. * \param y Center Y coordinate.
  33. * \param r Circle radius.
  34. * \param ch UTF-32 character to be used to draw the circle outline.
  35. * \return This function always returns 0.
  36. */
  37. int cucul_draw_circle(cucul_canvas_t *cv, int x, int y, int r,
  38. unsigned long int ch)
  39. {
  40. int test, dx, dy;
  41. /* Optimized Bresenham. Kick ass. */
  42. for(test = 0, dx = 0, dy = r ; dx <= dy ; dx++)
  43. {
  44. ellipsepoints(cv, x, y, dx, dy, ch);
  45. ellipsepoints(cv, x, y, dy, dx, ch);
  46. test += test > 0 ? dx - dy-- : dx;
  47. }
  48. return 0;
  49. }
  50. /** \brief Fill an ellipse on the canvas using the given character.
  51. *
  52. * This function never fails.
  53. *
  54. * \param cv The handle to the libcucul canvas.
  55. * \param xo Center X coordinate.
  56. * \param yo Center Y coordinate.
  57. * \param a Ellipse X radius.
  58. * \param b Ellipse Y radius.
  59. * \param ch UTF-32 character to be used to fill the ellipse.
  60. * \return This function always returns 0.
  61. */
  62. int cucul_fill_ellipse(cucul_canvas_t *cv, int xo, int yo, int a, int b,
  63. unsigned long int ch)
  64. {
  65. int d2;
  66. int x = 0;
  67. int y = b;
  68. int d1 = b*b - (a*a*b) + (a*a/4);
  69. while(a*a*y - a*a/2 > b*b*(x+1))
  70. {
  71. if(d1 < 0)
  72. {
  73. d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */
  74. }
  75. else
  76. {
  77. d1 += b*b*(2*x*1) + a*a*(-2*y+2);
  78. cucul_draw_line(cv, xo - x, yo - y, xo + x, yo - y, ch);
  79. cucul_draw_line(cv, xo - x, yo + y, xo + x, yo + y, ch);
  80. y--;
  81. }
  82. x++;
  83. }
  84. cucul_draw_line(cv, xo - x, yo - y, xo + x, yo - y, ch);
  85. cucul_draw_line(cv, xo - x, yo + y, xo + x, yo + y, ch);
  86. d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
  87. while(y > 0)
  88. {
  89. if(d2 < 0)
  90. {
  91. d2 += b*b*(2*x+2) + a*a*(-2*y+3);
  92. x++;
  93. }
  94. else
  95. {
  96. d2 += a*a*(-2*y+3);
  97. }
  98. y--;
  99. cucul_draw_line(cv, xo - x, yo - y, xo + x, yo - y, ch);
  100. cucul_draw_line(cv, xo - x, yo + y, xo + x, yo + y, ch);
  101. }
  102. return 0;
  103. }
  104. /** \brief Draw an ellipse on the canvas using the given character.
  105. *
  106. * This function never fails.
  107. *
  108. * \param cv The handle to the libcucul canvas.
  109. * \param xo Center X coordinate.
  110. * \param yo Center Y coordinate.
  111. * \param a Ellipse X radius.
  112. * \param b Ellipse Y radius.
  113. * \param ch UTF-32 character to be used to draw the ellipse outline.
  114. * \return This function always returns 0.
  115. */
  116. int cucul_draw_ellipse(cucul_canvas_t *cv, int xo, int yo, int a, int b,
  117. unsigned long int ch)
  118. {
  119. int d2;
  120. int x = 0;
  121. int y = b;
  122. int d1 = b*b - (a*a*b) + (a*a/4);
  123. ellipsepoints(cv, xo, yo, x, y, ch);
  124. while(a*a*y - a*a/2 > b*b*(x+1))
  125. {
  126. if(d1 < 0)
  127. {
  128. d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */
  129. }
  130. else
  131. {
  132. d1 += b*b*(2*x*1) + a*a*(-2*y+2);
  133. y--;
  134. }
  135. x++;
  136. ellipsepoints(cv, xo, yo, x, y, ch);
  137. }
  138. d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
  139. while(y > 0)
  140. {
  141. if(d2 < 0)
  142. {
  143. d2 += b*b*(2*x+2) + a*a*(-2*y+3);
  144. x++;
  145. }
  146. else
  147. {
  148. d2 += a*a*(-2*y+3);
  149. }
  150. y--;
  151. ellipsepoints(cv, xo, yo, x, y, ch);
  152. }
  153. return 0;
  154. }
  155. /** \brief Draw a thin ellipse on the canvas.
  156. *
  157. * This function never fails.
  158. *
  159. * \param cv The handle to the libcucul canvas.
  160. * \param xo Center X coordinate.
  161. * \param yo Center Y coordinate.
  162. * \param a Ellipse X radius.
  163. * \param b Ellipse Y radius.
  164. * \return This function always returns 0.
  165. */
  166. int cucul_draw_thin_ellipse(cucul_canvas_t *cv, int xo, int yo, int a, int b)
  167. {
  168. /* FIXME: this is not correct */
  169. int d2;
  170. int x = 0;
  171. int y = b;
  172. int d1 = b*b - (a*a*b) + (a*a/4);
  173. ellipsepoints(cv, xo, yo, x, y, '-');
  174. while(a*a*y - a*a/2 > b*b*(x+1))
  175. {
  176. if(d1 < 0)
  177. {
  178. d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */
  179. }
  180. else
  181. {
  182. d1 += b*b*(2*x*1) + a*a*(-2*y+2);
  183. y--;
  184. }
  185. x++;
  186. ellipsepoints(cv, xo, yo, x, y, '-');
  187. }
  188. d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
  189. while(y > 0)
  190. {
  191. if(d2 < 0)
  192. {
  193. d2 += b*b*(2*x+2) + a*a*(-2*y+3);
  194. x++;
  195. }
  196. else
  197. {
  198. d2 += a*a*(-2*y+3);
  199. }
  200. y--;
  201. ellipsepoints(cv, xo, yo, x, y, '|');
  202. }
  203. return 0;
  204. }
  205. static void ellipsepoints(cucul_canvas_t *cv, int xo, int yo, int x, int y,
  206. uint32_t ch)
  207. {
  208. uint8_t b = 0;
  209. if(xo + x >= 0 && xo + x < (int)cv->width)
  210. b |= 0x1;
  211. if(xo - x >= 0 && xo - x < (int)cv->width)
  212. b |= 0x2;
  213. if(yo + y >= 0 && yo + y < (int)cv->height)
  214. b |= 0x4;
  215. if(yo - y >= 0 && yo - y < (int)cv->height)
  216. b |= 0x8;
  217. if((b & (0x1|0x4)) == (0x1|0x4))
  218. cucul_put_char(cv, xo + x, yo + y, ch);
  219. if((b & (0x2|0x4)) == (0x2|0x4))
  220. cucul_put_char(cv, xo - x, yo + y, ch);
  221. if((b & (0x1|0x8)) == (0x1|0x8))
  222. cucul_put_char(cv, xo + x, yo - y, ch);
  223. if((b & (0x2|0x8)) == (0x2|0x8))
  224. cucul_put_char(cv, xo - x, yo - y, ch);
  225. }