aboutsummaryrefslogtreecommitdiff
path: root/pixman/pixman/pixman-region.c
diff options
context:
space:
mode:
Diffstat (limited to 'pixman/pixman/pixman-region.c')
-rw-r--r--pixman/pixman/pixman-region.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/pixman/pixman/pixman-region.c b/pixman/pixman/pixman-region.c
index 142493b77..47beb5238 100644
--- a/pixman/pixman/pixman-region.c
+++ b/pixman/pixman/pixman-region.c
@@ -102,7 +102,11 @@
static const box_type_t PREFIX (_empty_box_) = { 0, 0, 0, 0 };
static const region_data_type_t PREFIX (_empty_data_) = { 0, 0 };
+#if defined (__llvm__) && !defined (__clang__)
+static const volatile region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
+#else
static const region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
+#endif
static box_type_t *pixman_region_empty_box =
(box_type_t *)&PREFIX (_empty_box_);
@@ -2086,6 +2090,40 @@ PIXMAN_EXPORT PREFIX (_inverse) (region_type_t *new_reg, /* Destination region
return TRUE;
}
+/* In time O(log n), locate the first box whose y2 is greater than y.
+ * Return @end if no such box exists.
+ */
+static box_type_t *
+find_box_for_y (box_type_t *begin, box_type_t *end, int y)
+{
+ box_type_t *mid;
+
+ if (end == begin)
+ return end;
+
+ if (end - begin == 1)
+ {
+ if (begin->y2 > y)
+ return begin;
+ else
+ return end;
+ }
+
+ mid = begin + (end - begin) / 2;
+ if (mid->y2 > y)
+ {
+ /* If no box is found in [begin, mid], the function
+ * will return @mid, which is then known to be the
+ * correct answer.
+ */
+ return find_box_for_y (begin, mid, y);
+ }
+ else
+ {
+ return find_box_for_y (mid, end, y);
+ }
+}
+
/*
* rect_in(region, rect)
* This routine takes a pointer to a region and a pointer to a box
@@ -2102,7 +2140,6 @@ PIXMAN_EXPORT PREFIX (_inverse) (region_type_t *new_reg, /* Destination region
* partially in the region) or is outside the region (we reached a band
* that doesn't overlap the box at all and part_in is false)
*/
-
pixman_region_overlap_t
PIXMAN_EXPORT PREFIX (_contains_rectangle) (region_type_t * region,
box_type_t * prect)
@@ -2139,12 +2176,15 @@ PIXMAN_EXPORT PREFIX (_contains_rectangle) (region_type_t * region,
/* can stop when both part_out and part_in are TRUE, or we reach prect->y2 */
for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
- pbox != pbox_end;
- pbox++)
+ pbox != pbox_end;
+ pbox++)
{
-
- if (pbox->y2 <= y)
- continue; /* getting up to speed or skipping remainder of band */
+ /* getting up to speed or skipping remainder of band */
+ if (pbox->y2 <= y)
+ {
+ if ((pbox = find_box_for_y (pbox, pbox_end, y)) == pbox_end)
+ break;
+ }
if (pbox->y1 > y)
{
@@ -2342,13 +2382,13 @@ PREFIX (_contains_point) (region_type_t * region,
return(TRUE);
}
- for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
- pbox != pbox_end;
- pbox++)
- {
- if (y >= pbox->y2)
- continue; /* not there yet */
+ pbox = PIXREGION_BOXPTR (region);
+ pbox_end = pbox + numRects;
+ pbox = find_box_for_y (pbox, pbox_end, y);
+
+ for (;pbox != pbox_end; pbox++)
+ {
if ((y < pbox->y1) || (x < pbox->x1))
break; /* missed it */