diff options
author | Caolán McNamara <caolanm@redhat.com> | 2015-03-18 09:57:41 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-03-23 12:45:26 +0000 |
commit | 707a8bc1e47b57421412de3f1f47ec31be28c5a9 (patch) | |
tree | 4b353cca36ddb831a8f5b46608c2891571cb8a1b | |
parent | e510a208b01c87a341b43d74d8d901f992379b84 (diff) |
enable gtk3 to support cairo canvas
Change-Id: Ie6edf155288d1514ce7a0c859ba751cdebc93391
-rw-r--r-- | vcl/Library_vclplug_gtk3.mk | 1 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkgdi.hxx | 7 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalframe.cxx | 12 | ||||
-rw-r--r-- | vcl/unx/gtk3/gdi/cairo_gtk3_cairo.cxx | 117 | ||||
-rw-r--r-- | vcl/unx/gtk3/gdi/cairo_gtk3_cairo.hxx | 51 | ||||
-rw-r--r-- | vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx | 24 |
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(); } |