[cairo-commit] 4 commits - src/cairo-analysis-surface.c src/cairo.c src/cairo-clip.c src/cairo-gstate.c src/cairoint.h src/cairo-path-bounds.c src/cairo-path-in-fill.c src/cairo-pdf-surface.c src/cairo-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Nov 25 02:26:32 PST 2008
src/cairo-analysis-surface.c | 16 ++--------
src/cairo-clip.c | 27 ++----------------
src/cairo-gstate.c | 25 ++++++-----------
src/cairo-path-bounds.c | 63 +++++++++++++++++++++++++++++++++++++++----
src/cairo-path-in-fill.c | 23 ++++++++-------
src/cairo-pdf-surface.c | 1
src/cairo-surface.c | 8 +++--
src/cairo.c | 23 +++++----------
src/cairoint.h | 12 +++++---
9 files changed, 110 insertions(+), 88 deletions(-)
New commits:
commit ca80b8c652dde4449216da9d11691202eef97bbd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 25 10:25:24 2008 +0000
[pdf] Add a default case to silence the compiler.
The foolish compiler was emitting a warning about a potential
uninitialized variable even though the switch was fully populated.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index b98f7d7..9790250 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1387,6 +1387,7 @@ _cairo_pdf_surface_start_page (void *abstract_surface)
case CAIRO_PDF_VERSION_1_4:
version = "1.4";
break;
+ default:
case CAIRO_PDF_VERSION_1_5:
version = "1.5";
break;
commit b8991a1c69ae5d8fb630296a3c689aa8d1546671
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 25 10:11:59 2008 +0000
[in-fill] Add the implicit close-path during move-to.
When interpreting a fixed-path for a fill operation, any move-to
implicitly closes the current path.
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 3acbc10..9f7892a 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1060,7 +1060,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
return status;
}
-cairo_status_t
+void
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
cairo_path_fixed_t *path,
double x,
@@ -1069,11 +1069,11 @@ _cairo_gstate_in_fill (cairo_gstate_t *gstate,
{
_cairo_gstate_user_to_backend (gstate, &x, &y);
- return _cairo_path_fixed_in_fill (path,
- gstate->fill_rule,
- gstate->tolerance,
- x, y,
- inside_ret);
+ _cairo_path_fixed_in_fill (path,
+ gstate->fill_rule,
+ gstate->tolerance,
+ x, y,
+ inside_ret);
}
cairo_status_t
diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c
index 2b9b057..0362bfb 100644
--- a/src/cairo-path-in-fill.c
+++ b/src/cairo-path-in-fill.c
@@ -136,9 +136,14 @@ _cairo_in_fill_move_to (void *closure, cairo_point_t *point)
{
cairo_in_fill_t *in_fill = closure;
- if (! in_fill->has_current_point)
- in_fill->first_point = *point;
+ /* implicit close path */
+ if (in_fill->has_current_point) {
+ _cairo_in_fill_add_edge (in_fill,
+ &in_fill->current_point,
+ &in_fill->first_point);
+ }
+ in_fill->first_point = *point;
in_fill->current_point = *point;
in_fill->has_current_point = TRUE;
@@ -153,7 +158,10 @@ _cairo_in_fill_line_to (void *closure, cairo_point_t *point)
if (in_fill->has_current_point)
_cairo_in_fill_add_edge (in_fill, &in_fill->current_point, point);
- return _cairo_in_fill_move_to (in_fill, point);
+ in_fill->current_point = *point;
+ in_fill->has_current_point = TRUE;
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@@ -215,7 +223,7 @@ _cairo_in_fill_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-cairo_status_t
+void
_cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -235,8 +243,7 @@ _cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
_cairo_in_fill_curve_to,
_cairo_in_fill_close_path,
&in_fill);
- if (status)
- goto BAIL;
+ assert (status == CAIRO_STATUS_SUCCESS);
switch (fill_rule) {
case CAIRO_FILL_RULE_EVEN_ODD:
@@ -251,9 +258,5 @@ _cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
break;
}
- status = CAIRO_STATUS_SUCCESS;
-
-BAIL:
_cairo_in_fill_fini (&in_fill);
- return status;
}
diff --git a/src/cairo.c b/src/cairo.c
index d1892fd..3dc3001 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -2269,17 +2269,14 @@ cairo_in_stroke (cairo_t *cr, double x, double y)
cairo_bool_t
cairo_in_fill (cairo_t *cr, double x, double y)
{
- cairo_status_t status;
- cairo_bool_t inside = FALSE;
+ cairo_bool_t inside;
if (cr->status)
return 0;
- status = _cairo_gstate_in_fill (cr->gstate,
- cr->path,
- x, y, &inside);
- if (status)
- _cairo_set_error (cr, status);
+ _cairo_gstate_in_fill (cr->gstate,
+ cr->path,
+ x, y, &inside);
return inside;
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 32cc759..34ea874 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1183,7 +1183,7 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate,
double y,
cairo_bool_t *inside_ret);
-cairo_private cairo_status_t
+cairo_private void
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
cairo_path_fixed_t *path,
double x,
@@ -1537,7 +1537,7 @@ _cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
cairo_box_t *box);
/* cairo-path-in-fill.c */
-cairo_private cairo_status_t
+cairo_private void
_cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
commit 59de6fb89e80ee6aeeb2984b545ceb9bb9f0f7bb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 25 10:04:50 2008 +0000
[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.
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index d5b63e8..431f98e 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -283,9 +283,6 @@ _cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
cairo_antialias_t antialias)
{
cairo_analysis_surface_t *surface = abstract_surface;
- double x1, y1, x2, y2;
- cairo_rectangle_int_t extent;
- cairo_bool_t is_empty;
if (path == NULL) {
surface->current_clip.x = 0;
@@ -293,17 +290,10 @@ _cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
surface->current_clip.width = surface->width;
surface->current_clip.height = surface->height;
} else {
- cairo_status_t status;
-
- status = _cairo_path_fixed_bounds (path, &x1, &y1, &x2, &y2, tolerance);
- if (status)
- return status;
-
- extent.x = floor (x1);
- extent.y = floor (y1);
- extent.width = ceil (x2) - extent.x;
- extent.height = ceil (y2) - extent.y;
+ cairo_rectangle_int_t extent;
+ cairo_bool_t is_empty;
+ _cairo_path_fixed_approximate_extents (path, &extent);
is_empty = _cairo_rectangle_intersect (&surface->current_clip, &extent);
}
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 83ba28c..ce2a240 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -143,30 +143,11 @@ _cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
cairo_rectangle_int_t *rectangle)
{
while (clip_path) {
- cairo_status_t status;
- cairo_traps_t traps;
- cairo_box_t extents;
- cairo_rectangle_int_t extents_rect;
-
- _cairo_box_from_rectangle (&extents, rectangle);
-
- _cairo_traps_init (&traps);
- _cairo_traps_limit (&traps, &extents);
-
- status = _cairo_path_fixed_fill_to_traps (&clip_path->path,
- clip_path->fill_rule,
- clip_path->tolerance,
- &traps);
- if (status) {
- _cairo_traps_fini (&traps);
- return status;
- }
+ cairo_rectangle_int_t extents;
- _cairo_traps_extents (&traps, &extents);
- _cairo_traps_fini (&traps);
+ _cairo_path_fixed_approximate_extents (&clip_path->path, &extents);
- _cairo_box_round_to_rectangle (&extents, &extents_rect);
- if (! _cairo_rectangle_intersect (rectangle, &extents_rect))
+ if (! _cairo_rectangle_intersect (rectangle, &extents))
return CAIRO_STATUS_SUCCESS;
clip_path = clip_path->prev;
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 33880d8..3acbc10 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -783,20 +783,17 @@ _cairo_gstate_stroke_to_path (cairo_gstate_t *gstate)
}
*/
-cairo_status_t
+void
_cairo_gstate_path_extents (cairo_gstate_t *gstate,
cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2)
{
- cairo_status_t status;
double px1, py1, px2, py2;
- status = _cairo_path_fixed_bounds (path,
- &px1, &py1, &px2, &py2,
- gstate->tolerance);
- if (status)
- return status;
+ _cairo_path_fixed_bounds (path,
+ &px1, &py1, &px2, &py2,
+ gstate->tolerance);
_cairo_gstate_backend_to_user_rectangle (gstate,
&px1, &py1, &px2, &py2,
@@ -809,8 +806,6 @@ _cairo_gstate_path_extents (cairo_gstate_t *gstate,
*x2 = px2;
if (y2)
*y2 = py2;
-
- return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c
index 70867e3..54df5bf 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;
}
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index eaff47a..4c10f95 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2132,11 +2132,13 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
assert (surface->backend->set_clip_region != NULL);
- surface->current_clip_serial = serial;
-
status = surface->backend->set_clip_region (surface, region);
+ if (unlikely (status))
+ return _cairo_surface_set_error (surface, status);
- return _cairo_surface_set_error (surface, status);
+ surface->current_clip_serial = serial;
+
+ return CAIRO_STATUS_SUCCESS;
}
cairo_int_status_t
diff --git a/src/cairo.c b/src/cairo.c
index c80589d..d1892fd 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -1907,8 +1907,6 @@ void
cairo_path_extents (cairo_t *cr,
double *x1, double *y1, double *x2, double *y2)
{
- cairo_status_t status;
-
if (cr->status) {
if (x1)
*x1 = 0.0;
@@ -1922,11 +1920,9 @@ cairo_path_extents (cairo_t *cr,
return;
}
- status = _cairo_gstate_path_extents (cr->gstate,
- cr->path,
- x1, y1, x2, y2);
- if (status)
- _cairo_set_error (cr, status);
+ _cairo_gstate_path_extents (cr->gstate,
+ cr->path,
+ x1, y1, x2, y2);
}
/**
diff --git a/src/cairoint.h b/src/cairoint.h
index d219061..32cc759 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1139,7 +1139,7 @@ _cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate,
double *x2, double *y2,
cairo_bool_t *is_tight);
-cairo_private cairo_status_t
+cairo_private void
_cairo_gstate_path_extents (cairo_gstate_t *gstate,
cairo_path_fixed_t *path,
double *x1, double *y1,
@@ -1511,7 +1511,11 @@ _cairo_path_fixed_append (cairo_path_fixed_t *path,
const cairo_path_fixed_t *other,
cairo_direction_t dir);
-cairo_private cairo_status_t
+cairo_private void
+_cairo_path_fixed_approximate_extents (cairo_path_fixed_t *path,
+ cairo_rectangle_int_t *extents);
+
+cairo_private void
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2,
commit b6bf047494fc308fff00d818b2920d8ba4aa7aed
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Nov 21 15:27:31 2008 +0000
[clip] Check for error surface
The update to use a NULL backend with an error surface broke creating a
context from an error surface.
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 726896e..83ba28c 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -49,7 +49,7 @@ _cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
void
_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
{
- if (target)
+ if (target && target->backend)
clip->mode = _cairo_surface_get_clip_mode (target);
else
clip->mode = CAIRO_CLIP_MODE_MASK;
diff --git a/src/cairo.c b/src/cairo.c
index f53d0b0..c80589d 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -166,8 +166,8 @@ cairo_create (cairo_surface_t *target)
cr->gstate = cr->gstate_tail;
cr->gstate_freelist = NULL;
- status = _cairo_gstate_init (cr->gstate, target);
+ status = _cairo_gstate_init (cr->gstate, target);
if (status)
_cairo_set_error (cr, status);
More information about the cairo-commit
mailing list