diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-08-15 09:44:03 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-08-15 10:31:47 +0100 |
commit | 545f30856aac98199a49cf66c72dbcb66c1f3a4f (patch) | |
tree | 995aa743e7390b83718280b2dd770c9b794f6931 /src/cairo-polygon.c | |
parent | bbe704406ca97cd51ed1fcc76da7648abde36331 (diff) | |
download | cairo-545f30856aac98199a49cf66c72dbcb66c1f3a4f.tar.gz |
stroke: Convert the outlines into contour and then into a polygon
In step 1 of speeding up stroking, we introduce contours as a means for
tracking the connected edges around the stroke. By keeping track of
these chains, we can analyse the edges as we proceed and eliminate
redundant vertices speeding up rasterisation.
Coincidentally fixes line-width-tolerance (looks like a combination of
using spline tangent vectors and tolerance).
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-polygon.c')
-rw-r--r-- | src/cairo-polygon.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index 74ec9fa64..6436712b4 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -38,12 +38,14 @@ #include "cairoint.h" #include "cairo-boxes-private.h" +#include "cairo-contour-private.h" #include "cairo-error-private.h" static void _cairo_polygon_add_edge (cairo_polygon_t *polygon, const cairo_point_t *p1, - const cairo_point_t *p2); + const cairo_point_t *p2, + int dir); void _cairo_polygon_init (cairo_polygon_t *polygon, @@ -131,12 +133,12 @@ _cairo_polygon_init_boxes (cairo_polygon_t *polygon, p1 = chunk->base[i].p1; p2.x = p1.x; p2.y = chunk->base[i].p2.y; - _cairo_polygon_add_edge (polygon, &p1, &p2); + _cairo_polygon_add_edge (polygon, &p1, &p2, 1); p1 = chunk->base[i].p2; p2.x = p1.x; p2.y = chunk->base[i].p1.y; - _cairo_polygon_add_edge (polygon, &p1, &p2); + _cairo_polygon_add_edge (polygon, &p1, &p2, 1); } } @@ -178,12 +180,12 @@ _cairo_polygon_init_box_array (cairo_polygon_t *polygon, p1 = boxes[i].p1; p2.x = p1.x; p2.y = boxes[i].p2.y; - _cairo_polygon_add_edge (polygon, &p1, &p2); + _cairo_polygon_add_edge (polygon, &p1, &p2, 1); p1 = boxes[i].p2; p2.x = p1.x; p2.y = boxes[i].p1.y; - _cairo_polygon_add_edge (polygon, &p1, &p2); + _cairo_polygon_add_edge (polygon, &p1, &p2, 1); } return polygon->status; @@ -406,20 +408,17 @@ _add_clipped_edge (cairo_polygon_t *polygon, static void _cairo_polygon_add_edge (cairo_polygon_t *polygon, const cairo_point_t *p1, - const cairo_point_t *p2) + const cairo_point_t *p2, + int dir) { - int dir; - /* drop horizontal edges */ if (p1->y == p2->y) return; - if (p1->y < p2->y) { - dir = 1; - } else { + if (p1->y > p2->y) { const cairo_point_t *t; t = p1, p1 = p2, p2 = t; - dir = -1; + dir = -dir; } if (polygon->num_limits) { @@ -439,7 +438,7 @@ _cairo_polygon_add_external_edge (void *polygon, const cairo_point_t *p1, const cairo_point_t *p2) { - _cairo_polygon_add_edge (polygon, p1, p2); + _cairo_polygon_add_edge (polygon, p1, p2, 1); return _cairo_polygon_status (polygon); } @@ -469,3 +468,26 @@ _cairo_polygon_add_line (cairo_polygon_t *polygon, return polygon->status; } + +cairo_status_t +_cairo_polygon_add_contour (cairo_polygon_t *polygon, + const cairo_contour_t *contour) +{ + const struct _cairo_contour_chain *chain; + const cairo_point_t *prev = NULL; + int i; + + if (contour->chain.num_points <= 1) + return CAIRO_INT_STATUS_SUCCESS; + + prev = &contour->chain.points[0]; + for (chain = &contour->chain; chain; chain = chain->next) { + for (i = 0; i < chain->num_points; i++) { + _cairo_polygon_add_edge (polygon, prev, &chain->points[i], + contour->direction); + prev = &chain->points[i]; + } + } + + return polygon->status; +} |