GNOME Bugzilla – Bug 118317
Wrong clipping with nested begin/end_paint
Last modified: 2011-02-04 16:16:03 UTC
According to the documentation for gdk_window_begin_paint_region(), when you nest calls to this function backing stores will be pushed on a stack and drawing will only affect the top layer. It doesn't seem to work like that currently. The test program I will attach creates a drawing area and draws first a red rectangle all over the allocation, then begin_paint()s on a smaller rectangle in the middle. Then it draws blue color all over the allocation and calls end_paint(). Finally it draws a purple strip the width of the drawing area. I would expect a) The red color would cover the entire area b) The blue color would be clipped to the smaller rectangle c) The purple color would be clipped to the entire area minus the blue rectangle This would look like this: http://www.daimi.au.dk/~sandmann/right-clip.png but the program actually produces this: http://www.daimi.au.dk/~sandmann/wrong-clip.png So (b) doesn't happen; the blue color is not clipped to the smaller rectangle, but (c) does happen; the purple color is clipped to the entire area minus the blue rectangle The problem is that all the layers in the paint stack actually use the same pixmap, and drawing is only clipped when the backing store is actually copied on-screen. This means that if you draw outside the top-of-stack-region it will affect the lower layers. Assuming the documentation is right and I'm not misreading it, I can see two fixes: - make sure all drawing is actually clipped to the top-of-stack region This will require all drawing primitives modifying the clip-region of the GC to become the intersection of the layer region and the previous region before using it. - make each layer of the paint stack have its own pixmap I am attaching a patch that does the latter because - it is a fairly substantial simplification of gdkwindow.c. - nested begin/end pairs are used very rarely, so the extra pixmaps won't matter too much. - For performance reasons I don't think a gdk_gc_set_clipmask per drawing primitive is a good idea The patch also includes trivial modifcations to testgtk.c so that the "image from drawable" test will fit on an 800x600 screen.
Created attachment 18604 [details] Test application
Created attachment 18605 [details] [review] The patch
Comments in: http://mail.gnome.org/archives/gtk-devel-list/2003-August/msg00131.html Except for specific comments noted there the patch seems fine. Because nested paints are so rare, I think this is best only done in HEAD.
Wed Aug 20 22:04:47 2003 Soeren Sandmann <sandmann@daimi.au.dk> * gdk/gdkwindow.c: Make the layers in the paint stack have their own pixmap instead of sharing one. * tests/testgtk.c (create_get_image): Fixes to make the window fit on an 800x600 screen
Created attachment 19395 [details] [review] The patch I committed