summaryrefslogtreecommitdiff
path: root/src/cairo-path-bounds.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-11-25 10:04:50 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2008-11-25 10:16:32 +0000
commit59de6fb89e80ee6aeeb2984b545ceb9bb9f0f7bb (patch)
tree5b5df9e1429e48c560bec45163b4bb95d5aaf042 /src/cairo-path-bounds.c
parentb6bf047494fc308fff00d818b2920d8ba4aa7aed (diff)
downloadcairo-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.c63
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;
}