summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@l3000.localdomain>2010-11-10 13:18:09 -0500
committerSøren Sandmann Pedersen <ssp@l3000.localdomain>2010-11-10 23:26:52 -0500
commit20da3be10ac3bcf98aa195a81079a3f704f751f9 (patch)
tree38039bb864b1efd8d6826bfe711bcf58a6781337
parent2ebccee793653afc2ff127e8b136d86bae83f467 (diff)
Simplified segment iter
-rw-r--r--demo.c1
-rw-r--r--region-iter.c218
2 files changed, 82 insertions, 137 deletions
diff --git a/demo.c b/demo.c
index 1e35ba1..23765fe 100644
--- a/demo.c
+++ b/demo.c
@@ -68,7 +68,6 @@ on_expose (GtkWidget *widget, GdkEvent *event, gpointer data)
{
corner_t *corners;
int n_corners;
- int new = 0;
cr = gdk_cairo_create (widget->window);
diff --git a/region-iter.c b/region-iter.c
index 41827ba..596dd96 100644
--- a/region-iter.c
+++ b/region-iter.c
@@ -114,7 +114,7 @@ region_builder_add_boxes (region_builder_t *builder,
if (builder->data == BROKEN_DATA)
return FALSE;
-
+
data = region_data_append (builder->data, n, boxes);
if (!data)
@@ -140,7 +140,7 @@ region_builder_finish (region_builder_t *builder, pixman_region32_t *region)
}
else if (builder->data == BROKEN_DATA)
{
-
+
}
else
{
@@ -149,7 +149,6 @@ region_builder_finish (region_builder_t *builder, pixman_region32_t *region)
}
/* Region iterator */
-
static void
region_iter_init (region_iter_t *iter, pixman_region32_t *region)
{
@@ -303,6 +302,25 @@ overlapped_iter_get_rows (overlapped_iter_t *iter, row_t *row1, row_t *row2)
}
/* Row iter */
+typedef enum
+{
+ /* These are used when iterating a single row */
+ OFF = 0x00,
+ ON = 0x01,
+
+ /* These are used when iterating two rows */
+ ROW1 = 0x01,
+ ROW2 = 0x02,
+ BOTH = 0x03
+} segment_type_t;
+
+typedef struct segment_t segment_t;
+struct segment_t
+{
+ segment_type_t type;
+ int x1, x2;
+};
+
typedef struct row_iter_t row_iter_t;
struct row_iter_t
@@ -338,39 +356,45 @@ row_iter_init (row_iter_t *iter, const row_t *row)
}
static pixman_bool_t
-row_iter_get_box (row_iter_t *iter, int *x1, int *x2, pixman_bool_t *on)
+row_iter_get_segment (row_iter_t *iter, segment_t *segment)
{
switch (iter->state)
{
case FIRST:
- *on = FALSE;
- *x1 = INT_MIN;
+ segment->type = OFF;
+ segment->x1 = INT_MIN;
if (iter->u.first.row->first)
{
- *x2 = iter->u.first.row->first->x1;
+ const pixman_box32_t *first, *last;
+
+ segment->x2 = iter->u.first.row->first->x1;
iter->state = MIDDLE;
- iter->u.middle.first = iter->u.first.row->first;
- iter->u.middle.last = iter->u.first.row->last;
+
+ first = iter->u.first.row->first;
+ last = iter->u.first.row->last;
+
+ iter->u.middle.first = first;
+ iter->u.middle.last = last;
}
else
{
- *x2 = INT_MAX;
+ segment->x2 = INT_MAX;
iter->state = DONE;
}
break;
case MIDDLE:
- *on = TRUE;
- *x1 = iter->u.middle.first->x1;
- *x2 = iter->u.middle.first->x2;
+ segment->type = ON;
+ segment->x1 = iter->u.middle.first->x1;
+ segment->x2 = iter->u.middle.first->x2;
iter->u.middle.first++;
if (iter->u.middle.first == iter->u.middle.last)
{
iter->state = FINAL;
- iter->u.final.x1 = *x2;
+ iter->u.final.x1 = segment->x2;
}
else
{
@@ -379,16 +403,17 @@ row_iter_get_box (row_iter_t *iter, int *x1, int *x2, pixman_bool_t *on)
break;
case EMPTY:
- *on = FALSE;
- *x1 = (iter->u.middle.first - 1)->x2;
- *x2 = iter->u.middle.first->x1;
+ segment->type = OFF;
+ segment->x1 = (iter->u.middle.first - 1)->x2;
+ segment->x2 = iter->u.middle.first->x1;
iter->state = MIDDLE;
break;
case FINAL:
- *on = FALSE;
- *x1 = iter->u.final.x1;
- *x2 = INT_MAX;
+ segment->type = OFF;
+ segment->x1 = iter->u.final.x1;
+ segment->x2 = INT_MAX;
+ iter->state = DONE;
break;
case DONE:
@@ -399,127 +424,49 @@ row_iter_get_box (row_iter_t *iter, int *x1, int *x2, pixman_bool_t *on)
}
/* Segment iter */
-typedef enum
-{
- ROW1 = 0x01,
- ROW2 = 0x02,
- BOTH = 0x03
-} segment_type_t;
-
typedef struct segment_iter_t segment_iter_t;
struct segment_iter_t
{
- const pixman_box32_t *p1, *p2;
- const pixman_box32_t *row1_end, *row2_end;
- int x1, x2;
+ row_iter_t row1;
+ row_iter_t row2;
+ segment_t segment1;
+ segment_t segment2;
};
static void
segment_iter_init (segment_iter_t *iter, const row_t *row1, const row_t *row2)
{
- iter->p1 = row1->first;
- iter->p2 = row2->first;
- iter->row1_end = row1->last;
- iter->row2_end = row2->last;
+ row_iter_init (&iter->row1, row1);
+ row_iter_init (&iter->row2, row2);
- iter->x1 = 0;
- iter->x2 = 0;
+ row_iter_get_segment (&iter->row1, &iter->segment1);
+ row_iter_get_segment (&iter->row2, &iter->segment2);
}
static pixman_bool_t
-segment_iter_get_segment (segment_iter_t *iter,
- int *x1, int *x2, segment_type_t *type)
+segment_iter_get_segment (segment_iter_t *iter, segment_t *segment)
{
- if (iter->p1 == iter->row1_end && iter->p2 == iter->row2_end)
- return FALSE;
+ int m = MIN (iter->segment1.x2, iter->segment2.x2);
- if (iter->p1 == iter->row1_end)
- {
- *x1 = iter->p2->x1 + iter->x2;
- *x2 = iter->p2->x2;
- *type = ROW2;
+ segment->x1 = iter->segment1.x1;
+ segment->x2 = m;
- iter->p2++;
- iter->x2 = 0;
- return TRUE;
- }
-
- if (iter->p2 == iter->row2_end)
- {
- *x1 = iter->p1->x1 + iter->x1;
- *x2 = iter->p1->x2;
- *type = ROW1;
-
- iter->p1++;
- iter->x1 = 0;
- return TRUE;
- }
-
- if (iter->p1->x1 + iter->x1 < iter->p2->x1 + iter->x2)
- {
- *x1 = iter->p1->x1 + iter->x1;
- *type = ROW1;
+ segment->type = (iter->segment1.type | (iter->segment2.type << 1));
- if (iter->p1->x2 <= iter->p2->x1 + iter->x2)
- {
- *x2 = iter->p1->x2;
- iter->p1++;
- iter->x1 = 0;
- }
- else
- {
- *x2 = iter->p2->x1 + iter->x2;
- iter->x1 = iter->p2->x1 + iter->x2 - iter->p1->x1;
- }
- return TRUE;
- }
+ iter->segment1.x1 = iter->segment2.x1 = m;
- if (iter->p2->x1 + iter->x2 < iter->p1->x1 + iter->x1)
+ if (iter->segment1.x1 == iter->segment1.x2)
{
- *x1 = iter->p2->x1 + iter->x2;
- *type = ROW2;
-
- if (iter->p2->x2 <= iter->p1->x1 + iter->x1)
- {
- *x2 = iter->p2->x2;
- iter->p2++;
- iter->x2 = 0;
- }
- else
- {
- *x2 = iter->p1->x1 + iter->x1;
- iter->x2 = iter->p1->x1 + iter->x1 - iter->p2->x1;
- }
- return TRUE;
- }
-
- /* If we get here, the two segments start at the same X */
- *x1 = iter->p1->x1 + iter->x1;
- *type = BOTH;
-
- if (iter->p1->x2 < iter->p2->x2)
- {
- *x2 = iter->p1->x2;
- iter->p1++;
- iter->x1 = 0;
- iter->x2 += (*x2 - *x1);
- return TRUE;
+ if (!row_iter_get_segment (&iter->row1, &iter->segment1))
+ return FALSE;
}
- if (iter->p2->x2 < iter->p1->x2)
+ if (iter->segment2.x1 == iter->segment2.x2)
{
- *x2 = iter->p2->x2;
- iter->p2++;
- iter->x2 = 0;
- iter->x1 += (*x2 - *x1);
- return TRUE;
+ if (!row_iter_get_segment (&iter->row2, &iter->segment2))
+ return FALSE;
}
- *x2 = iter->p2->x2;
- iter->p2++;
- iter->p1++;
- iter->x2 = 0;
- iter->x1 = 0;
return TRUE;
}
@@ -544,17 +491,17 @@ region_op (ops_t op,
while (overlapped_iter_get_rows (&iter, &row1, &row2))
{
segment_iter_t seg_iter;
- segment_type_t type;
- int x1, x2;
+ segment_t segment;
segment_iter_init (&seg_iter, &row1, &row2);
- while (segment_iter_get_segment (&seg_iter, &x1, &x2, &type))
+ while (segment_iter_get_segment (&seg_iter, &segment))
{
- if (op & (1 << type))
+ if (op & (1 << segment.type))
{
printf ("box at %d %d %d %d %s\n",
- x1, row1.y1, x2, row1.y2,
- (x1 == x2 || row1.y1 == row2.y2)? "[empty]" : "");
+ segment.x1, row1.y1, segment.x2, row1.y2,
+ (segment.x1 == segment.x2 ||
+ row1.y1 == row2.y2)? "[empty]" : "");
}
}
}
@@ -702,8 +649,7 @@ region_path (pixman_region32_t *region, int *n)
while (region_iter_get_row (&iter, &row2))
{
segment_iter_t seg_iter;
- segment_type_t type;
- int x1, x2;
+ segment_t segment;
int *old_active;
int old_n_active;
@@ -717,22 +663,22 @@ region_path (pixman_region32_t *region, int *n)
current = 0;
segment_iter_init (&seg_iter, &row1, &row2);
- while (segment_iter_get_segment (&seg_iter, &x1, &x2, &type))
+ while (segment_iter_get_segment (&seg_iter, &segment))
{
- if (type == ROW1 || type == ROW2)
+ if (segment.type == ROW1 || segment.type == ROW2)
{
int c1, c2;
int p1 = -1;
int p2 = -1;
while (current < old_n_active &&
- corners[old_active[current]].x <= x2)
+ corners[old_active[current]].x <= segment.x2)
{
int c = old_active[current];
- if (corners[c].x == x1)
+ if (corners[c].x == segment.x1)
p1 = c;
- else if (corners[c].x == x2)
+ else if (corners[c].x == segment.x2)
p2 = c;
else
active = add_active (active, &n_active, c);
@@ -741,14 +687,14 @@ region_path (pixman_region32_t *region, int *n)
}
corners = add_corners (corners, &n_corners, &c1, &c2);
- corners[c1].x = x1;
+ corners[c1].x = segment.x1;
corners[c1].y = row1.y2;
- corners[c2].x = x2;
+ corners[c2].x = segment.x2;
corners[c2].y = row1.y2;
if (p1 != -1)
{
- if (type == ROW1)
+ if (segment.type == ROW1)
corners[p1].next = c1;
else
corners[c1].next = p1;
@@ -760,7 +706,7 @@ region_path (pixman_region32_t *region, int *n)
if (p2 != -1)
{
- if (type == ROW1)
+ if (segment.type == ROW1)
corners[c2].next = p2;
else
corners[p2].next = c2;
@@ -770,7 +716,7 @@ region_path (pixman_region32_t *region, int *n)
active = add_active (active, &n_active, c2);
}
- if (type == ROW1)
+ if (segment.type == ROW1)
corners[c1].next = c2;
else
corners[c2].next = c1;