diff options
author | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-11-10 13:18:09 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-11-10 23:26:52 -0500 |
commit | 20da3be10ac3bcf98aa195a81079a3f704f751f9 (patch) | |
tree | 38039bb864b1efd8d6826bfe711bcf58a6781337 | |
parent | 2ebccee793653afc2ff127e8b136d86bae83f467 (diff) |
Simplified segment iter
-rw-r--r-- | demo.c | 1 | ||||
-rw-r--r-- | region-iter.c | 218 |
2 files changed, 82 insertions, 137 deletions
@@ -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; |