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