[Xfce4-commits] [xfce/xfwm4] 01/01: icons: Use cairo for pixmaps and masks
noreply at xfce.org
noreply at xfce.org
Fri May 3 19:27:26 CEST 2019
This is an automated email from the git hooks/post-receive script.
o l i v i e r p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository xfce/xfwm4.
commit cdc02f928244a7f9bf40c2301b0085f7a03dc911
Author: Olivier Fourdan <fourdan at xfce.org>
Date: Fri May 3 19:24:22 2019 +0200
icons: Use cairo for pixmaps and masks
Update pixmap code to use cairo.
Copied from a similar fix for libwnck by Benjamin Otte <otte at redhat.com>
Signed-off-by: Olivier Fourdan <fourdan at xfce.org>
---
src/icons.c | 139 +++++++++++++++++++++++++-----------------------------------
1 file changed, 58 insertions(+), 81 deletions(-)
diff --git a/src/icons.c b/src/icons.c
index e547022..8612322 100644
--- a/src/icons.c
+++ b/src/icons.c
@@ -319,63 +319,14 @@ get_pixmap_geometry (Display *dpy, Pixmap pixmap, guint *out_width, guint *out_h
}
}
-static GdkPixbuf *
-apply_mask (GdkPixbuf * pixbuf, GdkPixbuf * mask)
-{
- GdkPixbuf *with_alpha;
- guchar *src;
- guchar *dest;
- guint w, h, i, j;
- guint src_stride, dest_stride;
- guint src_bpx, dest_bpx;
-
- 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);
-
- dest_bpx = dest_stride / gdk_pixbuf_get_width (with_alpha);
- src_bpx = src_stride / gdk_pixbuf_get_width (mask);
-
- if (G_UNLIKELY (dest_bpx != 4))
- {
- g_object_unref (with_alpha);
- g_return_val_if_reached (NULL);
- }
-
- i = 0;
- while (i < h)
- {
- j = 0;
- while (j < w)
- {
- guchar *s = src + i * src_stride + j * src_bpx;
- guchar *d = dest + i * dest_stride + j * dest_bpx;
- d[dest_bpx - 1] = s[src_bpx - 1];
- ++j;
- }
- ++i;
- }
-
- return with_alpha;
-}
-
-static GdkPixbuf *
-get_pixbuf_from_pixmap (ScreenInfo *screen_info, Pixmap xpixmap, guint width, guint height, guint depth)
+static cairo_surface_t *
+get_surface_from_pixmap (ScreenInfo *screen_info, Pixmap xpixmap, guint width, guint height, guint depth)
{
cairo_surface_t *surface;
- GdkPixbuf *retval;
#ifdef HAVE_COMPOSITOR
XRenderPictFormat *render_format;
#endif
- retval = NULL;
if (depth == 1)
{
surface = cairo_xlib_surface_create_for_bitmap (screen_info->display_info->dpy,
@@ -403,17 +354,7 @@ get_pixbuf_from_pixmap (ScreenInfo *screen_info, Pixmap xpixmap, guint width, gu
width, height);
}
- if (G_UNLIKELY(!surface))
- {
- /* Pixmap is gone ?? */
- return NULL;
- }
-
- retval = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
-
- cairo_surface_destroy (surface);
-
- return retval;
+ return surface;
}
static GdkPixbuf *
@@ -421,42 +362,78 @@ try_pixmap_and_mask (ScreenInfo *screen_info, Pixmap src_pixmap, Pixmap src_mask
{
GdkPixbuf *unscaled;
GdkPixbuf *icon;
- GdkPixbuf *mask;
guint w, h, depth;
+ cairo_surface_t *surface, *mask_surface, *image;
+ cairo_t *cr;
- if (src_pixmap == None)
+ if (G_UNLIKELY (src_pixmap == None))
{
return NULL;
}
- myDisplayErrorTrapPush (screen_info->display_info);
get_pixmap_geometry (myScreenGetXDisplay(screen_info), src_pixmap, &w, &h, &depth);
- unscaled = get_pixbuf_from_pixmap (screen_info, src_pixmap, w, h, depth);
- icon = NULL;
- mask = NULL;
+ surface = get_surface_from_pixmap (screen_info, src_pixmap, w, h, depth);
- if (depth > 1 && unscaled && src_mask)
+ if (surface && src_mask != None)
{
get_pixmap_geometry (myScreenGetXDisplay(screen_info), src_mask, &w, &h, &depth);
- mask = get_pixbuf_from_pixmap (screen_info, src_mask, w, h, depth);
+ mask_surface = get_surface_from_pixmap (screen_info, src_mask, w, h, depth);
+ }
+ else
+ {
+ mask_surface = NULL;
}
- myDisplayErrorTrapPopIgnored (screen_info->display_info);
- if (mask)
+ if (G_UNLIKELY (surface == NULL))
{
- GdkPixbuf *masked;
+ return NULL;
+ }
+ myDisplayErrorTrapPush (screen_info->display_info);
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
+ cr = cairo_create (image);
- masked = apply_mask (unscaled, mask);
+ /* 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 (mask_surface && cairo_surface_get_content (surface) & CAIRO_CONTENT_ALPHA)
+ {
+ cairo_push_group (cr);
- if (masked != NULL)
- {
- g_object_unref (G_OBJECT (unscaled));
- unscaled = 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);
- g_object_unref (G_OBJECT (mask));
- mask = NULL;
+ cairo_pop_group_to_source (cr);
}
+ else
+ {
+ cairo_set_source_surface (cr, surface, 0, 0);
+ }
+
+ if (mask_surface)
+ {
+ cairo_mask_surface (cr, mask_surface, 0, 0);
+ cairo_surface_destroy (mask_surface);
+ }
+ else
+ {
+ cairo_paint (cr);
+ }
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ if (myDisplayErrorTrapPop (screen_info->display_info) != Success)
+ {
+ cairo_surface_destroy (image);
+ return NULL;
+ }
+
+ unscaled = gdk_pixbuf_get_from_surface (image, 0, 0, w, h);
+ cairo_surface_destroy (image);
if (unscaled)
{
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list