[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 14:18:34 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit a55e38a9f8a54580303d59bc2d499bdbb29a5e0c
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Oct 6 16:52:44 2010 +0000

    2010-10-06  Carlos Garcia Campos  <cgarcia at igalia.com>
    
            Reviewed by Xan Lopez.
    
            [GTK] Use pixbufs instead of pixmaps when creating platform cursors
            https://bugs.webkit.org/show_bug.cgi?id=47087
    
            gdk_cursor_new_from_pixmap() has been removed in gtk3. We can use a
            pixbuf instead of a pixman and use gdk_cursor_new_from_pixbuf() instead
            for both gtk2 and gtk3.
    
            * platform/gtk/CursorGtk.cpp:
            (WebCore::createNamedCursor):
            * platform/gtk/GtkVersioning.c:
            (gdk_cairo_format_for_content):
            (gdk_cairo_surface_coerce_to_image):
            (convert_alpha):
            (convert_no_alpha):
            (gdk_pixbuf_get_from_surface):
            * platform/gtk/GtkVersioning.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69204 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e3504fd..ebe05bf 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2010-10-06  Carlos Garcia Campos  <cgarcia at igalia.com>
+
+        Reviewed by Xan Lopez.
+
+        [GTK] Use pixbufs instead of pixmaps when creating platform cursors
+        https://bugs.webkit.org/show_bug.cgi?id=47087
+
+        gdk_cursor_new_from_pixmap() has been removed in gtk3. We can use a
+        pixbuf instead of a pixman and use gdk_cursor_new_from_pixbuf() instead
+        for both gtk2 and gtk3.
+
+        * platform/gtk/CursorGtk.cpp:
+        (WebCore::createNamedCursor):
+        * platform/gtk/GtkVersioning.c:
+        (gdk_cairo_format_for_content):
+        (gdk_cairo_surface_coerce_to_image):
+        (convert_alpha):
+        (convert_no_alpha):
+        (gdk_pixbuf_get_from_surface):
+        * platform/gtk/GtkVersioning.h:
+
 2010-10-06  Pavel Podivilov  <podivilov at chromium.org>
 
         Reviewed by Yury Semikhatsky.
diff --git a/WebCore/platform/gtk/CursorGtk.cpp b/WebCore/platform/gtk/CursorGtk.cpp
index d1f1293..9971bfb 100644
--- a/WebCore/platform/gtk/CursorGtk.cpp
+++ b/WebCore/platform/gtk/CursorGtk.cpp
@@ -28,28 +28,17 @@
 
 #include "config.h"
 #include "CursorGtk.h"
+#include "GtkVersioning.h"
 
 #include "Image.h"
 #include "IntPoint.h"
+#include "PlatformRefPtrCairo.h"
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 #include <wtf/Assertions.h>
 
 namespace WebCore {
 
-static GdkPixmap* createPixmapFromBits(const unsigned char* bits, const IntSize& size)
-{
-    cairo_surface_t* dataSurface = cairo_image_surface_create_for_data(const_cast<unsigned char*>(bits), CAIRO_FORMAT_A1, size.width(), size.height(), size.width() / 8);
-    GdkPixmap* pixmap = gdk_pixmap_new(0, size.width(), size.height(), 1);
-    cairo_t* cr = gdk_cairo_create(pixmap);
-    cairo_set_source_surface(cr, dataSurface, 0, 0);
-    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-    cairo_paint(cr);
-    cairo_destroy(cr);
-    cairo_surface_destroy(dataSurface);
-    return pixmap;
-}
-
 static PlatformRefPtr<GdkCursor> createNamedCursor(CustomCursorType cursorType)
 {
     CustomCursor cursor = CustomCursors[cursorType];
@@ -57,12 +46,17 @@ static PlatformRefPtr<GdkCursor> createNamedCursor(CustomCursorType cursorType)
     if (c)
         return c;
 
-    const GdkColor fg = { 0, 0, 0, 0 };
-    const GdkColor bg = { 65535, 65535, 65535, 65535 };
     IntSize cursorSize = IntSize(32, 32);
-    PlatformRefPtr<GdkPixmap> source = adoptPlatformRef(createPixmapFromBits(cursor.bits, cursorSize));
-    PlatformRefPtr<GdkPixmap> mask = adoptPlatformRef(createPixmapFromBits(cursor.mask_bits, cursorSize));
-    return adoptPlatformRef(gdk_cursor_new_from_pixmap(source.get(), mask.get(), &fg, &bg, cursor.hot_x, cursor.hot_y));
+    PlatformRefPtr<cairo_surface_t> source = adoptPlatformRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.bits), CAIRO_FORMAT_A1, 32, 32, 4));
+    PlatformRefPtr<cairo_surface_t> mask = adoptPlatformRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.mask_bits), CAIRO_FORMAT_A1, 32, 32, 4));
+    PlatformRefPtr<cairo_surface_t> surface = adoptPlatformRef(cairo_image_surface_create(CAIRO_FORMAT_A1, 32, 32));
+    PlatformRefPtr<cairo_t> cr = adoptPlatformRef(cairo_create(surface.get()));
+
+    cairo_set_source_surface(cr.get(), source.get(), cursor.hot_x, cursor.hot_y);
+    cairo_mask_surface(cr.get(), mask.get(), cursor.hot_x, cursor.hot_y);
+
+    PlatformRefPtr<GdkPixbuf> pixbuf = adoptPlatformRef(gdk_pixbuf_get_from_surface(surface.get(), 0, 0, 32, 32));
+    return adoptPlatformRef(gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf.get(), 0, 0));
 }
 
 static PlatformRefPtr<GdkCursor> createCustomCursor(Image* image, const IntPoint& hotSpot)
diff --git a/WebCore/platform/gtk/GtkVersioning.c b/WebCore/platform/gtk/GtkVersioning.c
index b5d0c25..071c5e5 100644
--- a/WebCore/platform/gtk/GtkVersioning.c
+++ b/WebCore/platform/gtk/GtkVersioning.c
@@ -98,3 +98,166 @@ const gchar* gtk_menu_item_get_label(GtkMenuItem* menuItem)
     return 0;
 }
 #endif // GTK_CHECK_VERSION(2, 16, 0)
+
+#ifdef GTK_API_VERSION_2
+static cairo_format_t
+gdk_cairo_format_for_content(cairo_content_t content)
+{
+    switch (content) {
+    case CAIRO_CONTENT_COLOR:
+        return CAIRO_FORMAT_RGB24;
+    case CAIRO_CONTENT_ALPHA:
+        return CAIRO_FORMAT_A8;
+    case CAIRO_CONTENT_COLOR_ALPHA:
+    default:
+        return CAIRO_FORMAT_ARGB32;
+    }
+}
+
+static cairo_surface_t*
+gdk_cairo_surface_coerce_to_image(cairo_surface_t* surface,
+                                  cairo_content_t content,
+                                  int width,
+                                  int height)
+{
+    cairo_surface_t * copy;
+    cairo_t * cr;
+
+    if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE
+        && cairo_surface_get_content(surface) == content
+        && cairo_image_surface_get_width(surface) >= width
+        && cairo_image_surface_get_height(surface) >= height)
+        return cairo_surface_reference(surface);
+
+    copy = cairo_image_surface_create(gdk_cairo_format_for_content(content),
+                                      width,
+                                      height);
+
+    cr = cairo_create(copy);
+    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+    cairo_set_source_surface(cr, surface, 0, 0);
+    cairo_paint(cr);
+    cairo_destroy(cr);
+
+    return copy;
+}
+
+static void
+convert_alpha(guchar * destData, int destStride,
+              guchar * srcData, int srcStride,
+              int srcX, int srcY, int width, int height)
+{
+    int x, y;
+
+    srcData += srcStride * srcY + srcY * 4;
+
+    for (y = 0; y < height; y++) {
+        guint32 * src = (guint32 *) srcData;
+
+        for (x = 0; x < width; x++) {
+            guint alpha = src[x] >> 24;
+
+            if (!alpha) {
+                destData[x * 4 + 0] = 0;
+                destData[x * 4 + 1] = 0;
+                destData[x * 4 + 2] = 0;
+            } else {
+                destData[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+                destData[x * 4 + 1] = (((src[x] & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
+                destData[x * 4 + 2] = (((src[x] & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
+            }
+            destData[x * 4 + 3] = alpha;
+        }
+
+        srcData += srcStride;
+        destData += destStride;
+    }
+}
+
+static void
+convert_no_alpha(guchar * destData, int destStride, guchar * srcData,
+                 int srcStride, int srcX, int srcY,
+                 int width, int height)
+{
+    int x, y;
+
+    srcData += srcStride * srcY + srcX * 4;
+
+    for (y = 0; y < height; y++) {
+        guint32 * src = (guint32 *) srcData;
+
+        for (x = 0; x < width; x++) {
+            destData[x * 3 + 0] = src[x] >> 16;
+            destData[x * 3 + 1] = src[x] >>  8;
+            destData[x * 3 + 2] = src[x];
+        }
+
+        srcData += srcStride;
+        destData += destStride;
+    }
+}
+
+/**
+ * gdk_pixbuf_get_from_surface:
+ * @surface: surface to copy from
+ * @src_x: Source X coordinate within @surface
+ * @src_y: Source Y coordinate within @surface
+ * @width: Width in pixels of region to get
+ * @height: Height in pixels of region to get
+ *
+ * Transfers image data from a #cairo_surface_t and converts it to an RGB(A)
+ * representation inside a #GdkPixbuf. This allows you to efficiently read
+ * individual pixels from cairo surfaces. For #GdkWindows, use
+ * gdk_pixbuf_get_from_window() instead.
+ *
+ * This function will create an RGB pixbuf with 8 bits per channel. The pixbuf
+ * will contain an alpha channel if the @surface contains one.
+ *
+ * Return value: (transfer full): A newly-created pixbuf with a reference count
+ * of 1, or %NULL on error
+ **/
+GdkPixbuf*
+gdk_pixbuf_get_from_surface(cairo_surface_t * surface,
+                            int srcX, int srcY,
+                            int width, int height)
+{
+    cairo_content_t content;
+    GdkPixbuf * dest;
+
+    /* General sanity checks */
+    g_return_val_if_fail(!surface, NULL);
+    g_return_val_if_fail(srcX >= 0 && srcY >= 0, NULL);
+    g_return_val_if_fail(width > 0 && height > 0, NULL);
+
+    content = cairo_surface_get_content(surface) | CAIRO_CONTENT_COLOR;
+    dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+                          !!(content & CAIRO_CONTENT_ALPHA),
+                          8,
+                          width, height);
+
+    surface = gdk_cairo_surface_coerce_to_image(surface, content, srcX + width, srcY + height);
+    cairo_surface_flush(surface);
+    if (cairo_surface_status(surface) || !dest) {
+        cairo_surface_destroy(surface);
+        return NULL;
+    }
+
+    if (gdk_pixbuf_get_has_alpha(dest))
+        convert_alpha(gdk_pixbuf_get_pixels(dest),
+                       gdk_pixbuf_get_rowstride(dest),
+                       cairo_image_surface_get_data(surface),
+                       cairo_image_surface_get_stride(surface),
+                       srcX, srcY,
+                       width, height);
+    else
+        convert_no_alpha(gdk_pixbuf_get_pixels(dest),
+                          gdk_pixbuf_get_rowstride(dest),
+                          cairo_image_surface_get_data(surface),
+                          cairo_image_surface_get_stride(surface),
+                          srcX, srcY,
+                          width, height);
+
+    cairo_surface_destroy(surface);
+    return dest;
+}
+#endif // GTK_API_VERSION_2
diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h
index 02eeb00..1ffcb3a 100644
--- a/WebCore/platform/gtk/GtkVersioning.h
+++ b/WebCore/platform/gtk/GtkVersioning.h
@@ -32,6 +32,9 @@ G_BEGIN_DECLS
 // Macros to avoid deprecation checking churn
 #ifndef GTK_API_VERSION_2
 #define GDK_DISPLAY() (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()))
+#else
+GdkPixbuf* gdk_pixbuf_get_from_surface(cairo_surface_t* surface, int srcX, int srcY,
+                                       int width, int height);
 #endif
 
 #if !GTK_CHECK_VERSION(2, 24, 0)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list