summaryrefslogtreecommitdiffstats
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-03-18 09:57:41 +0000
committerCaolán McNamara <caolanm@redhat.com>2015-03-23 12:45:26 +0000
commit707a8bc1e47b57421412de3f1f47ec31be28c5a9 (patch)
tree4b353cca36ddb831a8f5b46608c2891571cb8a1b /vcl
parentmove cairo helpers to vcl and make per-plug (diff)
downloadcore-707a8bc1e47b57421412de3f1f47ec31be28c5a9.tar.gz
core-707a8bc1e47b57421412de3f1f47ec31be28c5a9.zip
enable gtk3 to support cairo canvas
Change-Id: Ie6edf155288d1514ce7a0c859ba751cdebc93391
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vclplug_gtk3.mk1
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx2
-rw-r--r--vcl/inc/unx/gtk/gtkgdi.hxx7
-rw-r--r--vcl/unx/gtk/window/gtksalframe.cxx12
-rw-r--r--vcl/unx/gtk3/gdi/cairo_gtk3_cairo.cxx117
-rw-r--r--vcl/unx/gtk3/gdi/cairo_gtk3_cairo.hxx51
-rw-r--r--vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx24
7 files changed, 208 insertions, 6 deletions
diff --git a/vcl/Library_vclplug_gtk3.mk b/vcl/Library_vclplug_gtk3.mk
index 5ba57227de16..515a81c1fdea 100644
--- a/vcl/Library_vclplug_gtk3.mk
+++ b/vcl/Library_vclplug_gtk3.mk
@@ -102,6 +102,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\
vcl/unx/gtk3/app/gtk3gtkinst \
vcl/unx/gtk3/app/gtk3gtksys \
vcl/unx/gtk3/app/gtk3fpicker \
+ vcl/unx/gtk3/gdi/cairo_gtk3_cairo \
vcl/unx/gtk3/gdi/gtk3cairotextrender \
vcl/unx/gtk3/gdi/gtk3gtkprintwrapper \
vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk \
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 56225ccf1fec..d5148b757dff 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -343,7 +343,7 @@ public:
#if GTK_CHECK_VERSION(3,0,0)
// only for gtk3 ...
- cairo_t* getCairoContext();
+ cairo_t* getCairoContext() const;
void damaged (const basegfx::B2IBox& rDamageRect);
#endif
virtual ~GtkSalFrame();
diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index 26f2efba05b9..2c8a8dcfc420 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -49,11 +49,16 @@ public:
const OUString& rCaption,
Rectangle &rNativeBoundingRegion,
Rectangle &rNativeContentRegion ) SAL_OVERRIDE;
+ virtual bool SupportsCairo() const SAL_OVERRIDE;
+ virtual cairo::SurfaceSharedPtr CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const SAL_OVERRIDE;
+ virtual cairo::SurfaceSharedPtr CreateSurface(const OutputDevice& rRefDevice, int x, int y, int width, int height) const SAL_OVERRIDE;
+ void WidgetQueueDraw() const;
+
void updateSettings( AllSettings& rSettings );
static void refreshFontconfig( GtkSettings *pSettings );
static void signalSettingsNotify( GObject*, GParamSpec *pSpec, gpointer );
- cairo_t* getCairoContext();
+ cairo_t* getCairoContext() const;
void clipRegion(cairo_t* cr);
diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 9d1021a3759d..b678d819283d 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -3356,7 +3356,7 @@ gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpoi
#if GTK_CHECK_VERSION(3,0,0)
-cairo_t* GtkSalFrame::getCairoContext()
+cairo_t* GtkSalFrame::getCairoContext() const
{
basebmp::RawMemorySharedArray data = m_aFrame->getBuffer();
basegfx::B2IVector size = m_aFrame->getSize();
@@ -3391,7 +3391,9 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
{
static int frame;
OString tmp("/tmp/frame" + OString::number(frame++) + ".png");
- cairo_surface_write_to_png(cairo_get_target(getCairoContext()), tmp.getStr());
+ cairo_t* cr = getCairoContext();
+ cairo_surface_write_to_png(cairo_get_target(cr), tmp.getStr());
+ cairo_destroy(cr);
}
gtk_widget_queue_draw_area(m_pWindow,
@@ -3408,11 +3410,15 @@ gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame )
cairo_save(cr);
- cairo_surface_t *pSurface = cairo_get_target(pThis->getCairoContext());
+ cairo_t* source = pThis->getCairoContext();
+ cairo_surface_t *pSurface = cairo_get_target(source);
+
cairo_set_operator( cr, CAIRO_OPERATOR_OVER );
cairo_set_source_surface(cr, pSurface, 0, 0);
cairo_paint(cr);
+ cairo_destroy(source);
+
cairo_restore(cr);
cairo_surface_flush(cairo_get_target(cr));
diff --git a/vcl/unx/gtk3/gdi/cairo_gtk3_cairo.cxx b/vcl/unx/gtk3/gdi/cairo_gtk3_cairo.cxx
new file mode 100644
index 000000000000..6917596f473d
--- /dev/null
+++ b/vcl/unx/gtk3/gdi/cairo_gtk3_cairo.cxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <utility>
+
+#include "cairo_cairo.hxx"
+#include "cairo_gtk3_cairo.hxx"
+
+#include <vcl/sysdata.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/window.hxx>
+#include <basegfx/vector/b2isize.hxx>
+
+#include "unx/gtk/gtkgdi.hxx"
+
+namespace cairo
+{
+ /**
+ * Surface::Surface: Create generic Canvas surface using given Cairo Surface
+ *
+ * @param pSurface Cairo Surface
+ *
+ * This constructor only stores data, it does no processing.
+ * It is used with e.g. cairo_image_surface_create_for_data()
+ *
+ * Set the mpSurface as pSurface
+ **/
+ Gtk3Surface::Gtk3Surface(const CairoSurfaceSharedPtr& pSurface)
+ : mpGraphics(NULL)
+ , cr(NULL)
+ , mpSurface(pSurface)
+ {}
+
+ /**
+ * Surface::Surface: Create Canvas surface from Window reference.
+ * @param x horizontal location of the new surface
+ * @param y vertical location of the new surface
+ * @param width width of the new surface
+ * @param height height of the new surface
+ *
+ * Set the mpSurface to the new surface or NULL
+ **/
+ Gtk3Surface::Gtk3Surface(const GtkSalGraphics* pGraphics, int x, int y, int width, int height)
+ : mpGraphics(pGraphics)
+ , cr(pGraphics->getCairoContext())
+ {
+ cairo_surface_t* surface = cairo_get_target(cr);
+ mpSurface.reset(
+ cairo_surface_create_for_rectangle(surface, x, y, width, height),
+ &cairo_surface_destroy);
+ }
+
+ Gtk3Surface::~Gtk3Surface()
+ {
+ if (cr)
+ cairo_destroy(cr);
+ }
+
+ /**
+ * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface
+ *
+ * @return new Cairo or NULL
+ **/
+ CairoSharedPtr Gtk3Surface::getCairo() const
+ {
+ return CairoSharedPtr( cairo_create(mpSurface.get()),
+ &cairo_destroy );
+ }
+
+ /**
+ * Surface::getSimilar: Create new similar Canvas surface
+ * @param cairo_content_type format of the new surface (cairo_content_t from cairo/src/cairo.h)
+ * @param width width of the new surface
+ * @param height height of the new surface
+ *
+ * Creates a new Canvas surface. This normally creates platform native surface, even though
+ * generic function is used.
+ *
+ * Cairo surface from cairo_content_type (cairo_content_t)
+ *
+ * @return new surface or NULL
+ **/
+ SurfaceSharedPtr Gtk3Surface::getSimilar(int cairo_content_type, int width, int height ) const
+ {
+ return SurfaceSharedPtr(
+ new Gtk3Surface(
+ CairoSurfaceSharedPtr(
+ cairo_surface_create_similar( mpSurface.get(),
+ static_cast<cairo_content_t>(cairo_content_type), width, height ),
+ &cairo_surface_destroy )));
+ }
+
+ void Gtk3Surface::flush() const
+ {
+ cairo_surface_flush(mpSurface.get());
+ //Wonder if there is any benefit in using cairo_fill/stroke extents on
+ //every canvas call and only redrawing the union of those in a
+ //poor-mans-damage tracking
+ if (mpGraphics)
+ mpGraphics->WidgetQueueDraw();
+ }
+
+ boost::shared_ptr<VirtualDevice> Gtk3Surface::createVirtualDevice() const
+ {
+ return boost::shared_ptr<VirtualDevice>(new VirtualDevice(NULL, Size(1, 1), 0));
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3/gdi/cairo_gtk3_cairo.hxx b/vcl/unx/gtk3/gdi/cairo_gtk3_cairo.hxx
new file mode 100644
index 000000000000..1d6e36ff44f6
--- /dev/null
+++ b/vcl/unx/gtk3/gdi/cairo_gtk3_cairo.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_CANVAS_SOURCE_CAIRO_CAIRO_GTK3_CAIRO_HXX
+#define INCLUDED_CANVAS_SOURCE_CAIRO_CAIRO_GTK3_CAIRO_HXX
+
+#include <sal/config.h>
+
+#include <sal/types.h>
+
+#include <vcl/cairo.hxx>
+
+class GtkSalGraphics;
+class OutputDevice;
+
+namespace cairo {
+
+ class Gtk3Surface : public Surface
+ {
+ const GtkSalGraphics* mpGraphics;
+ cairo_t* cr;
+ CairoSurfaceSharedPtr mpSurface;
+ public:
+ /// takes over ownership of passed cairo_surface
+ explicit Gtk3Surface(const CairoSurfaceSharedPtr& pSurface);
+ /// create surface on subarea of given drawable
+ explicit Gtk3Surface(const GtkSalGraphics* pGraphics, int x, int y, int width, int height);
+
+ // Surface interface
+ virtual CairoSharedPtr getCairo() const SAL_OVERRIDE;
+ virtual CairoSurfaceSharedPtr getCairoSurface() const SAL_OVERRIDE { return mpSurface; }
+ virtual SurfaceSharedPtr getSimilar(int nContentType, int width, int height) const SAL_OVERRIDE;
+
+ virtual boost::shared_ptr<VirtualDevice> createVirtualDevice() const SAL_OVERRIDE;
+
+ virtual void flush() const SAL_OVERRIDE;
+
+ ~Gtk3Surface();
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
index 3006d62fdf81..d92d6d99b17f 100644
--- a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
@@ -17,6 +17,7 @@
#include <vcl/settings.hxx>
#include "fontmanager.hxx"
#include "gtk3cairotextrender.hxx"
+#include "cairo_gtk3_cairo.hxx"
GtkStyleContext* GtkSalGraphics::mpButtonStyle = NULL;
GtkStyleContext* GtkSalGraphics::mpEntryStyle = NULL;
@@ -1447,6 +1448,27 @@ bool GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP
return false;
}
+bool GtkSalGraphics::SupportsCairo() const
+{
+ return true;
+}
+
+cairo::SurfaceSharedPtr GtkSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
+{
+ return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(rSurface));
+}
+
+cairo::SurfaceSharedPtr GtkSalGraphics::CreateSurface(const OutputDevice& /*rRefDevice*/, int x, int y, int width, int height) const
+{
+ return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(this, x, y, width, height));
+}
+
+void GtkSalGraphics::WidgetQueueDraw() const
+{
+ //request gtk to sync the entire contents
+ gtk_widget_queue_draw(mpWindow);
+}
+
static GtkWidget* gCacheWindow;
static GtkWidget* gDumbContainer;
@@ -1551,7 +1573,7 @@ GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow )
gtk_widget_path_free(path);
}
-cairo_t* GtkSalGraphics::getCairoContext()
+cairo_t* GtkSalGraphics::getCairoContext() const
{
return mpFrame->getCairoContext();
}