diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-11-25 10:04:50 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-11-25 10:16:32 +0000 |
commit | 59de6fb89e80ee6aeeb2984b545ceb9bb9f0f7bb (patch) | |
tree | 5b5df9e1429e48c560bec45163b4bb95d5aaf042 /src/cairo-path-bounds.c | |
parent | b6bf047494fc308fff00d818b2920d8ba4aa7aed (diff) | |
download | cairo-59de6fb89e80ee6aeeb2984b545ceb9bb9f0f7bb.tar.gz |
[path] Compute approximate extents.
When computing the bounds of the clip path, we care more for a fast result
than absolute precision as the extents are only used as a guide to trim
the future operations. So computing the extents of the path suffices.
Diffstat (limited to 'src/cairo-path-bounds.c')
-rw-r--r-- | src/cairo-path-bounds.c | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c index 70867e31c..54df5bff4 100644 --- a/src/cairo-path-bounds.c +++ b/src/cairo-path-bounds.c @@ -132,13 +132,67 @@ _cairo_path_bounder_line_to (void *closure, cairo_point_t *point) } static cairo_status_t +_cairo_path_bounder_curve_to (void *closure, + cairo_point_t *b, + cairo_point_t *c, + cairo_point_t *d) +{ + cairo_path_bounder_t *bounder = closure; + + if (bounder->has_move_to_point) { + _cairo_path_bounder_add_point (bounder, + &bounder->move_to_point); + bounder->has_move_to_point = FALSE; + } + + _cairo_path_bounder_add_point (bounder, b); + _cairo_path_bounder_add_point (bounder, c); + _cairo_path_bounder_add_point (bounder, d); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t _cairo_path_bounder_close_path (void *closure) { return CAIRO_STATUS_SUCCESS; } -/* XXX: Perhaps this should compute a PixRegion rather than 4 doubles */ -cairo_status_t +/* This computes the extents of all the points in the path, not those of + * the damage area (i.e it does not consider winding and it only inspects + * the control points of the curves, not the flattened path). + */ +void +_cairo_path_fixed_approximate_extents (cairo_path_fixed_t *path, + cairo_rectangle_int_t *extents) +{ + cairo_path_bounder_t bounder; + cairo_status_t status; + + _cairo_path_bounder_init (&bounder); + + status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, + _cairo_path_bounder_move_to, + _cairo_path_bounder_line_to, + _cairo_path_bounder_curve_to, + _cairo_path_bounder_close_path, + &bounder); + assert (status == CAIRO_STATUS_SUCCESS); + + if (bounder.has_point) { + extents->x = bounder.min_x; + extents->y = bounder.min_y; + extents->width = bounder.max_x - extents->x; + extents->height = bounder.max_y - extents->y; + } else { + extents->x = extents->y = 0; + extents->width = extents->height = 0; + } + + _cairo_path_bounder_fini (&bounder); +} + +void _cairo_path_fixed_bounds (cairo_path_fixed_t *path, double *x1, double *y1, double *x2, double *y2, @@ -155,8 +209,9 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path, _cairo_path_bounder_close_path, &bounder, tolerance); + assert (status == CAIRO_STATUS_SUCCESS); - if (status == CAIRO_STATUS_SUCCESS && bounder.has_point) { + if (bounder.has_point) { *x1 = _cairo_fixed_to_double (bounder.min_x); *y1 = _cairo_fixed_to_double (bounder.min_y); *x2 = _cairo_fixed_to_double (bounder.max_x); @@ -169,6 +224,4 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path, } _cairo_path_bounder_fini (&bounder); - - return status; } |