compilerplugins/clang/reservedid.cxx |    2 
 vcl/unx/gtk3/gtkinst.cxx             |  125 ++++++++++++++++++++++++++---------
 2 files changed, 98 insertions(+), 29 deletions(-)

New commits:
commit d132982667d0e8112e7cf9f5cc39323ec7be5068
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu May 27 16:20:12 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Thu May 27 21:09:46 2021 +0200

    gtk4: continue to provide Paintable via cairo surface
    
    instead of squeezing through a GdkTexture and losing hidpi surfaces
    
    Change-Id: I1ee75ff804d1d769273e2f80335bfdf528ae8039
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116267
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/compilerplugins/clang/reservedid.cxx 
b/compilerplugins/clang/reservedid.cxx
index 3f019a10d830..169942f9c392 100644
--- a/compilerplugins/clang/reservedid.cxx
+++ b/compilerplugins/clang/reservedid.cxx
@@ -207,6 +207,8 @@ bool ReservedId::VisitNamedDecl(NamedDecl const * decl) {
             && s != "_GstVideoOverlay"
                 // avmedia/source/gstreamer/gstplayer.hxx
             && s != "_Module" // extensions/source/activex/StdAfx2.h, 
CComModule
+            && s != "_SurfacePaintable" // vcl/unx/gtk3/gtkinst.cxx
+            && s != "_SurfacePaintableClass" // vcl/unx/gtk3/gtkinst.cxx
             && s != "_XRegion" // vcl/unx/generic/gdi/x11cairotextrender.cxx
             && s != "_XTrap") // vcl/unx/generic/gdi/xrender_peer.hxx
         {
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 4fd5e509fa1f..6ba181f8564f 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -3981,48 +3981,115 @@ namespace
 #endif
         return pixbuf;
     }
+}
 
 #if GTK_CHECK_VERSION(4, 0, 0)
-    GdkTexture* texture_new_from_virtual_device(const VirtualDevice& 
rImageSurface)
+
+G_BEGIN_DECLS
+
+G_DECLARE_FINAL_TYPE(SurfacePaintable, surface_paintable, SURFACE, PAINTABLE, 
GObject)
+
+struct _SurfacePaintable
+{
+    GObject parent_instance;
+    int width;
+    int height;
+    cairo_surface_t* surface;
+};
+
+struct _SurfacePaintableClass
+{
+    GObjectClass parent_class;
+};
+
+static void surface_paintable_snapshot(GdkPaintable *paintable, GdkSnapshot 
*snapshot,
+                                       double width, double height)
+{
+    graphene_rect_t rect = GRAPHENE_RECT_INIT(0.0f, 0.0f,
+                                              static_cast<float>(width),
+                                              static_cast<float>(height));
+    SurfacePaintable *self = SURFACE_PAINTABLE(paintable);
+    cairo_t* cr = gtk_snapshot_append_cairo(GTK_SNAPSHOT(snapshot), &rect);
+    cairo_set_source_surface(cr, self->surface, 0, 0);
+    cairo_paint(cr);
+    cairo_destroy(cr);
+}
+
+static int surface_paintable_get_intrinsic_width(GdkPaintable *paintable)
+{
+    SurfacePaintable *self = SURFACE_PAINTABLE(paintable);
+    return self->width;
+}
+
+static int surface_paintable_get_intrinsic_height(GdkPaintable *paintable)
+{
+    SurfacePaintable *self = SURFACE_PAINTABLE(paintable);
+    return self->height;
+}
+
+static void surface_paintable_init_interface(GdkPaintableInterface *iface)
+{
+    iface->snapshot = surface_paintable_snapshot;
+    iface->get_intrinsic_width = surface_paintable_get_intrinsic_width;
+    iface->get_intrinsic_height = surface_paintable_get_intrinsic_height;
+}
+
+G_DEFINE_TYPE_WITH_CODE(SurfacePaintable, surface_paintable, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(GDK_TYPE_PAINTABLE,
+                                              
surface_paintable_init_interface));
+
+static void surface_paintable_init(SurfacePaintable *self)
+{
+    self->width = 0;
+    self->height = 0;
+    self->surface = nullptr;
+}
+
+static void surface_paintable_dispose(GObject *object)
+{
+    SurfacePaintable* self = SURFACE_PAINTABLE(object);
+    cairo_surface_destroy(self->surface);
+    G_OBJECT_CLASS(surface_paintable_parent_class)->dispose(object);
+}
+
+static void surface_paintable_class_init(SurfacePaintableClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    object_class->dispose = surface_paintable_dispose;
+}
+
+G_END_DECLS
+
+#endif
+
+namespace
+{
+#if GTK_CHECK_VERSION(4, 0, 0)
+    SurfacePaintable* paintable_new_from_virtual_device(const VirtualDevice& 
rImageSurface)
     {
         cairo_surface_t* surface = get_underlying_cairo_surface(rImageSurface);
 
         Size aSize(rImageSurface.GetOutputSizePixel());
-
-        // seems unfortunately to lose the potentially hidpi image here
-        cairo_surface_t* target = cairo_surface_create_similar_image(surface,
-                                                                     
CAIRO_FORMAT_ARGB32,
-                                                                     
aSize.Width(),
-                                                                     
aSize.Height());
-
+        cairo_surface_t* target = cairo_surface_create_similar(surface,
+                                                               
cairo_surface_get_content(surface),
+                                                               aSize.Width(),
+                                                               aSize.Height());
         cairo_t* cr = cairo_create(target);
         cairo_set_source_surface(cr, surface, 0, 0);
         cairo_paint(cr);
         cairo_destroy(cr);
 
-        GBytes* bytes = 
g_bytes_new_with_free_func(cairo_image_surface_get_data(target),
-                                                   
cairo_image_surface_get_height(target) *
-                                                   
cairo_image_surface_get_stride(target),
-                                                   
reinterpret_cast<GDestroyNotify>(cairo_surface_destroy),
-                                                   
cairo_surface_reference(target));
-
-        GdkTexture* texture = 
gdk_memory_texture_new(cairo_image_surface_get_width(target),
-                                                     
cairo_image_surface_get_height(target),
-                                                     GDK_MEMORY_DEFAULT,
-                                                     bytes,
-                                                     
cairo_image_surface_get_stride(target));
-
-        g_bytes_unref (bytes);
-
-        cairo_surface_destroy(target);
-
-        return texture;
+        SurfacePaintable* pPaintable = 
SURFACE_PAINTABLE(g_object_new(surface_paintable_get_type(), nullptr));
+        pPaintable->surface = target;
+        pPaintable->width = aSize.Width();
+        pPaintable->height = aSize.Height();
+        return pPaintable;
     }
 
     GtkWidget* image_new_from_virtual_device(const VirtualDevice& 
rImageSurface)
     {
-        GdkTexture* texture = texture_new_from_virtual_device(rImageSurface);
-        return gtk_image_new_from_paintable(GDK_PAINTABLE(texture));
+        SurfacePaintable* paintable = 
paintable_new_from_virtual_device(rImageSurface);
+        return gtk_image_new_from_paintable(GDK_PAINTABLE(paintable));
     }
 #else
     GtkWidget* image_new_from_virtual_device(const VirtualDevice& 
rImageSurface)
@@ -4049,7 +4116,7 @@ namespace
     void image_set_from_virtual_device(GtkImage* pImage, const VirtualDevice* 
pDevice)
     {
 #if GTK_CHECK_VERSION(4, 0, 0)
-        gtk_image_set_from_paintable(pImage, pDevice ? 
GDK_PAINTABLE(texture_new_from_virtual_device(*pDevice)) : nullptr);
+        gtk_image_set_from_paintable(pImage, pDevice ? 
GDK_PAINTABLE(paintable_new_from_virtual_device(*pDevice)) : nullptr);
 #else
         gtk_image_set_from_surface(pImage, pDevice ? 
get_underlying_cairo_surface(*pDevice) : nullptr);
 #endif
@@ -10493,7 +10560,7 @@ public:
         if (!pDevice)
             gtk_picture_set_paintable(m_pPicture, nullptr);
         else
-            gtk_picture_set_paintable(m_pPicture, 
GDK_PAINTABLE(texture_new_from_virtual_device(*pDevice)));
+            gtk_picture_set_paintable(m_pPicture, 
GDK_PAINTABLE(paintable_new_from_virtual_device(*pDevice)));
     }
 
     virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& 
rPicture) override
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to