[cairo] insufficiency of gdkcairo

Jason Dorje Short jdorje at users.sf.net
Thu Jan 19 18:56:06 PST 2006


I have several questions about gdk-cairo and cairo<->GTK integration, 
and some comments about why I believe it to be incomplete for programs 
using GTK.

My first question is about using drawables with an alpha level.  In old 
GTK and X code, a drawable (GdkPixmap or Pixmap) did not have any alpha 
level.  At some point GTK worked its way around this by using 
GdkPixbufs.  Now all of gdk is supposed to be cairo-based.  Does this 
mean a GdkPixmap can have transparency?  You'd think that it would, but 
evidently not.

(Side note: looking at the GDK 2.8.10 code, I see that GDK is not 
actually cairo-based.  I had assumed that GdkPixmap was just a wrapper 
for cairo_surface_t, so that internally all GDK operations were just 
wrappers for cairo ones.  It would seem to me this is by far the best 
way to do it.  What's actually done is the old method of having 
different types of Pixmaps is still around, and gdkcairo just delves 
into the appropriate backend to get it to create a new cairo_surface_t 
for that pixmap.  This is something I'd say should definitely be 
changed.  With cairo to provide the different backends there is no need 
for GdkPixbuf to have different backends itself!)

So then we are still stuck with using GdkPixbufs for transparency.  The 
problem here is that there is no way for GdkPixbuf to interact with a 
cairo surface that I can see.  The only way is to make a new 
cairo_surface of whatever type and copy the pixbuf data into it (or vice 
versa).  This is a major problem because the majority of the GTK api is 
based entirely on Pixmaps and Pixbufs, and there is, therefore, *no way* 
to use cairo within GTK to do drawing with transparency.  This means, 
basically, that Cairo is not useful within gtk 2.8, and there is no 
incentive for programs to use it except to be able to access a few toy 
drawing operations.

So the next question is: what is needed to fix this?

 From the GTK user's point of view, the basic thing that's needed is for 
GDK to be able to make GdkPixmaps that have alpha levels.  The problem 
with this is two-fold however.  First, all the rest of the GDK API 
assumes that these pixmaps have no alpha, and some may no longer make 
sense with an alpha-supporting Pixmap.  Perhaps a bigger problem is that 
the GDK *backend* also assumes that pixmaps have no alpha, and since the 
GDK backends are not cairo-based this could be a major problem.  Some 
GDK backends may not even support alpha levels; if they were cairo-based 
this could easily be sidestepped by using image surfaces instead but 
since this isn't the case that problem would be insolvable.  The end 
result would be that GdkPixbuf would become obsolete, replaced by 
GdkPixmaps that have alpha support.

An alternative solution from the user's PoV would be to add direct cairo 
support into the gtk/gdk API.  Then gdkcairo would have to be able to 
create a cairo_surface_t directly (the gdk backend would create one of 
the appropriate type; i.e., gdk-x11 would create a cairo-x11 surface). 
Further, all places in the GTK and GDK apis which currently take a 
Pixmap or Pixbuf (and there are lots of them - like gtk_list_store_set 
or gtk_window_set_icon) would have to have variants that take a 
cairo_surface_t.  This would require much greater API changes (many API 
bits which are currently duplicated for Pixmaps and Pixbufs would become 
triplicated).

 From a design point of view, the solution is to get rid of the 
different gdkpixmap backends.  All gdkpixmaps should just be cairo 
surfaces, created to be an appropriate type (possibly the only backend 
function needed).  In the long run this would greatly simplify the GDK 
drawing code since it wouldn't have to worry about platform issues at 
all - cairo would do all the work.  However it will take lots of work to 
make this change, and cairo might not actually be up to the task (gdk 
has a linux-fb backend, but I don't think cairo has one).

-jason


More information about the cairo mailing list