[cairo] Strange values of cairo_xlib_surface_get_width

Benjamin Otte otte at redhat.com
Wed Jul 7 06:31:45 PDT 2010


Hey,

What you're seeing here is a GTK feature. GTK does not hand you a Cairo
surface made for the current widget, but applies some sophistication.
Some I do remember (there's probably more):

1) There is double buffering going on. To avoid flicker, GTK creates a
Pixmap and causes all rendering to happen on that Pixmap. Then it does a
single blit of the pixmap to the X window. The Pixmap will only be as
big as the area that needs to be redrawn. This explains why the surface
may be smaller than your allocation.

2) Some GTK widgets are NOWINDOW widgets and reuse the parent's
GdkWindow. This explains why the surface may be bigger than your
allocation.

3) Since GTK 2.20, so called "client side windows" exist in GTK. These
are GdkWindows that aren't backed by an Xlib window. They instead reuse
the parent's Xlib window when drawing. This also explains why the
surface may be bigger than your allocation.

In short: Do not rely on the target surface's size for anything.

Benjamin


On Wed, 2010-07-07 at 11:32 +0200, Stefan Salewski wrote:
> Hello,
> 
> I have just started working on my first non trivial GTK+/Cairo program.
> (picture of early draft of GUI: http://www.ssalewski.de/tmp/GUI.png )
> 
> My code is mainly based on the examples from A.Krauses GTK book, the
> http://zetcode.com/tutorials/cairographicstutorial/ and other web
> resources.
> 
> One of my task was to find the size of the GTK drawing area, which is
> used for cairo drawing.
> 
> My first attempt was using 
> 
> cairo_xlib_surface_get_width (surface)
> 
> which I found in an example in the web.
> But that gave me sometimes strange results, while
> widget->allocation.width seems to work fine.
> 
> I was going to just ignore this problem, but now I decided to search for
> an explanation -- to understand the problem and to avoid similar
> problems in future. So I stripped down my code to this example:
> 
> http://www.ssalewski.de/tmp/main.c
> 
> Excerpt:
>   cairosurfacewidth = widget->allocation.width;
>   cairosurfaceheight = widget->allocation.height;
> 
>   cr = gdk_cairo_create (widget->window);
>   surface = cairo_get_target (cr);
>   if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
>     g_print("we have problems\n");
>   cairowidthfromsurface = cairo_xlib_surface_get_width (surface);
>   cairoheightfromsurface = cairo_xlib_surface_get_height (surface);
> 
>   g_print("widget->allocation: %d  %d ",cairosurfacewidth, cairosurfaceheight);
>   g_print("cairo_xlib_surface_get: %d  %d\n",cairowidthfromsurface, cairoheightfromsurface);
> 
> 
> Output looks like
> 
> stefan at AMD64X2 ~/cairobug $ gcc -o test `pkg-config --cflags --libs gtk+-2.0` main.c
> stefan at AMD64X2 ~/cairobug $ ./test 
> widget->allocation: 100  100 cairo_xlib_surface_get: 182  110
> widget->allocation: 101  101 cairo_xlib_surface_get: 183  111
> widget->allocation: 101  102 cairo_xlib_surface_get: 183  107
> 
> widget->allocation: 108  248 cairo_xlib_surface_get: 197  253
> widget->allocation: 109  248 cairo_xlib_surface_get: 114  258
> widget->allocation: 109  249 cairo_xlib_surface_get: 200  259
> widget->allocation: 110  249 cairo_xlib_surface_get: 115  259
> widget->allocation: 111  249 cairo_xlib_surface_get: 116  259
> widget->allocation: 111  250 cairo_xlib_surface_get: 204  260
> widget->allocation: 112  250 cairo_xlib_surface_get: 117  260
> widget->allocation: 111  250 cairo_xlib_surface_get: 112  250
> 
> While the height (second value each) seems to be not too wrong, the
> width result of  cairo_xlib_surface_get_width makes very strange output,
> with jumping values. 
> 
> This is on a 64 bit AMD dual core box with Gentoo-Linux, 
> 
> stefan at AMD64X2 ~ $ emerge -pv gtk+ cairo
> 
> x11-libs/gtk+-2.18.9  USE="cups jpeg jpeg2k tiff (-aqua) -debug -doc -test -vim-syntax -xinerama" 17,769 kB
> 
> x11-libs/cairo-1.8.8  USE="X opengl svg (-aqua) -cleartype -debug -directfb -doc -glitz -xcb" 6,491 kB
> 
> gcc version 4.4.4
> 
> Best regards
> 
> Stefan Salewski
> 
> 
> --
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo




More information about the cairo mailing list