diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-10-08 13:34:10 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-10-08 13:34:10 -0400 |
commit | e9c9486d897947aaf672fbb5a9a40f54e87b16a3 (patch) | |
tree | 62989433269b400c2580976b09bd68e000d1ca3e | |
parent | f44d70a49d2784a6170ca721411fbf993611fd49 (diff) |
Various:
- region_iter_get_row_for_y() commented out
- region_builder_add_row() untested
- todo.
-rw-r--r-- | region-iter.c | 133 |
1 files changed, 127 insertions, 6 deletions
diff --git a/region-iter.c b/region-iter.c index cc49eb2..74e135d 100644 --- a/region-iter.c +++ b/region-iter.c @@ -10,6 +10,19 @@ * Useful for speeding up intersection, and * would also be useful for "contains" functions. * + * Ie., an overlapped iter that will can return one of the following: + * - two blank rows + * - one multi row, one blank row + * - one multi row, one one-box row + * - one single row, one single row + * + * We will need a subroutine row_iter_skip_to_y() that will skip + * to the next row with a y2 > y. + * + * - an iterator that will move backwards through a region and then + * one that will move backwards through a row would be useful for + * scrolling. + * */ #include <stdlib.h> #include <stdio.h> @@ -224,6 +237,59 @@ region_builder_add_box (region_builder_t *builder, } static pixman_bool_t +region_builder_add_row (region_builder_t *builder, const row_t *row) +{ + pixman_box32_t *last_box; + const pixman_box32_t *first; + pixman_region32_data_t *data; + int n_boxes; + + if (builder->data == BROKEN_DATA) + return FALSE; + + n_boxes = row->last - row->first; + + if (!(data = region_data_append (builder->data, n_boxes))) + { + free (builder->data); + builder->data = BROKEN_DATA; + return FALSE; + } + + builder->data = data; + + if (data->numRects == 0) + last_box = NULL; + else + last_box = ((pixman_box32_t *)(data + 1)) + data->numRects - 1; + + first = row->first; + if (last_box) + { + if (row->y1 != last_box->y1) + region_builder_coalesce_rows (builder); + else if (row->first->x1 == last_box->x2) + { + last_box->x2 = row->first->x2; + first = row->first + 1; + n_boxes--; + } + } + + while (first != row->last) + { + pixman_box32_t *box = (pixman_box32_t *)(data + 1) + data->numRects++; + + box->x1 = first->x1; + box->x2 = first->x2; + box->y1 = row->y1; + box->y2 = row->y2; + + first++; + } +} + +static pixman_bool_t region_builder_finish (region_builder_t *builder, pixman_region32_t *region) { region_builder_coalesce_rows (builder); @@ -367,6 +433,41 @@ region_iter_get_row (region_iter_t *iter, row_t *row) return TRUE; } +/* Skips forward to the first row whose y2 > @y */ +#if 0 +static pixman_bool_t +region_iter_get_row_for_y (region_iter_t *iter, int y, row_t *row) +{ + pixman_box32_t *box; + + while (iter->state != MIDDLE) + { + if (!region_iter_get_row (iter, row)) + return FALSE; + + if (row->y2 > y) + return TRUE; + } + + box = find_box_for_y (iter->u.middle.first, iter->u.middle.last, y); + + if (box != iter->u.middle.last) + { + if (box->y1 > y) + iter->state = EMPTY; + + iter->u.middle.first = box; + } + else + { + iter->state = FINAL; + iter->u.final.y1 = row->y2; + } + + return region_iter_get_row (iter, row); +} +#endif + /* Overlapped iter */ typedef struct overlapped_iter_t overlapped_iter_t; @@ -605,8 +706,8 @@ region_op (ops_t op, pixman_region32_t *src2) { overlapped_iter_t iter; - row_t row1, row2; region_builder_t builder; + row_t row1, row2; region_builder_init (&builder); @@ -616,13 +717,33 @@ region_op (ops_t op, segment_iter_t seg_iter; segment_t segment; - segment_iter_init (&seg_iter, &row1, &row2); - while (segment_iter_get_segment (&seg_iter, &segment)) + if (!row1.first && !row2.first) { - if (op & (1 << segment.type)) + /* Both are blank - nothing to do */ + } + else if (!row1.first) + { + /* row1 is blank, row2 is not */ + if (op & (1 << ROW2)) + region_builder_add_row (&builder, &row2); + } + else if (!row2.first) + { + /* row2 is blank, row1 is not */ + if (op & (1 << ROW1)) + region_builder_add_row (&builder, &row1); + } + else + { + /* Both are non blank */ + segment_iter_init (&seg_iter, &row1, &row2); + while (segment_iter_get_segment (&seg_iter, &segment)) { - region_builder_add_box ( - &builder, segment.x1, row1.y1, segment.x2, row1.y2); + if (op & (1 << segment.type)) + { + region_builder_add_box ( + &builder, segment.x1, row1.y1, segment.x2, row1.y2); + } } } } |