After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 118317 - Wrong clipping with nested begin/end_paint
Wrong clipping with nested begin/end_paint
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: X11
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2003-07-25 17:32 UTC by Soren Sandmann Pedersen
Modified: 2011-02-04 16:16 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test application (2.08 KB, text/plain)
2003-07-25 17:33 UTC, Soren Sandmann Pedersen
  Details
The patch (15.61 KB, patch)
2003-07-25 17:34 UTC, Soren Sandmann Pedersen
none Details | Review
The patch I committed (14.59 KB, patch)
2003-08-20 21:14 UTC, Soren Sandmann Pedersen
none Details | Review

Description Soren Sandmann Pedersen 2003-07-25 17:32:53 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.
Comment 1 Soren Sandmann Pedersen 2003-07-25 17:33:33 UTC
Created attachment 18604 [details]
Test application
Comment 2 Soren Sandmann Pedersen 2003-07-25 17:34:48 UTC
Created attachment 18605 [details] [review]
The patch
Comment 3 Owen Taylor 2003-08-19 17:52:38 UTC
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.
Comment 4 Soren Sandmann Pedersen 2003-08-20 21:13:27 UTC
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
Comment 5 Soren Sandmann Pedersen 2003-08-20 21:14:12 UTC
Created attachment 19395 [details] [review]
The patch I committed