diff options
Diffstat (limited to 'src/cairo-path-fill.c')
-rw-r--r-- | src/cairo-path-fill.c | 101 |
1 files changed, 77 insertions, 24 deletions
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index 8f34af85..74a019d6 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -31,6 +31,8 @@ typedef struct cairo_filler { cairo_gstate_t *gstate; cairo_traps_t *traps; + cairo_point_t current_point; + cairo_polygon_t polygon; } cairo_filler_t; @@ -41,15 +43,19 @@ static void _cairo_filler_fini (cairo_filler_t *filler); static cairo_status_t -_cairo_filler_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2); +_cairo_filler_move_to (void *closure, cairo_point_t *point); + +static cairo_status_t +_cairo_filler_line_to (void *closure, cairo_point_t *point); static cairo_status_t -_cairo_filler_add_spline (void *closure, - cairo_point_t *a, cairo_point_t *b, - cairo_point_t *c, cairo_point_t *d); +_cairo_filler_curve_to (void *closure, + cairo_point_t *b, + cairo_point_t *c, + cairo_point_t *d); static cairo_status_t -_cairo_filler_done_sub_path (void *closure, cairo_sub_path_done_t done); +_cairo_filler_close_path (void *closure); static cairo_status_t _cairo_filler_done_path (void *closure); @@ -60,6 +66,9 @@ _cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_ filler->gstate = gstate; filler->traps = traps; + filler->current_point.x = 0; + filler->current_point.y = 0; + _cairo_polygon_init (&filler->polygon); } @@ -70,18 +79,46 @@ _cairo_filler_fini (cairo_filler_t *filler) } static cairo_status_t -_cairo_filler_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2) +_cairo_filler_move_to (void *closure, cairo_point_t *point) { + cairo_status_t status; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; - return _cairo_polygon_add_edge (polygon, p1, p2); + status = _cairo_polygon_close (polygon); + if (status) + return status; + + status = _cairo_polygon_move_to (polygon, point); + if (status) + return status; + + filler->current_point = *point; + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_filler_line_to (void *closure, cairo_point_t *point) +{ + cairo_status_t status; + cairo_filler_t *filler = closure; + cairo_polygon_t *polygon = &filler->polygon; + + status = _cairo_polygon_line_to (polygon, point); + if (status) + return status; + + filler->current_point = *point; + + return CAIRO_STATUS_SUCCESS; } static cairo_status_t -_cairo_filler_add_spline (void *closure, - cairo_point_t *a, cairo_point_t *b, - cairo_point_t *c, cairo_point_t *d) +_cairo_filler_curve_to (void *closure, + cairo_point_t *b, + cairo_point_t *c, + cairo_point_t *d) { int i; cairo_status_t status = CAIRO_STATUS_SUCCESS; @@ -90,7 +127,8 @@ _cairo_filler_add_spline (void *closure, cairo_gstate_t *gstate = filler->gstate; cairo_spline_t spline; - status = _cairo_spline_init (&spline, a, b, c, d); + status = _cairo_spline_init (&spline, &filler->current_point, b, c, d); + if (status == CAIRO_INT_STATUS_DEGENERATE) return CAIRO_STATUS_SUCCESS; @@ -98,47 +136,62 @@ _cairo_filler_add_spline (void *closure, if (status) goto CLEANUP_SPLINE; - for (i = 0; i < spline.num_points - 1; i++) { - status = _cairo_polygon_add_edge (polygon, &spline.points[i], &spline.points[i+1]); + for (i = 1; i < spline.num_points; i++) { + status = _cairo_polygon_line_to (polygon, &spline.points[i]); if (status) - goto CLEANUP_SPLINE; + break; } CLEANUP_SPLINE: _cairo_spline_fini (&spline); + filler->current_point = *d; + return status; } static cairo_status_t -_cairo_filler_done_sub_path (void *closure, cairo_sub_path_done_t done) +_cairo_filler_close_path (void *closure) { - cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_status_t status; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; - _cairo_polygon_close (polygon); + status = _cairo_polygon_close (polygon); + if (status) + return status; - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_status_t _cairo_filler_done_path (void *closure) { + cairo_status_t status; cairo_filler_t *filler = closure; + cairo_polygon_t *polygon = &filler->polygon; + + status = _cairo_polygon_close (polygon); + if (status) + return status; - return _cairo_traps_tessellate_polygon (filler->traps, - &filler->polygon, - filler->gstate->fill_rule); + status = _cairo_traps_tessellate_polygon (filler->traps, + &filler->polygon, + filler->gstate->fill_rule); + if (status) + return status; + + return CAIRO_STATUS_SUCCESS; } cairo_status_t _cairo_path_fill_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_traps_t *traps) { static const cairo_path_callbacks_t filler_callbacks = { - _cairo_filler_add_edge, - _cairo_filler_add_spline, - _cairo_filler_done_sub_path, + _cairo_filler_move_to, + _cairo_filler_line_to, + _cairo_filler_curve_to, + _cairo_filler_close_path, _cairo_filler_done_path }; |