summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2010-11-08 03:53:10 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2010-11-08 03:53:10 -0500
commite6029a6270402ee4240c75aa509c4855d16b7c36 (patch)
tree2b92d535addc4cfd40d339a1b3306e36a74953c2
parent595f5962e210b7f0970e2563a8c2f8cf97b082cd (diff)
qwer
-rw-r--r--demo.c19
-rw-r--r--region-iter.c62
2 files changed, 65 insertions, 16 deletions
diff --git a/demo.c b/demo.c
index 66e3e8d..1e35ba1 100644
--- a/demo.c
+++ b/demo.c
@@ -6,7 +6,6 @@
#include "region-iter.c"
static const pixman_rectangle32_t rects[] = {
-#if 0
{ 0, 50, 200, 100 },
{ 250, 0, 200, 100 },
{ 500, 0, 50, 350 },
@@ -21,19 +20,31 @@ static const pixman_rectangle32_t rects[] = {
{ 450, 350, 50, 50 },
{ 50, 450, 400, 50 },
{ 25, 135, 600, 25 }
-#endif
};
+#define N_RECTS (sizeof (rects) / sizeof (rects[0]))
+
static corner_t *
make_path (int *n_corners)
{
corner_t *corners;
pixman_region32_t region;
int i;
+ pixman_box32_t *boxes = malloc (N_RECTS * sizeof (pixman_box32_t));
+
+ for (i = 0; i < N_RECTS; ++i)
+ {
+ boxes[i].x1 = rects[i].x;
+ boxes[i].y1 = rects[i].y;
+ boxes[i].x2 = rects[i].x + rects[i].width;
+ boxes[i].y2 = rects[i].y + rects[i].height;
+ }
+ region_from_boxes (&region, boxes, N_RECTS);
+
pixman_region32_init (&region);
- for (i = 0; i < sizeof (rects) / sizeof (rects[0]); ++i)
+ for (i = 0; i < N_RECTS; ++i)
{
pixman_region32_union_rect (&region, &region,
50 + rects[i].x, 50 + rects[i].y,
@@ -61,7 +72,7 @@ on_expose (GtkWidget *widget, GdkEvent *event, gpointer data)
cr = gdk_cairo_create (widget->window);
- for (i = 0; i < sizeof (rects) / sizeof (rects[0]); ++i)
+ for (i = 0; i < N_RECTS; ++i)
{
cairo_rectangle (cr,
50 + rects[i].x, 50 + rects[i].y,
diff --git a/region-iter.c b/region-iter.c
index f42c655..90f8ead 100644
--- a/region-iter.c
+++ b/region-iter.c
@@ -433,7 +433,7 @@ typedef enum
SUBTRACT = (1 << ROW1)
} ops_t;
-static void
+static pixman_bool_t
region_op (ops_t op,
pixman_region32_t *dst,
pixman_region32_t *src1,
@@ -463,10 +463,10 @@ region_op (ops_t op,
}
static int
-compare_boxes (void *box1v, void *box2v)
+compare_boxes (const void *box1v, const void *box2v)
{
- pixman_box32_t *box1 = box1v;
- pixman_box32_t *box2 = box2v;
+ const pixman_box32_t *box1 = box1v;
+ const pixman_box32_t *box2 = box2v;
int c;
if ((c = box1->y1 - box2->y1) == 0)
@@ -475,6 +475,42 @@ compare_boxes (void *box1v, void *box2v)
return c;
}
+static pixman_bool_t
+make_region_from_sorted (pixman_region32_t *region, pixman_box32_t *boxes, int n_boxes)
+{
+ if (n_boxes == 1)
+ {
+ pixman_region32_init_rect (region,
+ boxes[0].x1, boxes[0].y1,
+ boxes[0].x2, boxes[0].y2);
+ }
+ else
+ {
+ pixman_region32_t tmp;
+ int n_left = n_boxes / 2;
+ int n_right = n_boxes - n_left;
+
+ if (!make_region_from_sorted (region, boxes, n_left))
+ return FALSE;
+
+ if (!make_region_from_sorted (&tmp, boxes + n_left, n_right))
+ {
+ pixman_region32_fini (region);
+ return FALSE;
+ }
+
+ if (!region_op (UNION, region, region, &tmp))
+ {
+ pixman_region32_fini (region);
+ pixman_region32_fini (&tmp);
+
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+}
+
pixman_bool_t
region_from_boxes (pixman_region32_t *region, const pixman_box32_t *boxes, int n_boxes)
{
@@ -487,11 +523,15 @@ region_from_boxes (pixman_region32_t *region, const pixman_box32_t *boxes, int n
{
pixman_box32_t *copy = malloc (sizeof (pixman_box32_t) * n_boxes);
int displacement, i;
+ pixman_bool_t ret;
+ if (!copy)
+ return FALSE;
+
displacement = 0;
for (i = 0; i < n_boxes; ++i)
{
- pixman_box32_t *box = boxes + i;
+ const pixman_box32_t *box = boxes + i;
if (box->x1 >= box->x2 || box->y1 >= box->y2)
displacement++;
@@ -500,15 +540,13 @@ region_from_boxes (pixman_region32_t *region, const pixman_box32_t *boxes, int n
}
qsort (copy, i - displacement, sizeof (pixman_box32_t), compare_boxes);
+
+ ret = make_region_from_sorted (region, copy, i - displacement);
- make_region_from_boxes (region, copy, i - displacement);
- }
-
- else if (n_boxes == 1)
-
- pixman_region32_t tmp;
+ free (copy);
- qsort
+ return ret;
+ }
}
typedef struct corner_t corner_t;