diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-09-03 01:00:59 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-09-03 01:00:59 +0100 |
commit | f1d284f9976d38f636c6791f11479ae75d7bd199 (patch) | |
tree | c7184ba2bbdad3112ea6cce7ff5501b11e1f61e9 | |
parent | a6dfdeec82ec34d88276fd0bb0ddcc94405d89f3 (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.c | 29 | ||||
-rw-r--r-- | src/cairo-types-private.h | 1 |
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; |