[libwnck] xutils: Rewrite pixmap + mak icon reading code to use cairo
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libwnck] xutils: Rewrite pixmap + mak icon reading code to use cairo
- Date: Wed, 19 Jan 2011 20:47:24 +0000 (UTC)
commit 1876b761d070aef3d4cbde45c8cde549b57533ee
Author: Benjamin Otte <otte redhat com>
Date: Wed Jan 19 21:45:40 2011 +0100
xutils: Rewrite pixmap + mak icon reading code to use cairo
The previous code was hard-coded to assume certain alpha values. And
those values weren't always correct. In particular, the new GTK3 code
violated the assumptions.
The new code can cope with any alpha combination.
libwnck/xutils.c | 112 +++++++++++++++++++++++------------------------------
1 files changed, 49 insertions(+), 63 deletions(-)
---
diff --git a/libwnck/xutils.c b/libwnck/xutils.c
index 6e7a188..7213be7 100644
--- a/libwnck/xutils.c
+++ b/libwnck/xutils.c
@@ -1568,55 +1568,6 @@ free_pixels (guchar *pixels, gpointer data)
g_free (pixels);
}
-static GdkPixbuf*
-apply_mask (GdkPixbuf *pixbuf,
- GdkPixbuf *mask)
-{
- int w, h;
- int i, j;
- GdkPixbuf *with_alpha;
- guchar *src;
- guchar *dest;
- int src_stride;
- int dest_stride;
-
- w = MIN (gdk_pixbuf_get_width (mask), gdk_pixbuf_get_width (pixbuf));
- h = MIN (gdk_pixbuf_get_height (mask), gdk_pixbuf_get_height (pixbuf));
-
- with_alpha = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
-
- dest = gdk_pixbuf_get_pixels (with_alpha);
- src = gdk_pixbuf_get_pixels (mask);
-
- dest_stride = gdk_pixbuf_get_rowstride (with_alpha);
- src_stride = gdk_pixbuf_get_rowstride (mask);
-
- i = 0;
- while (i < h)
- {
- j = 0;
- while (j < w)
- {
- guchar *s = src + i * src_stride + j * 3;
- guchar *d = dest + i * dest_stride + j * 4;
-
- /* s[0] == s[1] == s[2], they are 255 if the bit was set, 0
- * otherwise
- */
- if (s[0] == 0)
- d[3] = 0; /* transparent */
- else
- d[3] = 255; /* opaque */
-
- ++j;
- }
-
- ++i;
- }
-
- return with_alpha;
-}
-
static cairo_surface_t *
_wnck_cairo_surface_get_from_pixmap (Pixmap xpixmap)
{
@@ -1686,35 +1637,70 @@ try_pixmap_and_mask (Pixmap src_pixmap,
int ideal_mini_width,
int ideal_mini_height)
{
- GdkPixbuf *unscaled = NULL;
- GdkPixbuf *mask = NULL;
+ cairo_surface_t *surface, *mask_surface, *image;
+ GdkPixbuf *unscaled;
+ int width, height;
+ cairo_t *cr;
if (src_pixmap == None)
return FALSE;
_wnck_error_trap_push ();
- unscaled = _wnck_gdk_pixbuf_get_from_pixmap (src_pixmap);
+ surface = _wnck_cairo_surface_get_from_pixmap (src_pixmap);
- if (unscaled && src_mask != None)
- {
- mask = _wnck_gdk_pixbuf_get_from_pixmap (src_mask);
- }
+ if (surface && src_mask != None)
+ mask_surface = _wnck_cairo_surface_get_from_pixmap (src_mask);
_wnck_error_trap_pop ();
- if (mask)
+ if (surface == NULL)
+ return FALSE;
+
+ width = cairo_xlib_surface_get_width (surface);
+ height = cairo_xlib_surface_get_height (surface);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ width, height);
+ cr = cairo_create (image);
+
+ /* Need special code for alpha-only surfaces. We only get those
+ * for bitmaps. And in that case, it's a differentiation between
+ * foreground (white) and background (black).
+ */
+ if (cairo_surface_get_content (surface) & CAIRO_CONTENT_ALPHA)
{
- GdkPixbuf *masked;
+ /* black background */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+ /* mask with white foreground */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_mask_surface (cr, surface, 0, 0);
+ }
+ else
+ {
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ }
- masked = apply_mask (unscaled, mask);
- g_object_unref (G_OBJECT (unscaled));
- unscaled = masked;
+ cairo_surface_destroy (surface);
- g_object_unref (G_OBJECT (mask));
- mask = NULL;
+ if (mask_surface)
+ {
+ cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
+ cairo_set_source_surface (cr, mask_surface, 0, 0);
+ cairo_paint (cr);
+ cairo_surface_destroy (mask_surface);
}
+ cairo_destroy (cr);
+
+ unscaled = gdk_pixbuf_get_from_surface (image,
+ 0, 0,
+ width, height);
+
+ cairo_surface_destroy (image);
+
if (unscaled)
{
*iconp =
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]