[cairo] synchronize surface clip region with gstate

Alexander Larsson alexl at redhat.com
Mon Dec 20 08:31:07 PST 2004


All state is not virtualized in gstate. The clip region is set on the
surface, which is shared between gstates. This means if you set a clip
region and then pop the gstate the new top gstate->surface has the old
clip region. 

Here is a fix:

Index: src/cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.44
diff -u -p -r1.44 cairo.c
--- src/cairo.c	22 Oct 2004 01:40:50 -0000	1.44
+++ src/cairo.c	20 Dec 2004 16:27:20 -0000
@@ -159,6 +159,12 @@ cairo_restore (cairo_t *cr)
 
     if (cr->gstate == NULL)
 	cr->status = CAIRO_STATUS_INVALID_RESTORE;
+    
+    if (cr->status)
+	return;
+   
+    cr->status = _cairo_gstate_restore_surface_state (cr->gstate);
+    
     CAIRO_CHECK_SANITY (cr);
 }
 slim_hidden_def(cairo_restore);
Index: src/cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.67
diff -u -p -r1.67 cairo_gstate.c
--- src/cairo_gstate.c	2 Dec 2004 00:27:18 -0000	1.67
+++ src/cairo_gstate.c	20 Dec 2004 16:27:20 -0000
@@ -1705,6 +1782,25 @@ extract_transformed_rectangle(cairo_matr
     return 0;
 }
 
+/* Reset surface clip region to the one in the gstate */
+cairo_status_t
+_cairo_gstate_restore_surface_state (cairo_gstate_t *gstate)
+{
+    cairo_status_t status;
+
+    status = CAIRO_STATUS_SUCCESS;
+    
+    if (gstate->surface) 
+	status = _cairo_surface_set_clip_region (gstate->surface, 
+						 gstate->clip.region);
+
+    /* If not supported we're already using surface clipping */
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
+	status = CAIRO_STATUS_SUCCESS;
+
+    return status;
+}
+
 cairo_status_t
 _cairo_gstate_clip (cairo_gstate_t *gstate)
 {
Index: src/cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.73
diff -u -p -r1.73 cairoint.h
--- src/cairoint.h	23 Nov 2004 20:53:46 -0000	1.73
+++ src/cairoint.h	20 Dec 2004 16:27:20 -0000
@@ -1041,6 +1048,9 @@ _cairo_gstate_init_clip (cairo_gstate_t 
 extern cairo_status_t __internal_linkage
 _cairo_gstate_clip (cairo_gstate_t *gstate);
 
+extern cairo_status_t
+_cairo_gstate_restore_surface_state (cairo_gstate_t *gstate);
+
 extern cairo_status_t __internal_linkage
 _cairo_gstate_show_surface (cairo_gstate_t	*gstate,
 			    cairo_surface_t	*surface,


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl at redhat.com    alla at lysator.liu.se 
He's an otherworldly misogynist paranormal investigator plagued by the memory 
of his family's brutal murder. She's a virginal French-Canadian safe cracker 
with a birthmark shaped like Liberty's torch. They fight crime! 




More information about the cairo mailing list