[cairo-commit] cairo/src cairo.c, 1.33, 1.34 cairo_gstate.c, 1.42, 1.43 cairo_image_surface.c, 1.7, 1.8 cairo_ps_surface.c, 1.6, 1.7 cairo_surface.c, 1.23, 1.24 cairo_xlib_surface.c, 1.16, 1.17 cairoint.h, 1.52, 1.53

Graydon Hoare commit at pdx.freedesktop.org
Fri Mar 19 15:47:27 PST 2004


Committed by: graydon

Update of /cvs/cairo/cairo/src
In directory pdx:/tmp/cvs-serv14228/src

Modified Files:
	cairo.c cairo_gstate.c cairo_image_surface.c 
	cairo_ps_surface.c cairo_surface.c cairo_xlib_surface.c 
	cairoint.h 
Log Message:
2004-03-19  Graydon Hoare  <graydon at redhat.com>

	* src/cairo.c (cairo_init_clip): Add.
	* src/cairo_gstate.c:
	Initialize, finalize and copy clip.region.
	Detect rectangular clips and push down to backend.

	* src/cairoint.h
	(cairo_surface_backend_t): Add set_clip_region slot.
	(cairo_clip_rec_t): Add region slot.
	(_cairo_gstate_init_clip)
	(_cairo_surface_set_clip_region): Prototype.

	* src/cairo_surface.c
	(_cairo_surface_set_clip_region): Add.
	
	* src/cairo_xlib_surface.c 
	(_cairo_xlib_surface_set_clip_region): Add.

	* src/cairo_image_surface.c 
	(_cairo_image_surface_set_clip_region): Add.

	* src/cairo_ps_surface.c
	(_cairo_ps_surface_set_clip_region): Stub, not implemented.



Index: cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** a/cairo.c	18 Feb 2004 02:38:23 -0000	1.33
--- b/cairo.c	19 Mar 2004 23:47:25 -0000	1.34
***************
*** 637,640 ****
--- 637,649 ----
  
  void
+ cairo_init_clip (cairo_t *cr)
+ {
+     if (cr->status)
+ 	return;
+ 
+     cr->status = _cairo_gstate_init_clip (cr->gstate);
+ }
+ 
+ void
  cairo_clip (cairo_t *cr)
  {

Index: cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -d -r1.42 -r1.43
*** a/cairo_gstate.c	18 Feb 2004 02:38:23 -0000	1.42
--- b/cairo_gstate.c	19 Mar 2004 23:47:25 -0000	1.43
***************
*** 82,85 ****
--- 82,86 ----
      gstate->source_is_solid = 1;
  
+     gstate->clip.region = NULL;
      gstate->clip.surface = NULL;
  
***************
*** 124,127 ****
--- 125,134 ----
      }
  
+     if (other->clip.region)
+     {	
+ 	gstate->clip.region = pixman_region_create ();
+ 	pixman_region_copy (gstate->clip.region, other->clip.region);
+     }
+ 
      cairo_surface_reference (gstate->surface);
      cairo_surface_reference (gstate->source);
***************
*** 167,170 ****
--- 174,181 ----
      gstate->clip.surface = NULL;
  
+     if (gstate->clip.region)
+ 	pixman_region_destroy (gstate->clip.region);
+     gstate->clip.region = NULL;
+ 
      _cairo_color_fini (&gstate->color);
  
***************
*** 1437,1440 ****
--- 1448,1452 ----
  	cairo_surface_destroy (white);
      BAIL0:
+ 
  	if (status)
  	    return status;
***************
*** 1549,1552 ****
--- 1561,1629 ----
  }
  
+ 
+ cairo_status_t
+ _cairo_gstate_init_clip (cairo_gstate_t *gstate)
+ {
+     pixman_region16_t *rect = NULL;
+     pixman_box16_t box;
+ 
+     /* 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;
+ 
+     /* reset the surface's clip to the whole surface */
+     _cairo_surface_set_clip_region (gstate->surface, 
+ 				    gstate->clip.region);
+ 
+     return CAIRO_STATUS_SUCCESS;
+ }
+ 
+ static int
+ extract_transformed_rectangle(cairo_matrix_t *mat,
+ 			      cairo_traps_t *tr,
+ 			      pixman_box16_t *box)
+ {
+ #define CAIRO_FIXED_IS_INTEGER(x) (((x) & 0xFFFF) == 0)
+ #define CAIRO_FIXED_INTEGER_PART(x) ((x) >> 16)
+ 
+     double a, b, c, d, tx, ty;
+     cairo_status_t st;
+ 
+     st = cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);    
+     if (!(st == CAIRO_STATUS_SUCCESS && b == 0. && c == 0.))
+ 	return 0;
+ 
+     if (tr->num_traps == 1 
+ 	&& tr->traps[0].left.p1.x == tr->traps[0].left.p2.x
+ 	&& tr->traps[0].right.p1.x == tr->traps[0].right.p2.x
+ 	&& tr->traps[0].left.p1.y == tr->traps[0].right.p1.y
+ 	&& tr->traps[0].left.p2.y == tr->traps[0].right.p2.y
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p1.x)
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p1.y)
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p2.x)
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p2.y)
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p1.x)
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p1.y)
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p2.x)
+ 	&& CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p2.y)) {
+ 
+ 	box->x1 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].left.p1.x);
+ 	box->x2 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].right.p1.x);
+ 	box->y1 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].left.p1.y);
+ 	box->y2 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].left.p2.y);
+ 	return 1;
+     }
+     return 0;
+ 
+ #undef CAIRO_FIXED_IS_INTEGER
+ #undef CAIRO_FIXED_INTEGER_PART
+ }
+ 
  cairo_status_t
  _cairo_gstate_clip (cairo_gstate_t *gstate)
***************
*** 1556,1559 ****
--- 1633,1685 ----
      cairo_traps_t traps;
      cairo_color_t white_color;
+     pixman_box16_t box;
+ 
+     /* Fill the clip region as traps. */
+ 
+     _cairo_traps_init (&traps);
+     status = _cairo_path_fill_to_traps (&gstate->path, gstate, &traps);
+     if (status) {
+ 	_cairo_traps_fini (&traps);
+ 	return status;
+     }
+ 
+     /* Check to see if we can represent these traps as a PixRegion. */
+ 
+     if (extract_transformed_rectangle (&gstate->ctm, &traps, &box)) {
+ 
+ 	pixman_region16_t *rect = NULL;
+ 	pixman_region16_t *intersection = NULL;
+ 
+ 	status = CAIRO_STATUS_SUCCESS;
+ 	rect = pixman_region_create_simple (&box);
+ 	
+ 	if (rect == NULL) {
+ 	    status = CAIRO_STATUS_NO_MEMORY;
+ 
+ 	} else {
+ 	    
+ 	    if (gstate->clip.region == NULL) {
+ 		gstate->clip.region = rect;		
+ 	    } else {
+ 		intersection = pixman_region_create();
+ 		if (pixman_region_intersect (intersection, 
+ 					     gstate->clip.region, rect)
+ 		    == PIXMAN_REGION_STATUS_SUCCESS) {
+ 		    pixman_region_destroy (gstate->clip.region);
+ 		    gstate->clip.region = intersection;
+ 		} else {		
+ 		    status = CAIRO_STATUS_NO_MEMORY;
+ 		}
+ 		pixman_region_destroy (rect);
+ 	    }
+ 
+ 	    _cairo_surface_set_clip_region (gstate->surface, 
+ 					    gstate->clip.region);
+ 	}
+ 	_cairo_traps_fini (&traps);
+ 	return status;
+     }
+ 
+     /* Otherwise represent the clip as a mask surface. */
  
      _cairo_color_init (&white_color);
***************
*** 1584,1594 ****
      cairo_surface_set_repeat (alpha_one, 1);
  
-     _cairo_traps_init (&traps);
-     status = _cairo_path_fill_to_traps (&gstate->path, gstate, &traps);
-     if (status) {
- 	_cairo_traps_fini (&traps);
- 	return status;
-     }
- 
      _cairo_gstate_clip_and_composite_trapezoids (gstate,
  						 alpha_one,
--- 1710,1713 ----

Index: cairo_image_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_image_surface.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** a/cairo_image_surface.c	11 Dec 2003 21:04:39 -0000	1.7
--- b/cairo_image_surface.c	19 Mar 2004 23:47:25 -0000	1.8
***************
*** 450,453 ****
--- 450,462 ----
  }
  
+ static cairo_int_status_t
+ _cairo_image_surface_set_clip_region (void *abstract_surface,
+ 				      pixman_region16_t *region)
+ {
+     cairo_image_surface_t *surf = (cairo_image_surface_t *) abstract_surface;
+     pixman_image_set_clip_region (surf->pixman_image, region);
+     return CAIRO_STATUS_SUCCESS;
+ }
+ 
  static const cairo_surface_backend_t cairo_image_surface_backend = {
      _cairo_image_surface_create_similar,
***************
*** 463,466 ****
      _cairo_image_surface_composite_trapezoids,
      _cairo_image_surface_copy_page,
!     _cairo_image_surface_show_page
  };
--- 472,476 ----
      _cairo_image_surface_composite_trapezoids,
      _cairo_image_surface_copy_page,
!     _cairo_image_surface_show_page,
!     _cairo_image_surface_set_clip_region
  };

Index: cairo_ps_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ps_surface.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** a/cairo_ps_surface.c	11 Dec 2003 20:43:58 -0000	1.6
--- b/cairo_ps_surface.c	19 Mar 2004 23:47:25 -0000	1.7
***************
*** 395,398 ****
--- 395,407 ----
  }
  
+ static cairo_int_status_t
+ _cairo_ps_surface_set_clip_region (void *abstract_surface,
+ 				   pixman_region16_t *region)
+ {
+     /* FIXME: I don't really understand this backend. */
+     return CAIRO_STATUS_SUCCESS;
+ }
+ 
+ 
  static const cairo_surface_backend_t cairo_ps_surface_backend = {
      _cairo_ps_surface_create_similar,
***************
*** 408,411 ****
      _cairo_ps_surface_composite_trapezoids,
      _cairo_ps_surface_copy_page,
!     _cairo_ps_surface_show_page
  };
--- 417,421 ----
      _cairo_ps_surface_composite_trapezoids,
      _cairo_ps_surface_copy_page,
!     _cairo_ps_surface_show_page,
!     _cairo_ps_surface_set_clip_region
  };

Index: cairo_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_surface.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** a/cairo_surface.c	17 Mar 2004 17:44:26 -0000	1.23
--- b/cairo_surface.c	19 Mar 2004 23:47:25 -0000	1.24
***************
*** 373,374 ****
--- 373,379 ----
  }
  
+ cairo_status_t
+ _cairo_surface_set_clip_region (cairo_surface_t *surface, pixman_region16_t *region)
+ {
+     return surface->backend->set_clip_region (surface, region);
+ }

Index: cairo_xlib_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_xlib_surface.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** a/cairo_xlib_surface.c	2 Feb 2004 19:20:45 -0000	1.16
--- b/cairo_xlib_surface.c	19 Mar 2004 23:47:25 -0000	1.17
***************
*** 456,460 ****
      cairo_xlib_surface_t *src_clone = NULL;
      cairo_xlib_surface_t *mask_clone = NULL;
!     
  
      if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
--- 456,460 ----
      cairo_xlib_surface_t *src_clone = NULL;
      cairo_xlib_surface_t *mask_clone = NULL;
! 
  
      if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
***************
*** 574,577 ****
--- 574,620 ----
  }
  
+ static cairo_int_status_t
+ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
+ 				     pixman_region16_t *region)
+ {
+     Region xregion;
+     XRectangle xr;
+     pixman_box16_t *box;
+     cairo_xlib_surface_t *surf;
+     int n, m;
+ 
+     surf = (cairo_xlib_surface_t *) abstract_surface;
+ 
+     if (region == NULL) {
+ 	/* NULL region == reset the clip */
+ 	xregion = XCreateRegion();
+ 	xr.x = 0;
+ 	xr.y = 0;
+ 	xr.width = surf->width;
+ 	xr.height = surf->height;
+ 	XUnionRectWithRegion (&xr, xregion, xregion);
+ 
+     } else {
+ 	n = pixman_region_num_rects (region);
+ 	if (n == 0)
+ 	    return;
+ 	box = pixman_region_rects (region);
+ 	xregion = XCreateRegion();
+ 	
+ 	m = n;
+ 	for (; n > 0; --n, ++box) {
+ 	    xr.x = (short) box->x1;
+ 	    xr.y = (short) box->y1;
+ 	    xr.width = (unsigned short) (box->x2 - box->x1);
+ 	    xr.height = (unsigned short) (box->y2 - box->y1);
+ 	    XUnionRectWithRegion (&xr, xregion, xregion);
+ 	}    
+     }
+     
+     XRenderSetPictureClipRegion (surf->dpy, surf->picture, xregion);
+     XDestroyRegion(xregion);
+     return CAIRO_STATUS_SUCCESS;
+ }
+ 
  static const struct cairo_surface_backend cairo_xlib_surface_backend = {
      _cairo_xlib_surface_create_similar,
***************
*** 587,591 ****
      _cairo_xlib_surface_composite_trapezoids,
      _cairo_xlib_surface_copy_page,
!     _cairo_xlib_surface_show_page
  };
  
--- 630,635 ----
      _cairo_xlib_surface_composite_trapezoids,
      _cairo_xlib_surface_copy_page,
!     _cairo_xlib_surface_show_page,
!     _cairo_xlib_surface_set_clip_region
  };
  
***************
*** 646,650 ****
      else
  	surface->picture = 0;
! 
      return (cairo_surface_t *) surface;
  }
--- 690,694 ----
      else
  	surface->picture = 0;
!     
      return (cairo_surface_t *) surface;
  }

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** a/cairoint.h	18 Feb 2004 02:38:23 -0000	1.52
--- b/cairoint.h	19 Mar 2004 23:47:25 -0000	1.53
***************
*** 373,376 ****
--- 373,380 ----
      cairo_int_status_t
      (*show_page)		(void			*surface);
+ 
+     cairo_int_status_t
+     (*set_clip_region)		(void			*surface,
+ 				 pixman_region16_t	*region);
  } cairo_surface_backend_t;
  
***************
*** 464,467 ****
--- 468,472 ----
      int width;
      int height;
+     pixman_region16_t *region;
      cairo_surface_t *surface;
  } cairo_clip_rec_t;
***************
*** 753,756 ****
--- 758,764 ----
  
  extern cairo_status_t __internal_linkage
+ _cairo_gstate_init_clip (cairo_gstate_t *gstate);
+ 
+ extern cairo_status_t __internal_linkage
  _cairo_gstate_clip (cairo_gstate_t *gstate);
  
***************
*** 1035,1038 ****
--- 1043,1049 ----
  _cairo_surface_show_page (cairo_surface_t *surface);
  
+ extern cairo_status_t __internal_linkage
+ _cairo_surface_set_clip_region (cairo_surface_t *surface, pixman_region16_t *region);
+ 
  extern double __internal_linkage
  _cairo_surface_pixels_per_inch (cairo_surface_t *surface);





More information about the cairo-commit mailing list