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.
 
 
 
 
 
 

207 regels
6.4 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 the dirty rectangle handling functions.
  16. */
  17. #include "config.h"
  18. #if !defined(__KERNEL__)
  19. # include <stdio.h>
  20. #endif
  21. #include "caca.h"
  22. #include "caca_internals.h"
  23. /** \brief Get the number of dirty rectangles in the canvas.
  24. *
  25. * Get the number of dirty rectangles in a canvas. Dirty rectangles are
  26. * areas that contain cells that have changed since the last reset.
  27. *
  28. * The dirty rectangles are used internally by display drivers to optimise
  29. * rendering by avoiding to redraw the whole screen. Once the display driver
  30. * has rendered the canvas, it resets the dirty rectangle list.
  31. *
  32. * Dirty rectangles are guaranteed not to overlap.
  33. *
  34. * This function never fails.
  35. *
  36. * \param cv A libcaca canvas.
  37. * \return The number of dirty rectangles in the given canvas.
  38. */
  39. int caca_get_dirty_rect_count(caca_canvas_t *cv)
  40. {
  41. return cv->ndirty;
  42. }
  43. /** \brief Get a canvas's dirty rectangle.
  44. *
  45. * Get the canvas's given dirty rectangle coordinates. The index must be
  46. * within the dirty rectangle count. See caca_get_dirty_rect_count()
  47. * for how to compute this count.
  48. *
  49. * If an error occurs, no coordinates are written in the pointer arguments,
  50. * -1 is returned and \b errno is set accordingly:
  51. * - \c EINVAL Specified rectangle index is out of bounds.
  52. *
  53. * \param cv A libcaca canvas.
  54. * \param r The requested rectangle index.
  55. * \param x A pointer to an integer where the leftmost edge of the
  56. * dirty rectangle will be stored.
  57. * \param y A pointer to an integer where the topmost edge of the
  58. * dirty rectangle will be stored.
  59. * \param width A pointer to an integer where the width of the
  60. * dirty rectangle will be stored.
  61. * \param height A pointer to an integer where the height of the
  62. * dirty rectangle will be stored.
  63. * \return 0 in case of success, -1 if an error occurred.
  64. */
  65. int caca_get_dirty_rect(caca_canvas_t *cv, int r,
  66. int *x, int *y, int *width, int *height)
  67. {
  68. if(r < 0 || r >= cv->ndirty)
  69. {
  70. seterrno(EINVAL);
  71. return -1;
  72. }
  73. /* Normalise dirty rectangle so that the values can be directly used. */
  74. if(cv->dirty_xmin < 0)
  75. cv->dirty_xmin = 0;
  76. if(cv->dirty_xmax > cv->width - 1)
  77. cv->dirty_xmax = cv->width - 1;
  78. if(cv->dirty_ymin < 0)
  79. cv->dirty_ymin = 0;
  80. if(cv->dirty_ymax > cv->height - 1)
  81. cv->dirty_ymax = cv->height - 1;
  82. *x = cv->dirty_xmin;
  83. *y = cv->dirty_ymin;
  84. *width = cv->dirty_xmax - cv->dirty_xmin + 1;
  85. *height = cv->dirty_ymax - cv->dirty_ymin + 1;
  86. return 0;
  87. }
  88. /** \brief Add an area to the canvas's dirty rectangle list.
  89. *
  90. * Add an invalidating zone to the canvas's dirty rectangle list. For more
  91. * information about the dirty rectangles, see caca_get_dirty_rect().
  92. *
  93. * This function may be useful to force refresh of a given zone of the
  94. * canvas even if the dirty rectangle tracking indicates that it is
  95. * unchanged. This may happen if the canvas contents were somewhat
  96. * directly modified.
  97. *
  98. * If an error occurs, -1 is returned and \b errno is set accordingly:
  99. * - \c EINVAL Specified rectangle coordinates are out of bounds.
  100. *
  101. * \param cv A libcaca canvas.
  102. * \param x The leftmost edge of the additional dirty rectangle.
  103. * \param y The topmost edge of the additional dirty rectangle.
  104. * \param width The width of the additional dirty rectangle.
  105. * \param height The height of the additional dirty rectangle.
  106. * \return 0 in case of success, -1 if an error occurred.
  107. */
  108. int caca_add_dirty_rect(caca_canvas_t *cv, int x, int y,
  109. int width, int height)
  110. {
  111. /* Ignore empty and out-of-bounds rectangles */
  112. if(width <= 0 || height <= 0 || x + width <= 0 || x >= cv->width
  113. || y + height <= 0 || y >= cv->height)
  114. {
  115. seterrno(EINVAL);
  116. return -1;
  117. }
  118. if(cv->ndirty == 0)
  119. {
  120. cv->ndirty = 1;
  121. cv->dirty_xmin = x;
  122. cv->dirty_xmax = x + width - 1;
  123. cv->dirty_ymin = y;
  124. cv->dirty_ymax = y + height - 1;
  125. }
  126. else
  127. {
  128. if(x < cv->dirty_xmin)
  129. cv->dirty_xmin = x;
  130. if(x + width - 1 > cv->dirty_xmax)
  131. cv->dirty_xmax = x + width - 1;
  132. if(y < cv->dirty_ymin)
  133. cv->dirty_ymin = y;
  134. if(y + height - 1 > cv->dirty_ymax)
  135. cv->dirty_ymax = y + height - 1;
  136. }
  137. return 0;
  138. }
  139. /** \brief Remove an area from the dirty rectangle list.
  140. *
  141. * Mark a cell area in the canvas as not dirty. For more information about
  142. * the dirty rectangles, see caca_get_dirty_rect().
  143. *
  144. * Values such that \b xmin > \b xmax or \b ymin > \b ymax indicate that
  145. * the dirty rectangle is empty. They will be silently ignored.
  146. *
  147. * If an error occurs, -1 is returned and \b errno is set accordingly:
  148. * - \c EINVAL Specified rectangle coordinates are out of bounds.
  149. *
  150. * \param cv A libcaca canvas.
  151. * \param x The leftmost edge of the clean rectangle.
  152. * \param y The topmost edge of the clean rectangle.
  153. * \param width The width of the clean rectangle.
  154. * \param height The height of the clean rectangle.
  155. * \return 0 in case of success, -1 if an error occurred.
  156. */
  157. int caca_remove_dirty_rect(caca_canvas_t *cv, int x, int y,
  158. int width, int height)
  159. {
  160. /* Ignore empty and out-of-bounds rectangles */
  161. if(width <= 0 || height <= 0 || x + width <= 0 || x >= cv->width
  162. || y + height <= 0 || y >= cv->height)
  163. {
  164. seterrno(EINVAL);
  165. return -1;
  166. }
  167. /* FIXME: implement this function. It's OK to have it do nothing,
  168. * since we take a conservative approach in dirty rectangle handling,
  169. * but we ought to help the rendering eventually. */
  170. return 0;
  171. }
  172. /** \brief Clear a canvas's dirty rectangle list.
  173. *
  174. * Empty the canvas's dirty rectangle list.
  175. *
  176. * This function never fails.
  177. *
  178. * \param cv A libcaca canvas.
  179. * \return This function always returns 0.
  180. */
  181. int caca_clear_dirty_rect_list(caca_canvas_t *cv)
  182. {
  183. cv->ndirty = 0;
  184. return 0;
  185. }