Re: Problem displaying image with alpha channel in a transparent window
- From: Yann Droneaud <ydroneaud mandriva com>
- To: gtk-app-devel-list gnome org, gtk-list <gtk-list gnome org>
- Subject: Re: Problem displaying image with alpha channel in a transparent window
- Date: Wed, 23 Jul 2008 17:42:27 +0200
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 <ydroneaud mandriva com>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]