[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