summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@l3000.localdomain>2010-11-10 11:40:50 -0500
committerSøren Sandmann Pedersen <ssp@l3000.localdomain>2010-11-10 23:25:59 -0500
commit2ebccee793653afc2ff127e8b136d86bae83f467 (patch)
tree8c87734f58e10d19a1597ec4c13ab73b29ce58af
parent4277dca05c442e6798c4a5029c4c1587b3c35d5e (diff)
row iter
-rw-r--r--region-iter.c121
1 files changed, 108 insertions, 13 deletions
diff --git a/region-iter.c b/region-iter.c
index cf64ec2..41827ba 100644
--- a/region-iter.c
+++ b/region-iter.c
@@ -18,7 +18,7 @@ typedef enum
{
FIRST,
MIDDLE,
- EMPTY_ROW,
+ EMPTY,
FINAL,
DONE
} state_t;
@@ -163,14 +163,14 @@ region_iter_get_row (region_iter_t *iter, row_t *row)
pixman_box32_t *first;
pixman_box32_t *last;
pixman_box32_t *box;
-
+
switch (iter->state)
{
case FIRST:
row->y1 = INT_MIN;
row->first = NULL;
row->last = NULL;
-
+
if (!iter->u.first.region->data)
{
iter->state = MIDDLE;
@@ -188,7 +188,7 @@ region_iter_get_row (region_iter_t *iter, row_t *row)
first = (pixman_box32_t *)(iter->u.first.region->data + 1);
last = first + iter->u.first.region->data->numRects;
}
-
+
if (iter->state == MIDDLE)
{
row->y2 = first->y1;
@@ -196,25 +196,25 @@ region_iter_get_row (region_iter_t *iter, row_t *row)
iter->u.middle.last = last;
}
break;
-
+
case MIDDLE:
assert (iter->u.middle.last - iter->u.middle.first > 0);
-
+
for (box = iter->u.middle.first; box != iter->u.middle.last; ++box)
{
if (box->y1 != iter->u.middle.first->y1)
break;
}
-
+
row->y1 = iter->u.middle.first->y1;
row->y2 = iter->u.middle.first->y2;
row->first = iter->u.middle.first;
row->last = box;
-
+
if (box != iter->u.middle.last)
{
if (box->y1 != row->y2)
- iter->state = EMPTY_ROW;
+ iter->state = EMPTY;
iter->u.middle.first = box;
}
@@ -225,7 +225,7 @@ region_iter_get_row (region_iter_t *iter, row_t *row)
}
break;
- case EMPTY_ROW:
+ case EMPTY:
row->y1 = (iter->u.middle.first - 1)->y2;
row->y2 = iter->u.middle.first->y1;
row->first = NULL;
@@ -233,7 +233,7 @@ region_iter_get_row (region_iter_t *iter, row_t *row)
iter->state = MIDDLE;
break;
-
+
case FINAL:
row->first = NULL;
row->last = NULL;
@@ -241,7 +241,7 @@ region_iter_get_row (region_iter_t *iter, row_t *row)
row->y2 = INT_MAX;
iter->state = DONE;
break;
-
+
case DONE:
return FALSE;
}
@@ -302,6 +302,102 @@ overlapped_iter_get_rows (overlapped_iter_t *iter, row_t *row1, row_t *row2)
return TRUE;
}
+/* Row iter */
+typedef struct row_iter_t row_iter_t;
+
+struct row_iter_t
+{
+ state_t state;
+
+ union
+ {
+ struct
+ {
+ const row_t *row;
+ } first;
+
+ struct
+ {
+ const pixman_box32_t *first;
+ const pixman_box32_t *last;
+ } middle;
+
+ struct
+ {
+ int x1;
+ } final;
+ } u;
+};
+
+static void
+row_iter_init (row_iter_t *iter, const row_t *row)
+{
+ iter->state = FIRST;
+
+ iter->u.first.row = row;
+}
+
+static pixman_bool_t
+row_iter_get_box (row_iter_t *iter, int *x1, int *x2, pixman_bool_t *on)
+{
+ switch (iter->state)
+ {
+ case FIRST:
+ *on = FALSE;
+ *x1 = INT_MIN;
+
+ if (iter->u.first.row->first)
+ {
+ *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;
+ }
+ else
+ {
+ *x2 = INT_MAX;
+ iter->state = DONE;
+ }
+ break;
+
+ case MIDDLE:
+ *on = TRUE;
+ *x1 = iter->u.middle.first->x1;
+ *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;
+ }
+ else
+ {
+ iter->state = EMPTY;
+ }
+ break;
+
+ case EMPTY:
+ *on = FALSE;
+ *x1 = (iter->u.middle.first - 1)->x2;
+ *x2 = iter->u.middle.first->x1;
+ iter->state = MIDDLE;
+ break;
+
+ case FINAL:
+ *on = FALSE;
+ *x1 = iter->u.final.x1;
+ *x2 = INT_MAX;
+ break;
+
+ case DONE:
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
/* Segment iter */
typedef enum
{
@@ -874,4 +970,3 @@ main ()
}
#endif
-