summaryrefslogtreecommitdiff
path: root/Source/DirectFB/include/directfb_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/include/directfb_util.h')
-rwxr-xr-xSource/DirectFB/include/directfb_util.h612
1 files changed, 612 insertions, 0 deletions
diff --git a/Source/DirectFB/include/directfb_util.h b/Source/DirectFB/include/directfb_util.h
new file mode 100755
index 0000000..1d3caae
--- /dev/null
+++ b/Source/DirectFB/include/directfb_util.h
@@ -0,0 +1,612 @@
+/*
+ (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))
+
+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;
+}
+
+static inline void dfb_region_from_rotated( DFBRegion *region,
+ const DFBRegion *from,
+ const DFBDimension *size,
+ int rotation )
+{
+ D_ASSERT( region != NULL );
+
+ DFB_REGION_ASSERT( from );
+ D_ASSERT( size != NULL );
+ D_ASSERT( size->w > 0 );
+ D_ASSERT( size->h > 0 );
+ D_ASSUME( rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270 );
+
+ switch (rotation) {
+ default:
+ D_BUG( "invalid rotation %d", rotation );
+ case 0:
+ *region = *from;
+ break;
+
+ case 90:
+ region->x1 = from->y1;
+ region->y1 = size->w - from->x2 - 1;
+ region->x2 = from->y2;
+ region->y2 = size->w - from->x1 - 1;
+ break;
+
+ case 180:
+ region->x1 = size->w - from->x2 - 1;
+ region->y1 = size->h - from->y2 - 1;
+ region->x2 = size->w - from->x1 - 1;
+ region->y2 = size->h - from->y1 - 1;
+ break;
+
+ case 270:
+ region->x1 = size->h - from->y2 - 1;
+ region->y1 = from->x1;
+ region->x2 = size->h - from->y1 - 1;
+ region->y2 = from->x2;
+ break;
+ }
+
+ DFB_REGION_ASSERT( region );
+}
+
+static inline void dfb_rectangle_from_rotated( DFBRectangle *rectangle,
+ const DFBRectangle *from,
+ const DFBDimension *size,
+ int rotation )
+{
+ D_ASSERT( rectangle != NULL );
+
+ DFB_RECTANGLE_ASSERT( from );
+ D_ASSERT( size != NULL );
+ D_ASSERT( size->w > 0 );
+ D_ASSERT( size->h > 0 );
+ D_ASSUME( rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270 );
+
+ switch (rotation) {
+ default:
+ D_BUG( "invalid rotation %d", rotation );
+ case 0:
+ *rectangle = *from;
+ break;
+
+ case 90:
+ rectangle->x = from->y;
+ rectangle->y = size->w - from->x - from->w;
+ rectangle->w = from->h;
+ rectangle->h = from->w;
+ break;
+
+ case 180:
+ rectangle->x = size->w - from->x - from->w;
+ rectangle->y = size->h - from->y - from->h;
+ rectangle->w = from->w;
+ rectangle->h = from->h;
+ break;
+
+ case 270:
+ rectangle->x = size->h - from->y - from->h;
+ rectangle->y = from->x;
+ rectangle->w = from->h;
+ rectangle->h = from->w;
+ break;
+ }
+
+ DFB_RECTANGLE_ASSERT( rectangle );
+}
+
+static inline void dfb_point_from_rotated_region( DFBPoint *point,
+ const DFBRegion *from,
+ const DFBDimension *size,
+ int rotation )
+{
+ D_ASSERT( point != NULL );
+
+ DFB_REGION_ASSERT( from );
+ D_ASSERT( size != NULL );
+ D_ASSERT( size->w > 0 );
+ D_ASSERT( size->h > 0 );
+ D_ASSUME( rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270 );
+
+ switch (rotation) {
+ default:
+ D_BUG( "invalid rotation %d", rotation );
+ case 0:
+ point->x = from->x1;
+ point->y = from->y1;
+ break;
+
+ case 90:
+ point->x = from->y1;
+ point->y = size->w - from->x2 - 1;
+ break;
+
+ case 180:
+ point->x = size->w - from->x2 - 1;
+ point->y = size->h - from->y2 - 1;
+ break;
+
+ case 270:
+ point->x = size->h - from->y2 - 1;
+ point->y = from->x1;
+ break;
+ }
+
+ D_ASSERT( point->x >= 0 );
+ D_ASSERT( point->y >= 0 );
+ D_ASSERT( point->x < size->w );
+ D_ASSERT( point->y < size->h );
+}
+
+
+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.
+ */
+static inline bool dfb_line_segment_intersect( const DFBRegion *line,
+ const DFBRegion *seg,
+ int *x,
+ int *y )
+{
+ int x1, x2, x3, x4;
+ int y1, y2, y3, y4;
+ int num, den;
+
+ D_ASSERT( line != NULL );
+ D_ASSERT( seg != NULL );
+
+ x1 = seg->x1; y1 = seg->y1; x2 = seg->y2; y2 = seg->y2;
+ x3 = line->x1; y3 = line->y1; x4 = line->x2; y4 = line->y2;
+
+ num = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
+ den = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
+
+ if (!den) /* parallel */
+ return false;
+
+ if (num && ((num < 0) != (den < 0) || abs(num) > abs(den))) /* not within segment */
+ return false;
+
+ if (x)
+ *x = (s64)(x2 - x1) * num / den + x1;
+ if (y)
+ *y = (s64)(y2 - y1) * num / den + y1;
+
+ return true;
+}
+
+
+/*
+ * 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, &region );
+}
+
+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