[cairo-commit] cairo/src Makefile.am, 1.55, 1.56 cairo-clip-private.h, NONE, 1.1 cairo-clip.c, NONE, 1.1 cairo-gstate-private.h, 1.14, 1.15 cairo-gstate.c, 1.154, 1.155 cairo-meta-surface.c, 1.6, 1.7 cairo-path-fill.c, 1.18, 1.19 cairo-surface.c, 1.87, 1.88 cairo-traps.c, 1.28, 1.29 cairoint.h, 1.178, 1.179

Kristian Hogsberg commit at pdx.freedesktop.org
Thu Aug 4 22:46:02 PDT 2005


Committed by: krh

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv16914/src

Modified Files:
	Makefile.am cairo-gstate-private.h cairo-gstate.c 
	cairo-meta-surface.c cairo-path-fill.c cairo-surface.c 
	cairo-traps.c cairoint.h 
Added Files:
	cairo-clip-private.h cairo-clip.c 
Log Message:
2005-08-05  Kristian Høgsberg  <krh at redhat.com>

        Reviewed by: otaylor

        * src/Makefile.am:
        * src/cairo-clip-private.h:
        * src/cairo-clip.c: New files.  Move code for manipulating
        cairo_clip_t out into cairo_clip_* functions and put them in
        cairo-clip.c.

        * src/cairo-gstate-private.h:
        * src/cairo-gstate.c: Rewrite to use new cairo_clip_t functions
        for manipulating the clip state, change the
        clip_and_composite_trapezoids call tree to use cairo_clip_t
        instead of cairo_gstate_t.

        * src/cairo-meta-surface.c: Use new cairo_clip_t function to
        maintain clip state while replaying.

        * src/cairo-path-fill.c: (_cairo_filler_init),
        (_cairo_filler_curve_to), (_cairo_path_fixed_fill_to_traps): Pass
        fill rule and tolerance directly, to break gstate dependency.

        * src/cairo-surface.c: (_cairo_surface_set_clip): New function.
        Set the clip for a surface as specified by the cairo_clip_t.

        * src/cairo-traps.c: (_cairo_traps_translate): Move
        translate_traps() from cairo-gstate.c to here and rename it.



Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/src/Makefile.am,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- Makefile.am	1 Aug 2005 20:33:47 -0000	1.55
+++ Makefile.am	5 Aug 2005 05:45:59 -0000	1.56
@@ -92,6 +92,8 @@
 	cairo-font-options.c			\
 	cairo-gstate.c				\
 	cairo-gstate-private.h			\
+	cairo-clip.c				\
+	cairo-clip-private.h			\
 	cairo-hull.c				\
 	cairo-image-surface.c			\
 	cairo-matrix.c				\

--- NEW FILE: cairo-clip-private.h ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: cairo-clip.c ---
(This appears to be a binary file; contents omitted.)

Index: cairo-gstate-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate-private.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- cairo-gstate-private.h	1 Aug 2005 21:39:01 -0000	1.14
+++ cairo-gstate-private.h	5 Aug 2005 05:45:59 -0000	1.15
@@ -36,46 +36,7 @@
 #ifndef CAIRO_GSTATE_PRIVATE_H
 #define CAIRO_GSTATE_PRIVATE_H
 
-#include "cairo-path-fixed-private.h"
-
-struct _cairo_clip_path {
-    unsigned int	ref_count;
-    cairo_path_fixed_t	path;
-    cairo_fill_rule_t	fill_rule;
-    double		tolerance;
-    cairo_clip_path_t	*prev;
-};
-
-typedef struct _cairo_clip {
-    cairo_clip_mode_t mode;
-
-    /*
-     * Mask-based clipping for cases where the backend 
-     * clipping isn't sufficiently able.
-     *
-     * The rectangle here represents the
-     * portion of the destination surface that this
-     * clip surface maps to, it does not
-     * represent the extents of the clip region or
-     * clip paths
-     */
-    cairo_surface_t *surface;
-    cairo_rectangle_t surface_rect;
-    /*
-     * Surface clip serial number to store
-     * in the surface when this clip is set
-     */
-    unsigned int serial;
-    /*
-     * A clip region that can be placed in the surface
-     */
-    pixman_region16_t *region;
-    /*
-     * If the surface supports path clipping, we store the list of
-     * clipping paths that has been set here as a linked list.
-     */
-    cairo_clip_path_t *path;
-} cairo_clip_t;
+#include "cairo-clip-private.h"
 
 struct _cairo_gstate {
     cairo_operator_t operator;

Index: cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.154
retrieving revision 1.155
diff -u -d -r1.154 -r1.155
--- cairo-gstate.c	5 Aug 2005 01:44:29 -0000	1.154
+++ cairo-gstate.c	5 Aug 2005 05:45:59 -0000	1.155
@@ -39,6 +39,7 @@
 
 #include "cairoint.h"
 
+#include "cairo-clip-private.h"
 #include "cairo-gstate-private.h"
 
 static cairo_status_t
@@ -64,15 +65,6 @@
 static void
 _cairo_gstate_unset_font (cairo_gstate_t *gstate);
 
-static void
-_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src);
-
-static cairo_clip_path_t *
-_cairo_clip_path_reference (cairo_clip_path_t *clip_path);
-
-static void
-_cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
-
 cairo_gstate_t *
 _cairo_gstate_create (cairo_surface_t *target)
 {
@@ -121,11 +113,7 @@
 
     _cairo_font_options_init_default (&gstate->font_options);
     
-    gstate->clip.mode = _cairo_surface_get_clip_mode (target);
-    gstate->clip.region = NULL;
-    gstate->clip.surface = NULL;
-    gstate->clip.serial = 0;
-    gstate->clip.path = NULL;
+    _cairo_clip_init (&gstate->clip, target);
 
     _cairo_gstate_identity_matrix (gstate);
     cairo_matrix_init_identity (&gstate->source_ctm_inverse);
@@ -162,10 +150,7 @@
 	memcpy (gstate->dash, other->dash, other->num_dashes * sizeof (double));
     }
 
-    if (other->clip.region) {
-	gstate->clip.region = pixman_region_create ();
-	pixman_region_copy (gstate->clip.region, other->clip.region);
-    }
+    _cairo_clip_init_copy (&gstate->clip, &other->clip);
 
     if (gstate->font_face)
 	cairo_font_face_reference (gstate->font_face);
@@ -174,8 +159,6 @@
 	cairo_scaled_font_reference (gstate->scaled_font);
     
     cairo_surface_reference (gstate->target);
-    cairo_surface_reference (gstate->clip.surface);
-    _cairo_clip_path_reference (gstate->clip.path);
 
     cairo_pattern_reference (gstate->source);
     
@@ -209,18 +192,7 @@
 	gstate->target = NULL;
     }
 
-    if (gstate->clip.surface)
-	cairo_surface_destroy (gstate->clip.surface);
-    gstate->clip.surface = NULL;
-
-    if (gstate->clip.path)
-	_cairo_clip_path_destroy (gstate->clip.path);
-    gstate->clip.path = NULL;
-
-    if (gstate->clip.region)
-	pixman_region_destroy (gstate->clip.region);
-    gstate->clip.region = NULL;
-    gstate->clip.serial = 0;
+    _cairo_clip_fini (&gstate->clip);
 
     cairo_pattern_destroy (gstate->source);
 
@@ -340,61 +312,6 @@
 }
 */
 
-static cairo_status_t
-_cairo_gstate_set_clip (cairo_gstate_t *gstate)
-{
-    cairo_surface_t *surface = gstate->target;
-    
-    if (!surface)
-	return CAIRO_STATUS_NULL_POINTER;
-    if (gstate->clip.serial == _cairo_surface_get_current_clip_serial (surface))
-	return CAIRO_STATUS_SUCCESS;
-    
-    if (gstate->clip.path)
-	return _cairo_surface_set_clip_path (surface,
-					     gstate->clip.path,
-					     gstate->clip.serial);
-    
-    if (gstate->clip.region)
-	return _cairo_surface_set_clip_region (surface, 
-					       gstate->clip.region,
-					       gstate->clip.serial);
-    
-    return _cairo_surface_reset_clip (surface);
-}
-
-static cairo_status_t
-_cairo_gstate_get_clip_extents (cairo_gstate_t	    *gstate,
-				cairo_rectangle_t   *rectangle)
-{
-    cairo_status_t  status;
-    
-    status = _cairo_surface_get_extents (gstate->target, rectangle);
-    if (status)
-	return status;
-    /* check path extents here */
-    
-    if (gstate->clip.region) {
-	pixman_box16_t	    *clip_box;
-	cairo_rectangle_t   clip_rect;
-
-	/* get region extents as a box */
-	clip_box = pixman_region_extents (gstate->clip.region);
-	/* convert to a rectangle */
-	clip_rect.x = clip_box->x1;
-	clip_rect.width = clip_box->x2 - clip_box->x1;
-	clip_rect.y = clip_box->y1;
-	clip_rect.height = clip_box->y2 - clip_box->y1;
-	/* intersect with surface extents */
-	_cairo_rectangle_intersect (rectangle, &clip_rect);
-    }
-
-    if (gstate->clip.surface)
-	_cairo_rectangle_intersect (rectangle, &gstate->clip.surface_rect);
-    
-    return CAIRO_STATUS_SUCCESS;
-}
-
 cairo_surface_t *
 _cairo_gstate_get_target (cairo_gstate_t *gstate)
 {
@@ -762,11 +679,14 @@
     if (gstate->source->status)
 	return gstate->source->status;
 
-    status = _cairo_gstate_set_clip (gstate);
+    status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
-    status = _cairo_gstate_get_clip_extents (gstate, &rectangle);
+    status = _cairo_surface_get_extents (gstate->target, &rectangle);
+    if (status)
+	return status;
+    status = _cairo_clip_intersect_to_rectangle (&gstate->clip, &rectangle);
     if (status)
 	return status;
 
@@ -785,108 +705,23 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
-/* Combines @gstate->clip_surface using the IN operator with
- * the given intermediate surface, which corresponds to the
- * rectangle of the destination space given by @extents.
- */
-static cairo_status_t
-_cairo_gstate_combine_clip_surface (cairo_gstate_t    *gstate,
-				    cairo_surface_t   *intermediate,
-				    cairo_rectangle_t *extents)
-{
-    cairo_pattern_union_t pattern;
-    cairo_status_t status;
-
-    _cairo_pattern_init_for_surface (&pattern.surface,
-				     gstate->clip.surface);
-    
-    status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
-				       &pattern.base,
-				       NULL,
-				       intermediate,
-				       extents->x - gstate->clip.surface_rect.x,
-				       extents->y - gstate->clip.surface_rect.y, 
-				       0, 0,
-				       0, 0,
-				       extents->width, extents->height);
-    
-    _cairo_pattern_fini (&pattern.base);
-
-    return status;
-}
-
-/* Creates a region from a cairo_rectangle_t */
-static cairo_status_t
-_region_new_from_rect (cairo_rectangle_t  *rect,
-		       pixman_region16_t **region)
-{
-    *region = pixman_region_create ();
-    if (pixman_region_union_rect (*region, *region,
-				  rect->x, rect->y,
-				  rect->width, rect->height) != PIXMAN_REGION_STATUS_SUCCESS) {
-	pixman_region_destroy (*region);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-/* Gets the bounding box of a region as a cairo_rectangle_t */
-static void
-_region_rect_extents (pixman_region16_t *region,
-		      cairo_rectangle_t *rect)
-{
-    pixman_box16_t *region_extents = pixman_region_extents (region);
-
-    rect->x = region_extents->x1;
-    rect->y = region_extents->y1;
-    rect->width = region_extents->x2 - region_extents->x1;
-    rect->height = region_extents->y2 - region_extents->y1;
-}
-
-/* Intersects @region with the clipping bounds (both region
- * and surface) of @gstate
- */
-static cairo_status_t
-_cairo_gstate_intersect_clip (cairo_gstate_t    *gstate,
-			      pixman_region16_t *region)
-{
-    if (gstate->clip.region)
-	pixman_region_intersect (region, gstate->clip.region, region);
-
-    if (gstate->clip.surface) {
-	pixman_region16_t *clip_rect;
-	cairo_status_t status;
-    
-	status = _region_new_from_rect (&gstate->clip.surface_rect, &clip_rect);
-	if (status)
-	    return status;
-	
-	if (pixman_region_intersect (region,
-				     clip_rect,
-				     region) != PIXMAN_REGION_STATUS_SUCCESS)
-	    status = CAIRO_STATUS_NO_MEMORY;
-
-	pixman_region_destroy (clip_rect);
-
-	if (status)
-	    return status;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 static cairo_status_t
 _get_mask_extents (cairo_gstate_t    *gstate,
 		   cairo_pattern_t   *mask,
 		   cairo_rectangle_t *extents)
 {
+    cairo_status_t status;
+
     /*
      * XXX should take mask extents into account, but
      * that involves checking the transform...  For now,
      * be lazy and just use the destination extents
      */
-    return _cairo_gstate_get_clip_extents (gstate, extents);
+    status = _cairo_surface_get_extents (gstate->target, extents);
+    if (status)
+	return status;
+
+    return _cairo_clip_intersect_to_rectangle (&gstate->clip, extents);
 }
 
 cairo_status_t
@@ -906,7 +741,7 @@
     if (gstate->source->status)
 	return gstate->source->status;
 
-    status = _cairo_gstate_set_clip (gstate);
+    status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
@@ -936,7 +771,7 @@
 	    return status;
 	}
 	
-	status = _cairo_gstate_combine_clip_surface (gstate, intermediate, &extents);
+	status = _cairo_clip_combine_to_surface (&gstate->clip, intermediate, &extents);
 	if (status) {
 	    cairo_surface_destroy (intermediate);
 	    return status;
@@ -986,7 +821,7 @@
     if (gstate->line_width <= 0.0)
 	return CAIRO_STATUS_SUCCESS;
 
-    status = _cairo_gstate_set_clip (gstate);
+    status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
@@ -1049,7 +884,7 @@
  * _cairo_rectangle_fixed_round.
  */
 
-static void
+void
 _cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle)
 {
     rectangle->x = _cairo_fixed_integer_floor (box->p1.x);
@@ -1058,7 +893,7 @@
     rectangle->height = _cairo_fixed_integer_ceil (box->p2.y) - rectangle->y;
 }
 
-static void
+void
 _cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src)
 {
     int x1, y1, x2, y2;
@@ -1087,74 +922,10 @@
     return rect->width == 0 || rect->height == 0;
 }
 
-/* Given a region representing a set of trapezoids that will be
- * drawn, clip the region according to the gstate and compute
- * the overall extents.
- */
-static cairo_status_t
-_clip_and_compute_extents_region (cairo_gstate_t    *gstate,
-				  pixman_region16_t *trap_region,
-				  cairo_rectangle_t *extents)
-{
-    cairo_status_t status;
-    
-    status = _cairo_gstate_intersect_clip (gstate, trap_region);
-    if (status)
-	return status;
-
-    _region_rect_extents (trap_region, extents);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-/* Given a a set of trapezoids to draw, find a bounding box (non-exact)
- * of the trapezoids clipped by the gstate
- */
-static cairo_status_t
-_clip_and_compute_extents_arbitrary (cairo_gstate_t    *gstate,
-				     cairo_traps_t     *traps,
-				     cairo_rectangle_t *extents)
-{
-    cairo_box_t trap_extents;
-	
-    _cairo_traps_extents (traps, &trap_extents);
-    _cairo_box_round_to_rectangle (&trap_extents, extents);
-    
-    if (gstate->clip.region) {
-	pixman_region16_t *intersection;
-	cairo_status_t status;
-	
-	status = _region_new_from_rect (extents, &intersection);
-	if (status)
-	    return status;
-	
-	if (pixman_region_intersect (intersection,
-				     gstate->clip.region,
-				     intersection) == PIXMAN_REGION_STATUS_SUCCESS) 
-	{
-	    _region_rect_extents (intersection, extents);
-	}
-	else
-	{
-	    status = CAIRO_STATUS_NO_MEMORY;
-	}
-
-	pixman_region_destroy (intersection);
-
-	if (status)
-	    return status;
-    }
-
-    if (gstate->clip.surface)
-	_cairo_rectangle_intersect (extents, &gstate->clip.surface_rect);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 /* Composites a region representing a set of trapezoids.
  */
 static cairo_status_t
-_composite_trap_region (cairo_gstate_t    *gstate,
+_composite_trap_region (cairo_clip_t      *clip,
 			cairo_pattern_t   *src,
 			cairo_operator_t   operator,
 			cairo_surface_t   *dst,
@@ -1170,73 +941,43 @@
 	return CAIRO_STATUS_SUCCESS;
     
     if (num_rects > 1) {
-	
-	if (gstate->clip.mode != CAIRO_CLIP_MODE_REGION)
+	if (clip->mode != CAIRO_CLIP_MODE_REGION)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	
-	clip_serial = _cairo_surface_allocate_clip_serial (gstate->target);
-	status = _cairo_surface_set_clip_region (gstate->target, 
+	clip_serial = _cairo_surface_allocate_clip_serial (dst);
+	status = _cairo_surface_set_clip_region (dst,
 						 trap_region,
 						 clip_serial);
 	if (status)
 	    return status;
     }
     
-    if (gstate->clip.surface)
-	_cairo_pattern_init_for_surface (&mask.surface, gstate->clip.surface);
+    if (clip->surface)
+	_cairo_pattern_init_for_surface (&mask.surface, clip->surface);
 	
-    status = _cairo_surface_composite (gstate->operator,
+    status = _cairo_surface_composite (operator,
 				       src,
-				       gstate->clip.surface ? &mask.base : NULL,
+				       clip->surface ? &mask.base : NULL,
 				       dst,
 				       extents->x, extents->y,
-				       extents->x - (gstate->clip.surface ? gstate->clip.surface_rect.x : 0),
-				       extents->y - (gstate->clip.surface ? gstate->clip.surface_rect.y : 0),
+				       extents->x - (clip->surface ? clip->surface_rect.x : 0),
+				       extents->y - (clip->surface ? clip->surface_rect.y : 0),
 				       extents->x, extents->y,
 				       extents->width, extents->height);
 
-    if (gstate->clip.surface)
+    if (clip->surface)
       _cairo_pattern_fini (&mask.base);
 
     return status;
 }
 
-static void
-translate_traps (cairo_traps_t *traps, int x, int y)
-{
-    cairo_fixed_t xoff, yoff;
-    cairo_trapezoid_t *t;
-    int i;
-
-    /* Ugh. The cairo_composite/(Render) interface doesn't allow
-       an offset for the trapezoids. Need to manually shift all
-       the coordinates to align with the offset origin of the
-       intermediate surface. */
-
-    xoff = _cairo_fixed_from_int (x);
-    yoff = _cairo_fixed_from_int (y);
-
-    for (i = 0, t = traps->traps; i < traps->num_traps; i++, t++) {
-	t->top += yoff;
-	t->bottom += yoff;
-	t->left.p1.x += xoff;
-	t->left.p1.y += yoff;
-	t->left.p2.x += xoff;
-	t->left.p2.y += yoff;
-	t->right.p1.x += xoff;
-	t->right.p1.y += yoff;
-	t->right.p2.x += xoff;
-	t->right.p2.y += yoff;
-    }
-}
-
 /* Composites a set of trapezoids in the case where we need to create
- * an intermediate surface to handle gstate->clip.surface
+ * an intermediate surface to handle clip->surface
  * 
  * Warning: This call modifies the coordinates of traps
  */
 static cairo_status_t
-_composite_traps_intermediate_surface (cairo_gstate_t    *gstate,
+_composite_traps_intermediate_surface (cairo_clip_t      *clip,
 				       cairo_pattern_t   *src,
 				       cairo_operator_t   operator,
 				       cairo_surface_t   *dst,
@@ -1248,9 +989,9 @@
     cairo_surface_pattern_t intermediate_pattern;
     cairo_status_t status;
 
-    translate_traps (traps, -extents->x, -extents->y);
+    _cairo_traps_translate (traps, -extents->x, -extents->y);
 
-    intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
+    intermediate = _cairo_surface_create_similar_solid (clip->surface,
 							CAIRO_CONTENT_ALPHA,
 							extents->width,
 							extents->height,
@@ -1274,7 +1015,7 @@
     if (status)
 	goto out;
 
-    status = _cairo_gstate_combine_clip_surface (gstate, intermediate, extents);
+    status = _cairo_clip_combine_to_surface (clip, intermediate, extents);
     if (status)
 	goto out;
     
@@ -1302,7 +1043,7 @@
  * _cairo_surface_fill_rectangles).
  */
 static cairo_status_t
-_composite_trap_region_solid (cairo_gstate_t        *gstate,
+_composite_trap_region_solid (cairo_clip_t          *clip,
 			      cairo_solid_pattern_t *src,
 			      cairo_operator_t       operator,
 			      cairo_surface_t       *dst,
@@ -1337,10 +1078,10 @@
 }
 
 /* Composites a set of trapezoids in the general case where
-   gstate->clip.surface == NULL
+   clip->surface == NULL
  */
 static cairo_status_t
-_composite_traps (cairo_gstate_t    *gstate,
+_composite_traps (cairo_clip_t      *clip,
 		  cairo_pattern_t   *src,
 		  cairo_operator_t   operator,
 		  cairo_surface_t   *dst,
@@ -1349,7 +1090,7 @@
 {
     cairo_status_t status;
 
-    status = _cairo_surface_composite_trapezoids (gstate->operator,
+    status = _cairo_surface_composite_trapezoids (operator,
 						  src, dst,
 						  extents->x, extents->y,
 						  extents->x, extents->y,
@@ -1361,13 +1102,26 @@
     return status;
 }
 
+/* Gets the bounding box of a region as a cairo_rectangle_t */
+static void
+_region_rect_extents (pixman_region16_t *region,
+		      cairo_rectangle_t *rect)
+{
+    pixman_box16_t *region_extents = pixman_region_extents (region);
+
+    rect->x = region_extents->x1;
+    rect->y = region_extents->y1;
+    rect->width = region_extents->x2 - region_extents->x1;
+    rect->height = region_extents->y2 - region_extents->y1;
+}
+
 /* Warning: This call modifies the coordinates of traps */
-static cairo_status_t
-_clip_and_composite_trapezoids_transformed (cairo_gstate_t *gstate,
-					    cairo_pattern_t *src,
-					    cairo_operator_t operator,
-					    cairo_surface_t *dst,
-					    cairo_traps_t *traps)
+cairo_status_t
+_cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src,
+					      cairo_operator_t operator,
+					      cairo_surface_t *dst,
+					      cairo_traps_t *traps,
+					      cairo_clip_t *clip)
 {
     cairo_status_t status;
     pixman_region16_t *trap_region;
@@ -1380,10 +1134,15 @@
     if (status)
 	return status;
 
-    if (trap_region)
-	status = _clip_and_compute_extents_region (gstate, trap_region, &extents);
-    else
-	status = _clip_and_compute_extents_arbitrary (gstate, traps, &extents);
+    if (trap_region) {
+	status = _cairo_clip_intersect_to_region (clip, trap_region);
+	_region_rect_extents (trap_region, &extents);
+    } else {
+	cairo_box_t trap_extents;
+	_cairo_traps_extents (traps, &trap_extents);
+	_cairo_box_round_to_rectangle (&trap_extents, &extents);
+	status = _cairo_clip_intersect_to_rectangle (clip, &extents);
+    }
 	
     if (status)
 	goto out;
@@ -1392,27 +1151,27 @@
 	/* Nothing to do */
 	goto out;
 
-    if (gstate->clip.surface) {
+    if (clip->surface) {
 	if (trap_region) {
 	    /* If we are compositing a set of rectangles, we can set them as the
 	     * clip region for the destination surface and use the clip surface
 	     * as the mask. A clip region might not be supported, in which case
 	     * we fall through to the next method
 	     */
-	    status = _composite_trap_region (gstate, src, operator, dst,
+	    status = _composite_trap_region (clip, src, operator, dst,
 					     trap_region, &extents);
 	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 		goto out;
 	}
 	
 	/* Handle a clip surface by creating an intermediate surface. */
-	status = _composite_traps_intermediate_surface (gstate, src, operator,
+	status = _composite_traps_intermediate_surface (clip, src, operator,
 							dst, traps, &extents);
     } else {
         /* No clip surface */
 	if (trap_region && src->type == CAIRO_PATTERN_SOLID) {
 	    /* Solid rectangles are handled specially */
-	    status = _composite_trap_region_solid (gstate, (cairo_solid_pattern_t *)src,
+	    status = _composite_trap_region_solid (clip, (cairo_solid_pattern_t *)src,
 						   operator, dst, trap_region);
 	} else {
 	    if (trap_region) {
@@ -1421,7 +1180,7 @@
 		 * trapezoids is pretty high for most backends currently, so it's
 		 * worthwhile even if a region is needed.
 		 */
-		status = _composite_trap_region (gstate, src, operator, dst,
+		status = _composite_trap_region (clip, src, operator, dst,
 						 trap_region, &extents);
 		if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 		    goto out;
@@ -1429,7 +1188,7 @@
 		/* If a clip regions aren't supported, fall through */
 	    }
 	  
-	  status = _composite_traps (gstate, src, operator,
+	  status = _composite_traps (clip, src, operator,
 				     dst, traps, &extents);
 	}
     }
@@ -1451,11 +1210,11 @@
   
   _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
 
-  status = _clip_and_composite_trapezoids_transformed (gstate,
-						       &pattern.base,
-						       gstate->operator,
-						       gstate->target,
-						       traps);
+  status = _cairo_surface_clip_and_composite_trapezoids (&pattern.base,
+							 gstate->operator,
+							 gstate->target,
+							 traps,
+							 &gstate->clip);
 
   _cairo_pattern_fini (&pattern.base);
 
@@ -1471,7 +1230,7 @@
     if (gstate->source->status)
 	return gstate->source->status;
     
-    status = _cairo_gstate_set_clip (gstate);
+    status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
@@ -1487,7 +1246,10 @@
 
     _cairo_traps_init (&traps);
 
-    status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps);
+    status = _cairo_path_fixed_fill_to_traps (path,
+					      gstate->fill_rule,
+					      gstate->tolerance,
+					      &traps);
     if (status) {
 	_cairo_traps_fini (&traps);
 	return status;
@@ -1514,7 +1276,10 @@
 
     _cairo_traps_init (&traps);
 
-    status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps);
+    status = _cairo_path_fixed_fill_to_traps (path,
+					      gstate->fill_rule,
+					      gstate->tolerance,
+					      &traps);
     if (status)
 	goto BAIL;
 
@@ -1584,7 +1349,10 @@
   
     _cairo_traps_init (&traps);
   
-    status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps);
+    status = _cairo_path_fixed_fill_to_traps (path,
+					      gstate->fill_rule,
+					      gstate->tolerance,
+					      &traps);
     if (status)
 	goto BAIL;
   
@@ -1607,224 +1375,15 @@
 cairo_status_t
 _cairo_gstate_reset_clip (cairo_gstate_t *gstate)
 {
-    /* destroy any existing clip-region artifacts */
-    if (gstate->clip.surface)
-	cairo_surface_destroy (gstate->clip.surface);
-    gstate->clip.surface = NULL;
-
-    if (gstate->clip.region)
-	pixman_region_destroy (gstate->clip.region);
-    gstate->clip.region = NULL;
-
-    if (gstate->clip.path)
-	_cairo_clip_path_destroy (gstate->clip.path);
-    gstate->clip.path = NULL;
-
-    gstate->clip.serial = 0;
-    
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gstate_intersect_clip_path (cairo_gstate_t     *gstate,
-				   cairo_path_fixed_t *path)
-{
-    cairo_clip_path_t *clip_path;
-    cairo_status_t status;
-
-    if (gstate->clip.mode != CAIRO_CLIP_MODE_PATH)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    clip_path = malloc (sizeof (cairo_clip_path_t));
-    if (clip_path == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    status = _cairo_path_fixed_init_copy (&clip_path->path, path);
-    if (status)
-	return status;
-
-    clip_path->ref_count = 1;
-    clip_path->fill_rule = gstate->fill_rule;
-    clip_path->tolerance = gstate->tolerance;
-    clip_path->prev = gstate->clip.path;
-    gstate->clip.path = clip_path;
-    gstate->clip.serial = _cairo_surface_allocate_clip_serial (gstate->target);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_clip_path_t *
-_cairo_clip_path_reference (cairo_clip_path_t *clip_path)
-{
-    if (clip_path == NULL)
-	return NULL;
-
-    clip_path->ref_count++;
-
-    return clip_path;
-}
-
-static void
-_cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
-{
-    if (clip_path == NULL)
-	return;
-
-    clip_path->ref_count--;
-    if (clip_path->ref_count)
-	return;
-
-    _cairo_path_fixed_fini (&clip_path->path);
-    _cairo_clip_path_destroy (clip_path->prev);
-    free (clip_path);
-}
-
-static cairo_status_t
-_cairo_gstate_intersect_clip_region (cairo_gstate_t *gstate,
-				     cairo_traps_t  *traps)
-{
-    pixman_region16_t *region;
-    cairo_status_t status;
-
-    if (gstate->clip.mode != CAIRO_CLIP_MODE_REGION)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    
-    status = _cairo_traps_extract_region (traps, &region);
-    if (status)
-	return status;
-	
-    if (region == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    status = CAIRO_STATUS_SUCCESS;
-    if (gstate->clip.region == NULL) {
-	gstate->clip.region = region;
-    } else {
-	pixman_region16_t *intersection = pixman_region_create();
-    
-	if (pixman_region_intersect (intersection, 
-				     gstate->clip.region, region)
-	    == PIXMAN_REGION_STATUS_SUCCESS) {
-	    pixman_region_destroy (gstate->clip.region);
-	    gstate->clip.region = intersection;
-	} else {		
-	    status = CAIRO_STATUS_NO_MEMORY;
-	}
-	pixman_region_destroy (region);
-    }
-    gstate->clip.serial = _cairo_surface_allocate_clip_serial (gstate->target);
-    return status;
-}
-
-static cairo_status_t
-_cairo_gstate_intersect_clip_mask (cairo_gstate_t *gstate,
-				   cairo_traps_t  *traps)
-{
-    cairo_pattern_union_t pattern;
-    cairo_box_t extents;
-    cairo_rectangle_t surface_rect;
-    cairo_surface_t *surface;
-    cairo_status_t status;
-
-    /* Represent the clip as a mask surface.  We create a new surface
-     * the size of the intersection of the old mask surface and the
-     * extents of the new clip path. */
-
-    _cairo_traps_extents (traps, &extents);
-    _cairo_box_round_to_rectangle (&extents, &surface_rect);
-
-    if (gstate->clip.surface != NULL)
-	_cairo_rectangle_intersect (&surface_rect, &gstate->clip.surface_rect);
-
-    surface = _cairo_surface_create_similar_solid (gstate->target,
-						   CAIRO_CONTENT_ALPHA,
-						   surface_rect.width,
-						   surface_rect.height,
-						   CAIRO_COLOR_WHITE);
-    if (surface->status)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    /* Render the new clipping path into the new mask surface. */
-
-    translate_traps (traps, -surface_rect.x, -surface_rect.y);
-    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
-    
-    status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
-						  &pattern.base,
-						  surface,
-						  0, 0,
-						  0, 0,
-						  surface_rect.width,
-						  surface_rect.height,
-						  traps->traps,
-						  traps->num_traps);
-
-    _cairo_pattern_fini (&pattern.base);
-
-    if (status) {
-	cairo_surface_destroy (surface);
-	return status;
-    }
-
-    /* If there was a clip surface already, combine it with the new
-     * mask surface using the IN operator, so we get the intersection
-     * of the old and new clipping paths. */
-
-    if (gstate->clip.surface != NULL) {
-	_cairo_pattern_init_for_surface (&pattern.surface, gstate->clip.surface);
-
-	status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
-					   &pattern.base,
-					   NULL,
-					   surface,
-					   surface_rect.x - gstate->clip.surface_rect.x,
-					   surface_rect.y - gstate->clip.surface_rect.y,
-					   0, 0,
-					   0, 0,
-					   surface_rect.width,
-					   surface_rect.height);
-
-	_cairo_pattern_fini (&pattern.base);
-
-	if (status) {
-	    cairo_surface_destroy (surface);
-	    return status;
-	}
-
-	cairo_surface_destroy (gstate->clip.surface);
-    }
-
-    gstate->clip.surface = surface;
-    gstate->clip.surface_rect = surface_rect;
-
-    return status;
+    return _cairo_clip_reset (&gstate->clip);
 }
 
 cairo_status_t
 _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 {
-    cairo_status_t status;
-    cairo_traps_t traps;
-    
-    status = _cairo_gstate_intersect_clip_path (gstate, path);
-    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	return status;
-
-    _cairo_traps_init (&traps);
-    status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps);
-    if (status)
-	goto bail;
-
-    status = _cairo_gstate_intersect_clip_region (gstate, &traps);
-    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	goto bail;
-
-    status = _cairo_gstate_intersect_clip_mask (gstate, &traps);
-	
- bail:
-    _cairo_traps_fini (&traps);
-
-    return status;
+    return _cairo_clip_clip (&gstate->clip,
+			     path, gstate->fill_rule, gstate->tolerance,
+			     gstate->target);
 }
 
 static void
@@ -2140,7 +1699,7 @@
     if (gstate->source->status)
 	return gstate->source->status;
 
-    status = _cairo_gstate_set_clip (gstate);
+    status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 

Index: cairo-meta-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-meta-surface.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cairo-meta-surface.c	5 Aug 2005 01:44:29 -0000	1.6
+++ cairo-meta-surface.c	5 Aug 2005 05:45:59 -0000	1.7
@@ -35,15 +35,7 @@
 
 #include "cairoint.h"
 #include "cairo-meta-surface-private.h"
-
-/* 
- * Notes: 
- *
- * Can't use cairo_surface_* calls since we often don't want
- * fallbacks.  For example, when determining the font subsets or the
- * fallback areas.  Hmm... but maybe those passes could be integrated
- * into the delegation wrappers and the ps output pass, respectively.
- */
+#include "cairo-gstate-private.h"
 
 static const cairo_surface_backend_t cairo_meta_surface_backend;
 
@@ -106,10 +98,6 @@
 	    free (command);
 	    break;
 
-	case CAIRO_COMMAND_SET_CLIP_REGION:
-	    free (command);
-	    break;
-
 	case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
 	    if (command->intersect_clip_path.path_pointer)
 		_cairo_path_fixed_fini (&command->intersect_clip_path.path);
@@ -276,38 +264,6 @@
 }
 
 static cairo_int_status_t
-_cairo_meta_surface_set_clip_region (void	       *abstract_surface,
-				     pixman_region16_t *region)
-{
-    cairo_meta_surface_t *meta = abstract_surface;
-    cairo_command_set_clip_region_t *command;
-
-    command = malloc (sizeof (cairo_command_set_clip_region_t));
-    if (command == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    command->type = CAIRO_COMMAND_SET_CLIP_REGION;
-
-    if (region) {
-	command->region = pixman_region_create ();
-	pixman_region_copy (command->region, region);
-    } else {
-	command->region = NULL;
-    }
-
-    command->serial = meta->base.current_clip_serial;
-
-    if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
-	if (command->region)
-	    pixman_region_destroy (command->region);
-	free (command);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
 _cairo_meta_surface_intersect_clip_path (void		    *dst,
 					 cairo_path_fixed_t *path,
 					 cairo_fill_rule_t   fill_rule,
@@ -468,7 +424,7 @@
     _cairo_meta_surface_composite_trapezoids,
     NULL, /* copy_page */
     NULL, /* show_page */
-    _cairo_meta_surface_set_clip_region,
+    NULL, /* set_clip_region */
     _cairo_meta_surface_intersect_clip_path,
     _cairo_meta_surface_get_extents,
     _cairo_meta_surface_show_glyphs,
@@ -483,16 +439,24 @@
     cairo_command_t *command, **elements;
     int i, num_elements;
     cairo_int_status_t status;
+    cairo_traps_t traps;
+    cairo_clip_t clip;
 
     meta = (cairo_meta_surface_t *) surface;
     status = CAIRO_STATUS_SUCCESS;
 
+    _cairo_clip_init (&clip, target);    
+
     num_elements = meta->commands.num_elements;
     elements = (cairo_command_t **) meta->commands.elements;
     for (i = 0; i < num_elements; i++) {
 	command = elements[i];
 	switch (command->type) {
 	case CAIRO_COMMAND_COMPOSITE:
+	    status = _cairo_surface_set_clip (target, &clip);
+	    if (status)
+		break;
+
 	    status = _cairo_surface_composite
 		(command->composite.operator,
 		 &command->composite.src_pattern.base,
@@ -509,6 +473,10 @@
 	    break;
 
 	case CAIRO_COMMAND_FILL_RECTANGLES:
+	    status = _cairo_surface_set_clip (target, &clip);
+	    if (status)
+		break;
+
 	    status = _cairo_surface_fill_rectangles
 		(target,
 		 command->fill_rectangles.operator,
@@ -518,6 +486,10 @@
 	    break;
 
 	case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS:
+	    status = _cairo_surface_set_clip (target, &clip);
+	    if (status)
+		break;
+
 	    status = _cairo_surface_composite_trapezoids
 		(command->composite_trapezoids.operator,
 		 &command->composite_trapezoids.pattern.base,
@@ -532,27 +504,24 @@
 		 command->composite_trapezoids.num_traps);
 	    break;
 
-	case CAIRO_COMMAND_SET_CLIP_REGION:
-	    status = _cairo_surface_set_clip_region
-		(target,
-		 command->set_clip_region.region,
-		 command->set_clip_region.serial);
-	    break;
-
 	case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
 	    /* XXX Meta surface clipping is broken and requires some
 	     * cairo-gstate.c rewriting.  Work around it for now. */
-	    if (target->backend->intersect_clip_path == NULL)
-		break;
-
-	    status = _cairo_surface_intersect_clip_path
-		(target,
-		 command->intersect_clip_path.path_pointer,
-		 command->intersect_clip_path.fill_rule,
-		 command->intersect_clip_path.tolerance);
+	    if (command->intersect_clip_path.path_pointer == NULL)
+		status = _cairo_clip_reset (&clip);
+	    else
+		status = _cairo_clip_clip (&clip,
+					   command->intersect_clip_path.path_pointer,
+					   command->intersect_clip_path.fill_rule,
+					   command->intersect_clip_path.tolerance,
+					   target);
 	    break;
 
 	case CAIRO_COMMAND_SHOW_GLYPHS:
+	    status = _cairo_surface_set_clip (target, &clip);
+	    if (status)
+		break;
+
 	    status = _cairo_surface_show_glyphs
 		(command->show_glyphs.scaled_font,
 		 command->show_glyphs.operator,
@@ -569,18 +538,37 @@
 	    break;
 
 	case CAIRO_COMMAND_FILL_PATH:
-	    /* XXX Meta surface fill_path is broken and requires some
-	     * cairo-gstate.c rewriting.  Work around it for now. */
-	    if (target->backend->fill_path == NULL)
+	    status = _cairo_surface_set_clip (target, &clip);
+	    if (status)
 		break;
 
-	    status = _cairo_surface_fill_path
-		(command->fill_path.operator,
-		 &command->fill_path.pattern.base,
-		 target,
-		 &command->fill_path.path,
-		 command->fill_path.fill_rule,
-		 command->fill_path.tolerance);
+	    status = _cairo_surface_fill_path (command->fill_path.operator,
+					       &command->fill_path.pattern.base,
+					       target,
+					       &command->fill_path.path,
+					       command->fill_path.fill_rule,
+					       command->fill_path.tolerance);
+	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+		break;
+
+	    _cairo_traps_init (&traps);
+
+	    status = _cairo_path_fixed_fill_to_traps (&command->fill_path.path,
+						      command->fill_path.fill_rule,
+						      command->fill_path.tolerance,
+						      &traps);
+	    if (status) {
+		_cairo_traps_fini (&traps);
+		break;
+	    }
+
+	    status = _cairo_surface_clip_and_composite_trapezoids (&command->fill_path.pattern.base,
+								   command->fill_path.operator,
+								   target,
+								   &traps,
+								   &clip);
+
+	    _cairo_traps_fini (&traps);
 	    break;
 
 	default:
@@ -591,5 +579,7 @@
 	    break;
     }
 
+    _cairo_clip_fini (&clip);
+
     return status;
 }

Index: cairo-path-fill.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-path-fill.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- cairo-path-fill.c	23 Mar 2005 22:17:40 -0000	1.18
+++ cairo-path-fill.c	5 Aug 2005 05:45:59 -0000	1.19
@@ -36,10 +36,8 @@
 
 #include "cairoint.h"
 
-#include "cairo-gstate-private.h"
-
 typedef struct cairo_filler {
-    cairo_gstate_t *gstate;
+    double tolerance;
     cairo_traps_t *traps;
 
     cairo_point_t current_point;
@@ -48,7 +46,7 @@
 } cairo_filler_t;
 
 static void
-_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps);
+_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps);
 
 static void
 _cairo_filler_fini (cairo_filler_t *filler);
@@ -69,9 +67,9 @@
 _cairo_filler_close_path (void *closure);
 
 static void
-_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps)
+_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps)
 {
-    filler->gstate = gstate;
+    filler->tolerance = tolerance;
     filler->traps = traps;
 
     filler->current_point.x = 0;
@@ -132,7 +130,6 @@
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_filler_t *filler = closure;
     cairo_polygon_t *polygon = &filler->polygon;
-    cairo_gstate_t *gstate = filler->gstate;
     cairo_spline_t spline;
 
     status = _cairo_spline_init (&spline, &filler->current_point, b, c, d);
@@ -140,7 +137,7 @@
     if (status == CAIRO_INT_STATUS_DEGENERATE)
 	return CAIRO_STATUS_SUCCESS;
 
-    _cairo_spline_decompose (&spline, gstate->tolerance);
+    _cairo_spline_decompose (&spline, filler->tolerance);
     if (status)
 	goto CLEANUP_SPLINE;
 
@@ -174,13 +171,14 @@
 
 cairo_status_t
 _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
-				 cairo_gstate_t     *gstate,
+				 cairo_fill_rule_t   fill_rule,
+				 double              tolerance,
 				 cairo_traps_t      *traps)
 {
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_filler_t filler;
 
-    _cairo_filler_init (&filler, gstate, traps);
+    _cairo_filler_init (&filler, tolerance, traps);
 
     status = _cairo_path_fixed_interpret (path,
 					  CAIRO_DIRECTION_FORWARD,
@@ -198,7 +196,7 @@
 
     status = _cairo_traps_tessellate_polygon (filler.traps,
 					      &filler.polygon,
-					      filler.gstate->fill_rule);
+					      fill_rule);
     if (status)
 	goto BAIL;
 

Index: cairo-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-surface.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -d -r1.87 -r1.88
--- cairo-surface.c	5 Aug 2005 01:44:29 -0000	1.87
+++ cairo-surface.c	5 Aug 2005 05:45:59 -0000	1.88
@@ -1283,7 +1283,7 @@
  * Sets the clipping path to be the intersection of the current
  * clipping path of the surface and the given path.
  **/
-cairo_status_t
+static cairo_status_t
 _cairo_surface_set_clip_path (cairo_surface_t	*surface,
 			      cairo_clip_path_t	*clip_path,
 			      unsigned int	serial)
@@ -1314,6 +1314,27 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
+cairo_status_t
+_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
+{
+    if (!surface)
+	return CAIRO_STATUS_NULL_POINTER;
+    if (clip->serial == _cairo_surface_get_current_clip_serial (surface))
+	return CAIRO_STATUS_SUCCESS;
+    
+    if (clip->path)
+	return _cairo_surface_set_clip_path (surface,
+					     clip->path,
+					     clip->serial);
+    
+    if (clip->region)
+	return _cairo_surface_set_clip_region (surface, 
+					       clip->region,
+					       clip->serial);
+    
+    return _cairo_surface_reset_clip (surface);
+}
+
 /**
  * _cairo_surface_get_extents:
  * @surface: the #cairo_surface_t to fetch extents for

Index: cairo-traps.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-traps.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- cairo-traps.c	1 Jun 2005 07:29:24 -0000	1.28
+++ cairo-traps.c	5 Aug 2005 05:45:59 -0000	1.29
@@ -229,6 +229,35 @@
     return ret;
 }
 
+void
+_cairo_traps_translate (cairo_traps_t *traps, int x, int y)
+{
+    cairo_fixed_t xoff, yoff;
+    cairo_trapezoid_t *t;
+    int i;
+
+    /* Ugh. The cairo_composite/(Render) interface doesn't allow
+       an offset for the trapezoids. Need to manually shift all
+       the coordinates to align with the offset origin of the
+       intermediate surface. */
+
+    xoff = _cairo_fixed_from_int (x);
+    yoff = _cairo_fixed_from_int (y);
+
+    for (i = 0, t = traps->traps; i < traps->num_traps; i++, t++) {
+	t->top += yoff;
+	t->bottom += yoff;
+	t->left.p1.x += xoff;
+	t->left.p1.y += yoff;
+	t->left.p2.x += xoff;
+	t->left.p2.y += yoff;
+	t->right.p1.x += xoff;
+	t->right.p1.y += yoff;
+	t->right.p2.x += xoff;
+	t->right.p2.y += yoff;
+    }
+}
+
 cairo_status_t
 _cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3])
 {

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.178
retrieving revision 1.179
diff -u -d -r1.178 -r1.179
--- cairoint.h	5 Aug 2005 01:44:29 -0000	1.178
+++ cairoint.h	5 Aug 2005 05:45:59 -0000	1.179
@@ -240,6 +240,9 @@
 } cairo_direction_t;
 
 typedef struct _cairo_path_fixed cairo_path_fixed_t;
+typedef enum _cairo_clip_mode cairo_clip_mode_t;
+typedef struct _cairo_clip_path cairo_clip_path_t;
+typedef struct _cairo_clip cairo_clip_t;
 
 typedef struct _cairo_edge {
     cairo_line_t edge;
@@ -289,6 +292,13 @@
 typedef struct _cairo_color cairo_color_t;
 typedef struct _cairo_image_surface cairo_image_surface_t;
 
+cairo_private void
+_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle);
+
+cairo_private void
+_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src);
+
+
 /* cairo_array.c structures and functions */ 
 
 typedef struct _cairo_array cairo_array_t;
@@ -813,12 +823,6 @@
     unsigned long blue_mask;
 } cairo_format_masks_t;
 
-typedef enum _cairo_clip_mode {
-    CAIRO_CLIP_MODE_PATH,
-    CAIRO_CLIP_MODE_REGION,
-    CAIRO_CLIP_MODE_MASK
-} cairo_clip_mode_t;
-
 struct _cairo_surface {
     const cairo_surface_backend_t *backend;
 
@@ -1499,7 +1503,8 @@
 /* cairo_path_fill.c */
 cairo_private cairo_status_t
 _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
-				 cairo_gstate_t     *gstate,
+				 cairo_fill_rule_t   fill_rule,
+				 double              tolerance,
 				 cairo_traps_t      *traps);
 
 /* cairo_path_stroke.c */
@@ -1585,6 +1590,13 @@
 				     cairo_trapezoid_t	*traps,
 				     int		ntraps);
 
+cairo_status_t
+_cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src,
+					      cairo_operator_t operator,
+					      cairo_surface_t *dst,
+					      cairo_traps_t *traps,
+					      cairo_clip_t *clip);
+
 cairo_private cairo_status_t
 _cairo_surface_copy_page (cairo_surface_t *surface);
 
@@ -1640,12 +1652,8 @@
 				    cairo_fill_rule_t   fill_rule,
 				    double		tolerance);
 
-typedef struct _cairo_clip_path cairo_clip_path_t;
-
 cairo_private cairo_status_t
-_cairo_surface_set_clip_path (cairo_surface_t	*surface,
-			      cairo_clip_path_t	*clip_path,
-			      unsigned int	serial);
+_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_get_extents (cairo_surface_t   *surface,
@@ -1800,6 +1808,9 @@
 cairo_private void
 _cairo_traps_fini (cairo_traps_t *traps);
 
+cairo_private void
+_cairo_traps_translate (cairo_traps_t *traps, int x, int y);
+
 cairo_private cairo_status_t
 _cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3]);
 




More information about the cairo-commit mailing list