[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