summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-10-08 13:34:10 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-10-08 13:34:10 -0400
commite9c9486d897947aaf672fbb5a9a40f54e87b16a3 (patch)
tree62989433269b400c2580976b09bd68e000d1ca3e
parentf44d70a49d2784a6170ca721411fbf993611fd49 (diff)
Various:
- region_iter_get_row_for_y() commented out - region_builder_add_row() untested - todo.
-rw-r--r--region-iter.c133
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);
+ }
}
}
}