directfb_util.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
  3. (c) Copyright 2000-2004 Convergence (integrated media) GmbH
  4. All rights reserved.
  5. Written by Denis Oliver Kropp <dok@directfb.org>,
  6. Andreas Hundt <andi@fischlustig.de>,
  7. Sven Neumann <neo@directfb.org>,
  8. Ville Syrjälä <syrjala@sci.fi> and
  9. Claudio Ciccani <klan@users.sf.net>.
  10. This library is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU Lesser General Public
  12. License as published by the Free Software Foundation; either
  13. version 2 of the License, or (at your option) any later version.
  14. This library is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. Lesser General Public License for more details.
  18. You should have received a copy of the GNU Lesser General Public
  19. License along with this library; if not, write to the
  20. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21. Boston, MA 02111-1307, USA.
  22. */
  23. #ifndef __DIRECTFB_UTIL_H__
  24. #define __DIRECTFB_UTIL_H__
  25. #include <stdlib.h>
  26. #include <errno.h>
  27. #include <directfb.h>
  28. #ifdef __cplusplus
  29. extern "C"
  30. {
  31. #endif
  32. #include <directfb_strings.h>
  33. #include <direct/types.h>
  34. #include <direct/debug.h>
  35. bool dfb_region_intersect( DFBRegion *region,
  36. int x1, int y1, int x2, int y2 );
  37. bool dfb_region_region_intersect( DFBRegion *region,
  38. const DFBRegion *clip );
  39. bool dfb_region_rectangle_intersect( DFBRegion *region,
  40. const DFBRectangle *rect );
  41. bool dfb_unsafe_region_intersect( DFBRegion *region,
  42. int x1, int y1, int x2, int y2 );
  43. bool dfb_unsafe_region_rectangle_intersect( DFBRegion *region,
  44. const DFBRectangle *rect );
  45. bool dfb_rectangle_intersect_by_unsafe_region( DFBRectangle *rectangle,
  46. DFBRegion *region );
  47. bool dfb_rectangle_intersect_by_region( DFBRectangle *rectangle,
  48. const DFBRegion *region );
  49. bool dfb_rectangle_intersect( DFBRectangle *rectangle,
  50. const DFBRectangle *clip );
  51. /* returns the result in the first rectangle */
  52. void dfb_rectangle_union ( DFBRectangle *rect1,
  53. const DFBRectangle *rect2 );
  54. #define DFB_RECTANGLE_ASSERT(r) \
  55. do { \
  56. D_ASSERT( (r) != NULL ); \
  57. D_ASSERT( (r)->w >= 0 ); \
  58. D_ASSERT( (r)->h >= 0 ); \
  59. } while (0)
  60. #define DFB_RECTANGLE_ASSERT_IF(r) \
  61. do { \
  62. if ((r) != NULL) { \
  63. D_ASSERT( (r)->w >= 0 ); \
  64. D_ASSERT( (r)->h >= 0 ); \
  65. } \
  66. } while (0)
  67. #define DFB_RECTANGLE_VALS(r) (r)->x, (r)->y, (r)->w, (r)->h
  68. #define DFB_RECTANGLE_VALS_FROM_REGION(r) (r)->x1, (r)->y1, (r)->x2-(r)->x1+1, (r)->y2-(r)->y1+1
  69. #define DFB_RECTANGLE_INIT_FROM_REGION(r) (DFBRectangle){ DFB_RECTANGLE_VALS_FROM_REGION(r) }
  70. #define DFB_RECTANGLE_CONTAINS_POINT(r,X,Y) (((X) >= (r)->x) && ((X) < (r)->x + (r)->w) && \
  71. ((Y) >= (r)->y) && ((Y) < (r)->y + (r)->h))
  72. #define DFB_RECTANGLES_DEBUG_AT( Domain, rects, num ) \
  73. do { \
  74. unsigned int i; \
  75. \
  76. for (i=0; i<(num); i++) \
  77. D_DEBUG_AT( Domain, " -> [%2d] %4d,%4d-%4dx%4d\n", i, DFB_RECTANGLE_VALS(&(rects)[i]) ); \
  78. } while (0)
  79. #define DFB_TRIANGLE_VALS(t) (t)->x1, (t)->y1, (t)->x2, (t)->y2, (t)->x3, (t)->y3
  80. #define DFB_COLORKEY_VALS(c) (c)->r, (c)->g, (c)->b, (c)->index
  81. #define DFB_REGION_CHECK(r) \
  82. ((r) != NULL && \
  83. (r)->x1 <= (r)->x2 && \
  84. (r)->y1 <= (r)->y2)
  85. #define DFB_REGION_CHECK_IF(r) \
  86. ((r) == NULL || \
  87. ((r)->x1 <= (r)->x2 && \
  88. (r)->y1 <= (r)->y2))
  89. #define DFB_REGION_ASSERT(r) \
  90. do { \
  91. D_ASSERT( (r) != NULL ); \
  92. D_ASSERT( (r)->x1 <= (r)->x2 ); \
  93. D_ASSERT( (r)->y1 <= (r)->y2 ); \
  94. } while (0)
  95. #define DFB_REGION_ASSERT_IF(r) \
  96. do { \
  97. if ((r) != NULL) { \
  98. D_ASSERT( (r)->x1 <= (r)->x2 ); \
  99. D_ASSERT( (r)->y1 <= (r)->y2 ); \
  100. } \
  101. } while (0)
  102. #define DFB_REGION_VALS(r) (r)->x1, (r)->y1, (r)->x2, (r)->y2
  103. #define DFB_REGION_VALS_FROM_DIMENSION(d) 0, 0, (d)->w-1, (d)->h-1
  104. #define DFB_REGION_INIT_FROM_DIMENSION(d) (DFBRegion){ DFB_REGION_VALS_FROM_DIMENSION(d) }
  105. #define DFB_REGION_VALS_FROM_RECTANGLE(r) (r)->x, (r)->y, (r)->x+(r)->w-1, (r)->y+(r)->h-1
  106. #define DFB_REGION_INIT_FROM_RECTANGLE(r) (DFBRegion){ DFB_REGION_VALS_FROM_RECTANGLE(r) }
  107. #define DFB_REGION_VALS_FROM_RECTANGLE_VALS(x,y,w,h) (x), (y), (x)+(w)-1, (y)+(h)-1
  108. #define DFB_REGION_INIT_FROM_RECTANGLE_VALS(x,y,w,h) (DFBRegion){ DFB_REGION_VALS_FROM_RECTANGLE_VALS(x,y,w,h) }
  109. #define DFB_REGION_VALS_TRANSLATED(r,x,y) (r)->x1 + x, (r)->y1 + y, (r)->x2 + x, (r)->y2 + y
  110. #define DFB_REGION_INIT_TRANSLATED(r,x,y) (DFBRegion){ DFB_REGION_VALS_TRANSLATED(r,x,y) }
  111. #define DFB_REGION_VALS_INTERSECTED(r,X1,Y1,X2,Y2) (r)->x1 > (X1) ? (r)->x1 : (X1), \
  112. (r)->y1 > (Y1) ? (r)->y1 : (Y1), \
  113. (r)->x2 < (X2) ? (r)->x2 : (X2), \
  114. (r)->y2 < (Y2) ? (r)->y2 : (Y2)
  115. #define DFB_REGION_INIT_INTERSECTED(r,X1,Y1,X2,Y2) (DFBRegion){ DFB_REGION_VALS_INTERSECTED(r,X1,Y1,X2,Y2) }
  116. #define DFB_REGION_CONTAINS_POINT(r,X,Y) (((X) >= (r)->x1) && ((X) <= (r)->x2) && \
  117. ((Y) >= (r)->y1) && ((Y) <= (r)->y2))
  118. #define DFB_REGIONS_DEBUG_AT( Domain, regions, num ) \
  119. do { \
  120. unsigned int i; \
  121. \
  122. for (i=0; i<(num); i++) \
  123. D_DEBUG_AT( Domain, " -> [%2d] %4d,%4d-%4d,%4d\n", i, DFB_REGION_VALS(&(regions)[i]) ); \
  124. } while (0)
  125. static inline void dfb_rectangle_from_region( DFBRectangle *rect,
  126. const DFBRegion *region )
  127. {
  128. D_ASSERT( rect != NULL );
  129. DFB_REGION_ASSERT( region );
  130. rect->x = region->x1;
  131. rect->y = region->y1;
  132. rect->w = region->x2 - region->x1 + 1;
  133. rect->h = region->y2 - region->y1 + 1;
  134. }
  135. static inline void dfb_rectangle_from_rectangle_plus_insets( DFBRectangle *rect,
  136. const DFBRectangle *inner,
  137. const DFBInsets *insets )
  138. {
  139. D_ASSERT( rect != NULL );
  140. D_ASSERT( insets != NULL );
  141. DFB_RECTANGLE_ASSERT( inner );
  142. rect->x = inner->x - insets->l;
  143. rect->y = inner->y - insets->t;
  144. rect->w = inner->w + insets->l + insets->r;
  145. rect->h = inner->h + insets->t + insets->b;
  146. }
  147. static inline void dfb_region_from_rectangle( DFBRegion *region,
  148. const DFBRectangle *rect )
  149. {
  150. D_ASSERT( region != NULL );
  151. DFB_RECTANGLE_ASSERT( rect );
  152. D_ASSERT( rect->w > 0 );
  153. D_ASSERT( rect->h > 0 );
  154. region->x1 = rect->x;
  155. region->y1 = rect->y;
  156. region->x2 = rect->x + rect->w - 1;
  157. region->y2 = rect->y + rect->h - 1;
  158. }
  159. void dfb_region_from_rotated( DFBRegion *region,
  160. const DFBRegion *from,
  161. const DFBDimension *size,
  162. int rotation );
  163. void dfb_rectangle_from_rotated( DFBRectangle *rectangle,
  164. const DFBRectangle *from,
  165. const DFBDimension *size,
  166. int rotation );
  167. void dfb_point_from_rotated_region( DFBPoint *point,
  168. const DFBRegion *from,
  169. const DFBDimension *size,
  170. int rotation );
  171. static inline void dfb_rectangle_translate( DFBRectangle *rect,
  172. int dx,
  173. int dy )
  174. {
  175. DFB_RECTANGLE_ASSERT( rect );
  176. rect->x += dx;
  177. rect->y += dy;
  178. }
  179. static inline void dfb_region_translate( DFBRegion *region,
  180. int dx,
  181. int dy )
  182. {
  183. DFB_REGION_ASSERT( region );
  184. region->x1 += dx;
  185. region->y1 += dy;
  186. region->x2 += dx;
  187. region->y2 += dy;
  188. }
  189. static inline void dfb_rectangle_resize( DFBRectangle *rect,
  190. int width,
  191. int height )
  192. {
  193. DFB_RECTANGLE_ASSERT( rect );
  194. D_ASSERT( width >= 0 );
  195. D_ASSERT( height >= 0 );
  196. rect->w = width;
  197. rect->h = height;
  198. }
  199. static inline void dfb_region_resize( DFBRegion *region,
  200. int width,
  201. int height )
  202. {
  203. DFB_REGION_ASSERT( region );
  204. D_ASSERT( width >= 0 );
  205. D_ASSERT( height >= 0 );
  206. region->x2 = region->x1 + width - 1;
  207. region->y2 = region->y1 + height - 1;
  208. }
  209. static inline bool dfb_region_intersects( const DFBRegion *region,
  210. int x1,
  211. int y1,
  212. int x2,
  213. int y2 )
  214. {
  215. DFB_REGION_ASSERT( region );
  216. D_ASSERT( x1 <= x2 );
  217. D_ASSERT( y1 <= y2 );
  218. return (region->x1 <= x2 &&
  219. region->y1 <= y2 &&
  220. region->x2 >= x1 &&
  221. region->y2 >= y1);
  222. }
  223. static inline bool dfb_region_region_intersects( const DFBRegion *region,
  224. const DFBRegion *other )
  225. {
  226. DFB_REGION_ASSERT( region );
  227. DFB_REGION_ASSERT( other );
  228. return (region->x1 <= other->x2 &&
  229. region->y1 <= other->y2 &&
  230. region->x2 >= other->x1 &&
  231. region->y2 >= other->y1);
  232. }
  233. static inline bool dfb_region_region_extends( const DFBRegion *a,
  234. const DFBRegion *b )
  235. {
  236. if (a->x1 == b->x1 && a->x2 == b->x2)
  237. return (a->y1 == b->y2 - 1) || (a->y2 == b->y1 - 1);
  238. if (a->y1 == b->y1 && a->y2 == b->y2)
  239. return (a->x1 == b->x2 - 1) || (a->x2 == b->x1 - 1);
  240. return false;
  241. }
  242. static inline void dfb_region_region_union( DFBRegion *region,
  243. const DFBRegion *other )
  244. {
  245. DFB_REGION_ASSERT( region );
  246. DFB_REGION_ASSERT( other );
  247. if (region->x1 > other->x1)
  248. region->x1 = other->x1;
  249. if (region->y1 > other->y1)
  250. region->y1 = other->y1;
  251. if (region->x2 < other->x2)
  252. region->x2 = other->x2;
  253. if (region->y2 < other->y2)
  254. region->y2 = other->y2;
  255. }
  256. static inline bool dfb_rectangle_region_intersects( const DFBRectangle *rect,
  257. const DFBRegion *region )
  258. {
  259. DFB_RECTANGLE_ASSERT( rect );
  260. DFB_REGION_ASSERT( region );
  261. return (rect->x <= region->x2 &&
  262. rect->y <= region->y2 &&
  263. rect->x + rect->w > region->x1 &&
  264. rect->y + rect->h > region->y1);
  265. }
  266. static inline void dfb_region_clip( DFBRegion *region,
  267. int x1,
  268. int y1,
  269. int x2,
  270. int y2 )
  271. {
  272. DFB_REGION_ASSERT( region );
  273. D_ASSERT( dfb_region_intersects( region, x1, y1, x2, y2 ) );
  274. if (region->x1 < x1)
  275. region->x1 = x1;
  276. if (region->y1 < y1)
  277. region->y1 = y1;
  278. if (region->x2 > x2)
  279. region->x2 = x2;
  280. if (region->y2 > y2)
  281. region->y2 = y2;
  282. }
  283. static inline void dfb_rectangle_subtract( DFBRectangle *rect,
  284. const DFBInsets *insets )
  285. {
  286. D_ASSERT( rect != NULL );
  287. D_ASSERT( insets != NULL );
  288. rect->x += insets->l;
  289. rect->y += insets->t;
  290. rect->w -= insets->l + insets->r;
  291. rect->h -= insets->t + insets->b;
  292. if (rect->w <= 0 || rect->h <= 0)
  293. rect->w = rect->h = 0;
  294. }
  295. /*
  296. * Compute line segment intersection.
  297. * Return true if intersection point exists within the given segment.
  298. */
  299. bool dfb_line_segment_intersect( const DFBRegion *line,
  300. const DFBRegion *seg,
  301. int *x,
  302. int *y );
  303. /*
  304. * Copied declaration of DFBPixelFormatName from directfb_strings.h
  305. */
  306. extern const struct DFBPixelFormatName dfb_pixelformat_names[];
  307. const char *dfb_input_event_type_name ( DFBInputEventType type );
  308. const char *dfb_pixelformat_name ( DFBSurfacePixelFormat format );
  309. const char *dfb_window_event_type_name( DFBWindowEventType type );
  310. typedef struct {
  311. int magic;
  312. DFBRegion *regions;
  313. int max_regions;
  314. int num_regions;
  315. DFBRegion bounding;
  316. } DFBUpdates;
  317. #define DFB_UPDATES_ASSERT(updates) \
  318. do { \
  319. D_MAGIC_ASSERT( updates, DFBUpdates ); \
  320. D_ASSERT( (updates)->regions != NULL ); \
  321. D_ASSERT( (updates)->max_regions > 0 ); \
  322. D_ASSERT( (updates)->num_regions <= (updates)->max_regions ); \
  323. } while (0)
  324. void dfb_updates_init( DFBUpdates *updates,
  325. DFBRegion *regions,
  326. int max_regions );
  327. void dfb_updates_add ( DFBUpdates *updates,
  328. const DFBRegion *region );
  329. void dfb_updates_stat( DFBUpdates *updates,
  330. int *ret_total,
  331. int *ret_bounding );
  332. void dfb_updates_get_rectangles( DFBUpdates *updates,
  333. DFBRectangle *ret_rects,
  334. int *ret_num );
  335. static inline void
  336. dfb_updates_add_rect( DFBUpdates *updates,
  337. int x,
  338. int y,
  339. int w,
  340. int h )
  341. {
  342. DFBRegion region = DFB_REGION_INIT_FROM_RECTANGLE_VALS( x, y, w, h );
  343. dfb_updates_add( updates, &region );
  344. }
  345. static inline void
  346. dfb_updates_reset( DFBUpdates *updates )
  347. {
  348. D_MAGIC_ASSERT( updates, DFBUpdates );
  349. updates->num_regions = 0;
  350. }
  351. static inline void
  352. dfb_updates_deinit( DFBUpdates *updates )
  353. {
  354. D_MAGIC_ASSERT( updates, DFBUpdates );
  355. D_MAGIC_CLEAR( updates );
  356. }
  357. #ifdef __cplusplus
  358. }
  359. #endif
  360. #endif