123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- /*
- (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
- (c) Copyright 2000-2004 Convergence (integrated media) GmbH
- All rights reserved.
- Written by Denis Oliver Kropp <dok@directfb.org>,
- Andreas Hundt <andi@fischlustig.de>,
- Sven Neumann <neo@directfb.org>,
- Ville Syrjälä <syrjala@sci.fi> and
- Claudio Ciccani <klan@users.sf.net>.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
- #ifndef __DIRECTFB_UTIL_H__
- #define __DIRECTFB_UTIL_H__
- #include <stdlib.h>
- #include <errno.h>
- #include <directfb.h>
- #ifdef __cplusplus
- extern "C"
- {
- #endif
- #include <directfb_strings.h>
- #include <direct/types.h>
- #include <direct/debug.h>
- bool dfb_region_intersect( DFBRegion *region,
- int x1, int y1, int x2, int y2 );
- bool dfb_region_region_intersect( DFBRegion *region,
- const DFBRegion *clip );
- bool dfb_region_rectangle_intersect( DFBRegion *region,
- const DFBRectangle *rect );
- bool dfb_unsafe_region_intersect( DFBRegion *region,
- int x1, int y1, int x2, int y2 );
- bool dfb_unsafe_region_rectangle_intersect( DFBRegion *region,
- const DFBRectangle *rect );
- bool dfb_rectangle_intersect_by_unsafe_region( DFBRectangle *rectangle,
- DFBRegion *region );
- bool dfb_rectangle_intersect_by_region( DFBRectangle *rectangle,
- const DFBRegion *region );
- bool dfb_rectangle_intersect( DFBRectangle *rectangle,
- const DFBRectangle *clip );
- /* returns the result in the first rectangle */
- void dfb_rectangle_union ( DFBRectangle *rect1,
- const DFBRectangle *rect2 );
- #define DFB_RECTANGLE_ASSERT(r) \
- do { \
- D_ASSERT( (r) != NULL ); \
- D_ASSERT( (r)->w >= 0 ); \
- D_ASSERT( (r)->h >= 0 ); \
- } while (0)
- #define DFB_RECTANGLE_ASSERT_IF(r) \
- do { \
- if ((r) != NULL) { \
- D_ASSERT( (r)->w >= 0 ); \
- D_ASSERT( (r)->h >= 0 ); \
- } \
- } while (0)
- #define DFB_RECTANGLE_VALS(r) (r)->x, (r)->y, (r)->w, (r)->h
- #define DFB_RECTANGLE_VALS_FROM_REGION(r) (r)->x1, (r)->y1, (r)->x2-(r)->x1+1, (r)->y2-(r)->y1+1
- #define DFB_RECTANGLE_INIT_FROM_REGION(r) (DFBRectangle){ DFB_RECTANGLE_VALS_FROM_REGION(r) }
- #define DFB_RECTANGLE_CONTAINS_POINT(r,X,Y) (((X) >= (r)->x) && ((X) < (r)->x + (r)->w) && \
- ((Y) >= (r)->y) && ((Y) < (r)->y + (r)->h))
- #define DFB_RECTANGLES_DEBUG_AT( Domain, rects, num ) \
- do { \
- unsigned int i; \
- \
- for (i=0; i<(num); i++) \
- D_DEBUG_AT( Domain, " -> [%2d] %4d,%4d-%4dx%4d\n", i, DFB_RECTANGLE_VALS(&(rects)[i]) ); \
- } while (0)
- #define DFB_TRIANGLE_VALS(t) (t)->x1, (t)->y1, (t)->x2, (t)->y2, (t)->x3, (t)->y3
- #define DFB_COLORKEY_VALS(c) (c)->r, (c)->g, (c)->b, (c)->index
- #define DFB_REGION_CHECK(r) \
- ((r) != NULL && \
- (r)->x1 <= (r)->x2 && \
- (r)->y1 <= (r)->y2)
- #define DFB_REGION_CHECK_IF(r) \
- ((r) == NULL || \
- ((r)->x1 <= (r)->x2 && \
- (r)->y1 <= (r)->y2))
- #define DFB_REGION_ASSERT(r) \
- do { \
- D_ASSERT( (r) != NULL ); \
- D_ASSERT( (r)->x1 <= (r)->x2 ); \
- D_ASSERT( (r)->y1 <= (r)->y2 ); \
- } while (0)
- #define DFB_REGION_ASSERT_IF(r) \
- do { \
- if ((r) != NULL) { \
- D_ASSERT( (r)->x1 <= (r)->x2 ); \
- D_ASSERT( (r)->y1 <= (r)->y2 ); \
- } \
- } while (0)
- #define DFB_REGION_VALS(r) (r)->x1, (r)->y1, (r)->x2, (r)->y2
- #define DFB_REGION_VALS_FROM_DIMENSION(d) 0, 0, (d)->w-1, (d)->h-1
- #define DFB_REGION_INIT_FROM_DIMENSION(d) (DFBRegion){ DFB_REGION_VALS_FROM_DIMENSION(d) }
- #define DFB_REGION_VALS_FROM_RECTANGLE(r) (r)->x, (r)->y, (r)->x+(r)->w-1, (r)->y+(r)->h-1
- #define DFB_REGION_INIT_FROM_RECTANGLE(r) (DFBRegion){ DFB_REGION_VALS_FROM_RECTANGLE(r) }
- #define DFB_REGION_VALS_FROM_RECTANGLE_VALS(x,y,w,h) (x), (y), (x)+(w)-1, (y)+(h)-1
- #define DFB_REGION_INIT_FROM_RECTANGLE_VALS(x,y,w,h) (DFBRegion){ DFB_REGION_VALS_FROM_RECTANGLE_VALS(x,y,w,h) }
- #define DFB_REGION_VALS_TRANSLATED(r,x,y) (r)->x1 + x, (r)->y1 + y, (r)->x2 + x, (r)->y2 + y
- #define DFB_REGION_INIT_TRANSLATED(r,x,y) (DFBRegion){ DFB_REGION_VALS_TRANSLATED(r,x,y) }
- #define DFB_REGION_VALS_INTERSECTED(r,X1,Y1,X2,Y2) (r)->x1 > (X1) ? (r)->x1 : (X1), \
- (r)->y1 > (Y1) ? (r)->y1 : (Y1), \
- (r)->x2 < (X2) ? (r)->x2 : (X2), \
- (r)->y2 < (Y2) ? (r)->y2 : (Y2)
- #define DFB_REGION_INIT_INTERSECTED(r,X1,Y1,X2,Y2) (DFBRegion){ DFB_REGION_VALS_INTERSECTED(r,X1,Y1,X2,Y2) }
- #define DFB_REGION_CONTAINS_POINT(r,X,Y) (((X) >= (r)->x1) && ((X) <= (r)->x2) && \
- ((Y) >= (r)->y1) && ((Y) <= (r)->y2))
- #define DFB_REGIONS_DEBUG_AT( Domain, regions, num ) \
- do { \
- unsigned int i; \
- \
- for (i=0; i<(num); i++) \
- D_DEBUG_AT( Domain, " -> [%2d] %4d,%4d-%4d,%4d\n", i, DFB_REGION_VALS(&(regions)[i]) ); \
- } while (0)
- static inline void dfb_rectangle_from_region( DFBRectangle *rect,
- const DFBRegion *region )
- {
- D_ASSERT( rect != NULL );
- DFB_REGION_ASSERT( region );
- rect->x = region->x1;
- rect->y = region->y1;
- rect->w = region->x2 - region->x1 + 1;
- rect->h = region->y2 - region->y1 + 1;
- }
- static inline void dfb_rectangle_from_rectangle_plus_insets( DFBRectangle *rect,
- const DFBRectangle *inner,
- const DFBInsets *insets )
- {
- D_ASSERT( rect != NULL );
- D_ASSERT( insets != NULL );
- DFB_RECTANGLE_ASSERT( inner );
- rect->x = inner->x - insets->l;
- rect->y = inner->y - insets->t;
- rect->w = inner->w + insets->l + insets->r;
- rect->h = inner->h + insets->t + insets->b;
- }
- static inline void dfb_region_from_rectangle( DFBRegion *region,
- const DFBRectangle *rect )
- {
- D_ASSERT( region != NULL );
- DFB_RECTANGLE_ASSERT( rect );
- D_ASSERT( rect->w > 0 );
- D_ASSERT( rect->h > 0 );
- region->x1 = rect->x;
- region->y1 = rect->y;
- region->x2 = rect->x + rect->w - 1;
- region->y2 = rect->y + rect->h - 1;
- }
- void dfb_region_from_rotated( DFBRegion *region,
- const DFBRegion *from,
- const DFBDimension *size,
- int rotation );
- void dfb_rectangle_from_rotated( DFBRectangle *rectangle,
- const DFBRectangle *from,
- const DFBDimension *size,
- int rotation );
- void dfb_point_from_rotated_region( DFBPoint *point,
- const DFBRegion *from,
- const DFBDimension *size,
- int rotation );
- static inline void dfb_rectangle_translate( DFBRectangle *rect,
- int dx,
- int dy )
- {
- DFB_RECTANGLE_ASSERT( rect );
- rect->x += dx;
- rect->y += dy;
- }
- static inline void dfb_region_translate( DFBRegion *region,
- int dx,
- int dy )
- {
- DFB_REGION_ASSERT( region );
- region->x1 += dx;
- region->y1 += dy;
- region->x2 += dx;
- region->y2 += dy;
- }
- static inline void dfb_rectangle_resize( DFBRectangle *rect,
- int width,
- int height )
- {
- DFB_RECTANGLE_ASSERT( rect );
- D_ASSERT( width >= 0 );
- D_ASSERT( height >= 0 );
- rect->w = width;
- rect->h = height;
- }
- static inline void dfb_region_resize( DFBRegion *region,
- int width,
- int height )
- {
- DFB_REGION_ASSERT( region );
- D_ASSERT( width >= 0 );
- D_ASSERT( height >= 0 );
- region->x2 = region->x1 + width - 1;
- region->y2 = region->y1 + height - 1;
- }
- static inline bool dfb_region_intersects( const DFBRegion *region,
- int x1,
- int y1,
- int x2,
- int y2 )
- {
- DFB_REGION_ASSERT( region );
- D_ASSERT( x1 <= x2 );
- D_ASSERT( y1 <= y2 );
- return (region->x1 <= x2 &&
- region->y1 <= y2 &&
- region->x2 >= x1 &&
- region->y2 >= y1);
- }
- static inline bool dfb_region_region_intersects( const DFBRegion *region,
- const DFBRegion *other )
- {
- DFB_REGION_ASSERT( region );
- DFB_REGION_ASSERT( other );
- return (region->x1 <= other->x2 &&
- region->y1 <= other->y2 &&
- region->x2 >= other->x1 &&
- region->y2 >= other->y1);
- }
- static inline bool dfb_region_region_extends( const DFBRegion *a,
- const DFBRegion *b )
- {
- if (a->x1 == b->x1 && a->x2 == b->x2)
- return (a->y1 == b->y2 - 1) || (a->y2 == b->y1 - 1);
- if (a->y1 == b->y1 && a->y2 == b->y2)
- return (a->x1 == b->x2 - 1) || (a->x2 == b->x1 - 1);
- return false;
- }
- static inline void dfb_region_region_union( DFBRegion *region,
- const DFBRegion *other )
- {
- DFB_REGION_ASSERT( region );
- DFB_REGION_ASSERT( other );
- if (region->x1 > other->x1)
- region->x1 = other->x1;
- if (region->y1 > other->y1)
- region->y1 = other->y1;
- if (region->x2 < other->x2)
- region->x2 = other->x2;
- if (region->y2 < other->y2)
- region->y2 = other->y2;
- }
- static inline bool dfb_rectangle_region_intersects( const DFBRectangle *rect,
- const DFBRegion *region )
- {
- DFB_RECTANGLE_ASSERT( rect );
- DFB_REGION_ASSERT( region );
- return (rect->x <= region->x2 &&
- rect->y <= region->y2 &&
- rect->x + rect->w > region->x1 &&
- rect->y + rect->h > region->y1);
- }
- static inline void dfb_region_clip( DFBRegion *region,
- int x1,
- int y1,
- int x2,
- int y2 )
- {
- DFB_REGION_ASSERT( region );
- D_ASSERT( dfb_region_intersects( region, x1, y1, x2, y2 ) );
- if (region->x1 < x1)
- region->x1 = x1;
- if (region->y1 < y1)
- region->y1 = y1;
- if (region->x2 > x2)
- region->x2 = x2;
- if (region->y2 > y2)
- region->y2 = y2;
- }
- static inline void dfb_rectangle_subtract( DFBRectangle *rect,
- const DFBInsets *insets )
- {
- D_ASSERT( rect != NULL );
- D_ASSERT( insets != NULL );
- rect->x += insets->l;
- rect->y += insets->t;
- rect->w -= insets->l + insets->r;
- rect->h -= insets->t + insets->b;
- if (rect->w <= 0 || rect->h <= 0)
- rect->w = rect->h = 0;
- }
- /*
- * Compute line segment intersection.
- * Return true if intersection point exists within the given segment.
- */
- bool dfb_line_segment_intersect( const DFBRegion *line,
- const DFBRegion *seg,
- int *x,
- int *y );
- /*
- * Copied declaration of DFBPixelFormatName from directfb_strings.h
- */
- extern const struct DFBPixelFormatName dfb_pixelformat_names[];
- const char *dfb_input_event_type_name ( DFBInputEventType type );
- const char *dfb_pixelformat_name ( DFBSurfacePixelFormat format );
- const char *dfb_window_event_type_name( DFBWindowEventType type );
- typedef struct {
- int magic;
- DFBRegion *regions;
- int max_regions;
- int num_regions;
- DFBRegion bounding;
- } DFBUpdates;
- #define DFB_UPDATES_ASSERT(updates) \
- do { \
- D_MAGIC_ASSERT( updates, DFBUpdates ); \
- D_ASSERT( (updates)->regions != NULL ); \
- D_ASSERT( (updates)->max_regions > 0 ); \
- D_ASSERT( (updates)->num_regions <= (updates)->max_regions ); \
- } while (0)
- void dfb_updates_init( DFBUpdates *updates,
- DFBRegion *regions,
- int max_regions );
- void dfb_updates_add ( DFBUpdates *updates,
- const DFBRegion *region );
- void dfb_updates_stat( DFBUpdates *updates,
- int *ret_total,
- int *ret_bounding );
- void dfb_updates_get_rectangles( DFBUpdates *updates,
- DFBRectangle *ret_rects,
- int *ret_num );
- static inline void
- dfb_updates_add_rect( DFBUpdates *updates,
- int x,
- int y,
- int w,
- int h )
- {
- DFBRegion region = DFB_REGION_INIT_FROM_RECTANGLE_VALS( x, y, w, h );
- dfb_updates_add( updates, ®ion );
- }
- static inline void
- dfb_updates_reset( DFBUpdates *updates )
- {
- D_MAGIC_ASSERT( updates, DFBUpdates );
- updates->num_regions = 0;
- }
- static inline void
- dfb_updates_deinit( DFBUpdates *updates )
- {
- D_MAGIC_ASSERT( updates, DFBUpdates );
- D_MAGIC_CLEAR( updates );
- }
- #ifdef __cplusplus
- }
- #endif
- #endif
|