summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-09-03 01:00:59 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-09-03 01:00:59 +0100
commitf1d284f9976d38f636c6791f11479ae75d7bd199 (patch)
treec7184ba2bbdad3112ea6cce7ff5501b11e1f61e9
parenta6dfdeec82ec34d88276fd0bb0ddcc94405d89f3 (diff)
[polygon] Fix discard with non-banded disjoint clip boxes
The early discard checked if the line was below the last clip-box, or if above the first. However, the clip-boxes are only sorted on by the bottom (not the strict XY-banded sort of the regions) and so this was erroneously discarding lines.
-rw-r--r--src/cairo-polygon.c29
-rw-r--r--src/cairo-types-private.h1
2 files changed, 25 insertions, 5 deletions
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index f3e8e4d2..904b33d3 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -63,8 +63,27 @@ _cairo_polygon_limit (cairo_polygon_t *polygon,
const cairo_box_t *limits,
int num_limits)
{
+ int n;
+
polygon->limits = limits;
polygon->num_limits = num_limits;
+
+ polygon->limit.p1.x = polygon->limit.p1.y = INT32_MAX;
+ polygon->limit.p2.x = polygon->limit.p2.y = INT32_MIN;
+
+ for (n = 0; n < num_limits; n++) {
+ if (limits[n].p1.x < polygon->limit.p1.x)
+ polygon->limit.p1.x = limits[n].p1.x;
+
+ if (limits[n].p1.y < polygon->limit.p1.y)
+ polygon->limit.p1.y = limits[n].p1.y;
+
+ if (limits[n].p2.x > polygon->limit.p2.x)
+ polygon->limit.p2.x = limits[n].p2.x;
+
+ if (limits[n].p2.y > polygon->limit.p2.y)
+ polygon->limit.p2.y = limits[n].p2.y;
+ }
}
void
@@ -233,7 +252,7 @@ _add_clipped_edge (cairo_polygon_t *polygon,
limits->p2.x);
if (left_y == right_y) /* horizontal within bounds */
- return;
+ continue;
p1_y = top;
p2_y = bottom;
@@ -342,10 +361,10 @@ _cairo_polygon_add_edge (cairo_polygon_t *polygon,
}
if (polygon->num_limits) {
- if (p2->y <= polygon->limits[0].p1.y)
+ if (p2->y <= polygon->limit.p1.y)
return;
- if (p1->y >= polygon->limits[polygon->num_limits-1].p2.y)
+ if (p1->y >= polygon->limit.p2.y)
return;
_add_clipped_edge (polygon, p1, p2, p1->y, p2->y, dir);
@@ -376,10 +395,10 @@ _cairo_polygon_add_line (cairo_polygon_t *polygon,
return CAIRO_STATUS_SUCCESS;
if (polygon->num_limits) {
- if (line->p2.y <= polygon->limits[0].p1.y)
+ if (line->p2.y <= polygon->limit.p1.y)
return CAIRO_STATUS_SUCCESS;
- if (line->p1.y >= polygon->limits[polygon->num_limits-1].p2.y)
+ if (line->p1.y >= polygon->limit.p2.y)
return CAIRO_STATUS_SUCCESS;
_add_clipped_edge (polygon, &line->p1, &line->p2, top, bottom, dir);
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index 54bd2a74..82754cff 100644
--- a/src/cairo-types-private.h
+++ b/src/cairo-types-private.h
@@ -254,6 +254,7 @@ typedef struct _cairo_polygon {
cairo_bool_t has_current_edge;
cairo_box_t extents;
+ cairo_box_t limit;
const cairo_box_t *limits;
int num_limits;