Le mercredi 23 juillet 2008 à 10:38 +0200, Yann Droneaud a écrit :
> Hi,
> 
> I'm trying to write a program to display a picture with full
> transparency in its own window (without border), using Composite
> extension (ARGB colormap and visual).
> 

Using Cairo correctly (e.g. using operator CAIRO_OPERATOR_SOURCE) fixes
my problems, see below.

> So here are my little demonstration programs
> 
> - test-gdkpixbuf.c : 
> 
>   This program does the following:
>   - looks up the RGBA colormap with gdk_screen_get_rgba_colormap()
>   - installs the colormap with gtk_widget_set_default_colormap()
>   - creates a GdkPixbuf with gdk_pixbuf_new_from_file()
>   - creates a GtkWindow
>   - sets the widget as GTK_APP_PAINTABLE with  
>     gtk_widget_set_app_paintable()
>   - disables double buffering with gtk_widget_set_double_buffered()
>   - in the realize signal handler, it removes any background pixmap 
>     using gdk_window_set_back_pixmap()
>   - in the expose event handler, it draws the GdkPixBuf using
>     gdk_draw_pixbuf()
> 

Problem:

- gdk_draw_pixbuf() seems to use Cairo with operator CAIRO_OPERATOR_OVER
  so it composes the GdkPixbuf with the background of the window (or 
  the content of the root window, if it has no background).

Two way to fix:

Fill the window with a black, full transparency content before 
calling gdk_draw_pixbuf(): in expose_event():

    ...  
    cairo_t *cr = gdk_cairo_create(widget->window);
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
    cairo_paint(cr);
    cairo_destroy(cr);
 
    gdk_draw_pixbuf(widget->window,
    ...

Or, better, use gdk_cairo_set_source_pixbuf() instead of 
gdk_draw_pixbuf():

    ...
    cairo_t *cr = gdk_cairo_create(widget->window);
    gdk_cairo_region(cr, event->region);    
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    
    gdk_cairo_set_source_pixbuf(cr, pixbuf, 0.0, 0.0);
    cairo_paint(cr);
    cairo_destroy(cr);
    ...

Here, I was using CAIRO_OPERATOR_OVER in my first tests, so the 
results were the same than with gdk_draw_pixbuf(). My mistake.

Fixed program is test-gdkpixbuf-cairo.c

> - test-gdkpixbuf-bg.patch:
>   
>   Apply the patch on top of test-gdkpixbuf.c to create 
>   test-gdkpixbuf-background.c
>   This patch set a pixmap as a background, and draw nothing on the 
>   window. Only the realize signal and expose event handlers are 
>   modified:
>   - realize signal handler creates a new pixmap with gdk_pixmap_new(),
>     writes the content of the GdkPixBuf with gdk_draw_pixbuf() and then
>     install the background with gdk_window_set_back_pixmap().
>   - expose event handler only call to gdk_window_clear()
> 

Problems:
- gdk_create_pixmap() returns a GdkPixmap with undefined content
- gdk_draw_pixbuf() composes the GdkPixbuf's content with the 
     undefined content of the GdkPixmap

  See my post[1] titled "There's something in my pixmap".

Same fixes two can be applied here: either initialize the content of the
drawable before calling gdk_draw_pixbuf(), either use only cairo to 
draw the GdkPixbuf with the correct operator: CAIRO_OPERATOR_SOURCE.

Remark: I'm still interested in a version using only GDK drawing
functions and no Cairo functions.

Regards.

[1] http://mail.gnome.org/archives/gtk-list/2008-July/msg00107.html

-- 
Yann Droneaud <[EMAIL PROTECTED]>

_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to