diff options
author | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-11-10 11:40:50 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-11-10 23:25:59 -0500 |
commit | 2ebccee793653afc2ff127e8b136d86bae83f467 (patch) | |
tree | 8c87734f58e10d19a1597ec4c13ab73b29ce58af | |
parent | 4277dca05c442e6798c4a5029c4c1587b3c35d5e (diff) |
row iter
-rw-r--r-- | region-iter.c | 121 |
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 - |