diff options
author | Andrea Canciani <ranma42@gmail.com> | 2010-12-09 22:00:10 +0100 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2010-12-10 11:04:47 +0100 |
commit | 75f34b595aead729b6f6a7017c8790d68dfa0326 (patch) | |
tree | 35b9443f58bc7d50199ea18cb367b69a5047cdda /src/cairo-path-fill.c | |
parent | df453b7aca5ad7c4b796f150c8a90e78c1b96e04 (diff) | |
download | cairo-75f34b595aead729b6f6a7017c8790d68dfa0326.tar.gz |
fill: Simplify path to polygon conversion
Using _cairo_path_fixed_interpret_flat() greatly simplifies the path
to polygon conversion (because it already converts curve_to's to
line_to's).
This commit also removes the optimization which merges two consecutive
lines if they have the same slope, because it's unlikely (since it
should already happen during path construction), it doesn't provide
better performance (at least not measurable with the currently
available cairo-traces) and bloats the code.
Diffstat (limited to 'src/cairo-path-fill.c')
-rw-r--r-- | src/cairo-path-fill.c | 91 |
1 files changed, 41 insertions, 50 deletions
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index 845cdfcff..3a8e58a6d 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -1,3 +1,4 @@ +/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ /* cairo - a vector graphics library with display and print output * * Copyright © 2002 University of Southern California @@ -41,67 +42,55 @@ #include "cairo-region-private.h" typedef struct cairo_filler { - double tolerance; cairo_polygon_t *polygon; + + cairo_point_t current_point; + cairo_point_t last_move_to; } cairo_filler_t; -static void -_cairo_filler_init (cairo_filler_t *filler, - double tolerance, - cairo_polygon_t *polygon) -{ - filler->tolerance = tolerance; - filler->polygon = polygon; -} - -static void -_cairo_filler_fini (cairo_filler_t *filler) -{ -} static cairo_status_t -_cairo_filler_move_to (void *closure, +_cairo_filler_line_to (void *closure, const cairo_point_t *point) { cairo_filler_t *filler = closure; - cairo_polygon_t *polygon = filler->polygon; + cairo_status_t status; + + status = _cairo_polygon_add_external_edge (filler->polygon, + &filler->current_point, + point); + + filler->current_point = *point; - return _cairo_polygon_close (polygon) || - _cairo_polygon_move_to (polygon, point); + return status; } static cairo_status_t -_cairo_filler_line_to (void *closure, - const cairo_point_t *point) +_cairo_filler_close (void *closure) { cairo_filler_t *filler = closure; - return _cairo_polygon_line_to (filler->polygon, point); + + /* close the subpath */ + return _cairo_filler_line_to (closure, &filler->last_move_to); } static cairo_status_t -_cairo_filler_curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) +_cairo_filler_move_to (void *closure, + const cairo_point_t *point) { cairo_filler_t *filler = closure; - cairo_spline_t spline; + cairo_status_t status; - if (! _cairo_spline_init (&spline, - _cairo_filler_line_to, filler, - &filler->polygon->current_point, b, c, d)) - { - return _cairo_filler_line_to (closure, d); - } + /* close current subpath */ + status = _cairo_filler_close (closure); + if (unlikely (status)) + return status; - return _cairo_spline_decompose (&spline, filler->tolerance); -} + /* make sure that the closure represents a degenerate path */ + filler->current_point = *point; + filler->last_move_to = *point; -static cairo_status_t -_cairo_filler_close_path (void *closure) -{ - cairo_filler_t *filler = closure; - return _cairo_polygon_close (filler->polygon); + return CAIRO_STATUS_SUCCESS; } cairo_status_t @@ -112,21 +101,23 @@ _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path, cairo_filler_t filler; cairo_status_t status; - _cairo_filler_init (&filler, tolerance, polygon); + filler.polygon = polygon; - status = _cairo_path_fixed_interpret (path, - _cairo_filler_move_to, - _cairo_filler_line_to, - _cairo_filler_curve_to, - _cairo_filler_close_path, - &filler); + /* make sure that the closure represents a degenerate path */ + filler.current_point.x = 0; + filler.current_point.y = 0; + filler.last_move_to = filler.current_point; + + status = _cairo_path_fixed_interpret_flat (path, + _cairo_filler_move_to, + _cairo_filler_line_to, + _cairo_filler_close, + &filler, + tolerance); if (unlikely (status)) return status; - status = _cairo_polygon_close (polygon); - _cairo_filler_fini (&filler); - - return status; + return _cairo_filler_close (&filler); } cairo_status_t |