[Xfce4-commits] [xfce/xfwm4] 18/32: Implement cairo drawing

noreply at xfce.org noreply at xfce.org
Tue Dec 5 09:22:04 CET 2017


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 c1b720f018f8942a361cf9ad68bf308161effa8d
Author: Viktor Odintsev <zakhams at gmail.com>
Date:   Mon Jul 3 15:25:22 2017 +0300

    Implement cairo drawing
---
 src/frame.c    |  41 ++++++++------
 src/mypixmap.c | 171 ++++++++++++++++++++++++++++++++-------------------------
 src/mypixmap.h |   3 +
 3 files changed, 123 insertions(+), 92 deletions(-)

diff --git a/src/frame.c b/src/frame.c
index ca0d511..19e5712 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -385,9 +385,8 @@ static void
 frameCreateTitlePixmap (Client * c, int state, int left, int right, xfwmPixmap * title_pm, xfwmPixmap * top_pm)
 {
     ScreenInfo *screen_info;
-    GdkPixmap *gpixmap;
-    GdkGCValues values;
-    GdkGC *gc;
+    cairo_surface_t *surface;
+    cairo_t *cr;
     PangoLayout *layout;
     PangoRectangle logical_rect;
     int width, x, hoffset, w1, w2, w3, w4, w5, temp;
@@ -536,9 +535,9 @@ frameCreateTitlePixmap (Client * c, int state, int left, int right, xfwmPixmap *
 
     xfwmPixmapCreate (screen_info, top_pm, width, top_height);
     xfwmPixmapCreate (screen_info, title_pm, width, frameTop (c));
-    gpixmap = gdk_pixmap_foreign_new (title_pm->pixmap);
-    gdk_drawable_set_colormap (gpixmap, gdk_screen_get_system_colormap (screen_info->gscr));
-    gc = gdk_gc_new (gpixmap);
+
+    surface = xfwmPixmapCreateSurface (title_pm, FALSE);
+    cr = cairo_create (surface);
 
     if (w1 > 0)
     {
@@ -553,25 +552,31 @@ frameCreateTitlePixmap (Client * c, int state, int left, int right, xfwmPixmap *
     {
         frameFillTitlePixmap (c, state, TITLE_3, x, w3, top_height, title_pm, top_pm);
         title_x = hoffset + x;
+        cairo_translate (cr, title_x, title_y);
         if (screen_info->params->title_shadow[state])
         {
-            gdk_gc_get_values (screen_info->title_shadow_colors[state].gc, &values);
-            gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND);
+            gdk_cairo_set_source_rgba (cr, &screen_info->title_shadow_colors[state]);
             if (screen_info->params->title_shadow[state] == TITLE_SHADOW_UNDER)
             {
-                gdk_draw_layout (gpixmap, gc, title_x + 1, title_y + 1, layout);
+                cairo_translate (cr, 1, 1);
+                pango_cairo_show_layout (cr, layout);
+                cairo_translate (cr, -1, -1);
             }
             else
             {
-                gdk_draw_layout (gpixmap, gc, title_x - 1, title_y, layout);
-                gdk_draw_layout (gpixmap, gc, title_x, title_y - 1, layout);
-                gdk_draw_layout (gpixmap, gc, title_x + 1, title_y, layout);
-                gdk_draw_layout (gpixmap, gc, title_x, title_y + 1, layout);
+                cairo_translate (cr, -1, 0);
+                pango_cairo_show_layout (cr, layout);
+                cairo_translate (cr, 1, -1);
+                pango_cairo_show_layout (cr, layout);
+                cairo_translate (cr, 1, 1);
+                pango_cairo_show_layout (cr, layout);
+                cairo_translate (cr, -1, 1);
+                pango_cairo_show_layout (cr, layout);
+                cairo_translate (cr, 0, -1);
             }
         }
-        gdk_gc_get_values (screen_info->title_colors[state].gc, &values);
-        gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND);
-        gdk_draw_layout (gpixmap, gc, title_x, title_y, layout);
+        gdk_cairo_set_source_rgba (cr, &screen_info->title_colors[state]);
+        pango_cairo_show_layout (cr, layout);
         x = x + w3;
     }
 
@@ -586,8 +591,8 @@ frameCreateTitlePixmap (Client * c, int state, int left, int right, xfwmPixmap *
     {
         frameFillTitlePixmap (c, state, TITLE_5, x, w5, top_height, title_pm, top_pm);
     }
-    g_object_unref (G_OBJECT (gc));
-    g_object_unref (G_OBJECT (gpixmap));
+    cairo_destroy (cr);
+    cairo_surface_destroy (surface);
     g_object_unref (G_OBJECT (layout));
 }
 
diff --git a/src/mypixmap.c b/src/mypixmap.c
index 0c51672..7d84e6f 100644
--- a/src/mypixmap.c
+++ b/src/mypixmap.c
@@ -42,6 +42,7 @@
 #include <glib/gstdio.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
+#include <cairo/cairo-xlib.h>
 #include <libxfce4util/libxfce4util.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -794,27 +795,21 @@ xfwmPixmapCompose (GdkPixbuf *pixbuf, const gchar * dir, const gchar * file)
 static gboolean
 xfwmPixmapDrawFromGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
 {
-    GdkPixmap *dest_pixmap;
-    GdkPixmap *dest_bitmap;
-    GdkVisual *gvisual;
-    GdkColormap *cmap;
+    cairo_surface_t *dest_pixmap;
+    cairo_surface_t *dest_bitmap;
+    cairo_t *cr;
     gint width, height;
     gint dest_x, dest_y;
-    gint alpha_threshold;
+    guchar *pixels;
+    gint dpx;
+    gboolean status, start_status;
+    gint x, y, start;
 
     g_return_val_if_fail (pm != NULL, FALSE);
     g_return_val_if_fail (pm->pixmap != None, FALSE);
     g_return_val_if_fail (pm->mask != None, FALSE);
 
-    dest_pixmap = gdk_xid_table_lookup (pm->pixmap);
-    if (dest_pixmap)
-    {
-        g_object_ref (G_OBJECT (dest_pixmap));
-    }
-    else
-    {
-        dest_pixmap = gdk_pixmap_foreign_new (pm->pixmap);
-    }
+    dest_pixmap = xfwmPixmapCreateSurface (pm, FALSE);
 
     if (!dest_pixmap)
     {
@@ -822,31 +817,12 @@ xfwmPixmapDrawFromGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
         return FALSE;
     }
 
-    dest_bitmap = gdk_xid_table_lookup (pm->mask);
-    if (dest_bitmap)
-    {
-        g_object_ref (G_OBJECT (dest_bitmap));
-    }
-    else
-    {
-        dest_bitmap = gdk_pixmap_foreign_new (pm->mask);
-    }
+    dest_bitmap = xfwmPixmapCreateSurface (pm, TRUE);
 
     if (!dest_bitmap)
     {
         g_warning ("Cannot get bitmap");
-        g_object_unref (dest_pixmap);
-        return FALSE;
-    }
-
-    gvisual = gdk_screen_get_system_visual (pm->screen_info->gscr);
-    cmap = gdk_x11_colormap_foreign_new (gvisual, pm->screen_info->cmap);
-
-    if (!cmap)
-    {
-        g_warning ("Cannot create colormap");
-        g_object_unref (dest_pixmap);
-        g_object_unref (dest_bitmap);
+        cairo_surface_destroy (dest_pixmap);
         return FALSE;
     }
 
@@ -855,18 +831,63 @@ xfwmPixmapDrawFromGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
     dest_x = (pm->width - width) / 2;
     dest_y = (pm->height - height) / 2;
 
-    gdk_drawable_set_colormap (GDK_DRAWABLE (dest_pixmap), cmap);
-    gdk_draw_pixbuf (GDK_DRAWABLE (dest_pixmap), NULL, pixbuf, 0, 0, dest_x, dest_y,
-                     width, height, GDK_RGB_DITHER_NONE, 0, 0);
+    cr = cairo_create (dest_pixmap);
+    gdk_cairo_set_source_pixbuf (cr, pixbuf, dest_x, dest_y);
+    cairo_paint (cr);
+    cairo_destroy (cr);
+
+    cr = cairo_create (dest_bitmap);
+    if (gdk_pixbuf_get_has_alpha (pixbuf) && width > 0)
+    {
+        /* draw alpha with threshold as gdk_pixbuf_render_threshold_alpha did before */
+
+        pixels = gdk_pixbuf_get_pixels (pixbuf);
+        dpx = gdk_pixbuf_get_rowstride (pixbuf) / gdk_pixbuf_get_width (pixbuf);
 
-    alpha_threshold = (gdk_pixbuf_get_has_alpha (pixbuf) ? 0xFF : 0);
-    gdk_pixbuf_render_threshold_alpha (pixbuf, dest_bitmap,
-                                       0, 0, dest_x, dest_y,
-                                       width, height, alpha_threshold);
+        cairo_translate (cr, dest_x, dest_y);
+        cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+        cairo_rectangle (cr, 0, 0, width, height);
+        cairo_fill (cr);
 
-    g_object_unref (cmap);
-    g_object_unref (dest_pixmap);
-    g_object_unref (dest_bitmap);
+        for (y = 0; y < height; y++)
+        {
+            start_status = FALSE;
+            start = 0;
+            for (x = 0; x < width; x++)
+            {
+                status = pixels[(y * width + x + 1) * dpx - 1] == 0xff;
+                if (status != start_status)
+                {
+                    if (!status)
+                    {
+                        /* draw line from previous start point to current point */
+                        cairo_rectangle (cr, start, y, x - start, 1);
+                    }
+                    start_status = status;
+                    start = x;
+                }
+            }
+            if (start_status)
+            {
+                /* draw finishing line */
+                cairo_rectangle (cr, start, y, width - start, 1);
+            }
+        }
+
+        cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+        cairo_set_source_rgba (cr, 0, 0, 0, 1);
+        cairo_fill (cr);
+    }
+    else
+    {
+        cairo_set_source_rgba (cr, 0, 0, 0, 1);
+        cairo_rectangle (cr, dest_x, dest_y, width, height);
+        cairo_fill (cr);
+    }
+    cairo_destroy (cr);
+
+    cairo_surface_destroy (dest_pixmap);
+    cairo_surface_destroy (dest_bitmap);
 
     return TRUE;
 }
@@ -875,9 +896,8 @@ gboolean
 xfwmPixmapRenderGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
 {
     GdkPixbuf *src;
-    GdkPixmap *destw;
-    GdkVisual *gvisual;
-    GdkColormap *cmap;
+    cairo_surface_t *surface;
+    cairo_t *cr;
     gint width, height;
     gint dest_x, dest_y;
 
@@ -885,32 +905,14 @@ xfwmPixmapRenderGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
     g_return_val_if_fail (pm->pixmap != None, FALSE);
     g_return_val_if_fail (pm->mask != None, FALSE);
 
-    destw = gdk_xid_table_lookup (pm->pixmap);
-    if (destw)
-    {
-        g_object_ref (G_OBJECT (destw));
-    }
-    else
-    {
-        destw = gdk_pixmap_foreign_new (pm->pixmap);
-    }
+    surface = xfwmPixmapCreateSurface (pm, FALSE);
 
-    if (!destw)
+    if (!surface)
     {
         g_warning ("Cannot get pixmap");
         return FALSE;
     }
 
-    gvisual = gdk_screen_get_system_visual (pm->screen_info->gscr);
-    cmap = gdk_x11_colormap_foreign_new (gvisual, pm->screen_info->cmap);
-
-    if (!cmap)
-    {
-        g_warning ("Cannot create colormap");
-        g_object_unref (destw);
-        return FALSE;
-    }
-
     width = MIN (gdk_pixbuf_get_width (pixbuf), pm->width);
     height = MIN (gdk_pixbuf_get_height (pixbuf), pm->height);
 
@@ -918,16 +920,16 @@ xfwmPixmapRenderGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
     dest_x = (pm->width - width + 1) / 2;
     dest_y = (pm->height - height + 1) / 2;
 
-    src = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE (destw), cmap,
-                                        dest_x, dest_y, 0, 0, width, height);
+    src = gdk_pixbuf_get_from_surface (surface, dest_x, dest_y, width, height);
     gdk_pixbuf_composite (pixbuf, src, 0, 0, width, height,
                           0, 0, 1.0, 1.0, GDK_INTERP_BILINEAR, 0xFF);
-    gdk_draw_pixbuf (GDK_DRAWABLE (destw), NULL, src, 0, 0, dest_x, dest_y,
-                     width, height, GDK_RGB_DITHER_NONE, 0, 0);
+    cr = cairo_create (surface);
+    gdk_cairo_set_source_pixbuf (cr, pixbuf, dest_x, dest_y);
+    cairo_paint (cr);
 
-    g_object_unref (cmap);
     g_object_unref (src);
-    g_object_unref (destw);
+    cairo_destroy (cr);
+    cairo_surface_destroy (surface);
 
     return TRUE;
 }
@@ -1124,3 +1126,24 @@ xfwmPixmapDuplicate (xfwmPixmap * src, xfwmPixmap * dst)
     xfwmPixmapCreate (src->screen_info, dst, src->width, src->height);
     xfwmPixmapFill (src, dst, 0, 0, src->width, src->height);
 }
+
+cairo_surface_t *
+xfwmPixmapCreateSurface (xfwmPixmap *pm, gboolean bitmap)
+{
+    g_return_val_if_fail (pm != NULL, NULL);
+
+    if (bitmap)
+    {
+        return cairo_xlib_surface_create_for_bitmap (pm->screen_info->display_info->dpy,
+                                                     pm->mask,
+                                                     pm->screen_info->xscreen,
+                                                     pm->width, pm->height);
+    }
+    else
+    {
+        return cairo_xlib_surface_create (pm->screen_info->display_info->dpy,
+                                          pm->pixmap,
+                                          pm->screen_info->visual,
+                                          pm->width, pm->height);
+    }
+}
diff --git a/src/mypixmap.h b/src/mypixmap.h
index 19302bc..1b05cfa 100644
--- a/src/mypixmap.h
+++ b/src/mypixmap.h
@@ -26,6 +26,7 @@
 #endif
 
 #include <glib.h>
+#include <cairo/cairo.h>
 #include "screen.h"
 
 #ifdef HAVE_RENDER
@@ -78,4 +79,6 @@ void                     xfwmPixmapFill                         (xfwmPixmap *,
                                                                  gint);
 void                     xfwmPixmapDuplicate                    (xfwmPixmap *,
                                                                  xfwmPixmap *);
+cairo_surface_t         *xfwmPixmapCreateSurface                (xfwmPixmap *,
+                                                                 gboolean);
 #endif /* INC_MYPIXMAP_H */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list