206476e
From f770a69457b5e0432b396d5d1bd62cdc9db8e1ed Mon Sep 17 00:00:00 2001
206476e
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
206476e
Date: Wed, 11 Apr 2018 11:06:37 +0100
206476e
Subject: [PATCH] Related: rhbz#1396729 use cairo_surface_create_similar
206476e
MIME-Version: 1.0
206476e
Content-Type: text/plain; charset=UTF-8
206476e
Content-Transfer-Encoding: 8bit
206476e
206476e
where we can
206476e
206476e
Change-Id: If6fd729a9cbf834faef33586b5bd886aad2fbe1d
206476e
Reviewed-on: https://gerrit.libreoffice.org/52726
206476e
Tested-by: Jenkins <ci@libreoffice.org>
206476e
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
206476e
Tested-by: Caolán McNamara <caolanm@redhat.com>
206476e
(cherry picked from commit b524de950c6eb0bc61d05d41fe69b67ab59b16c6)
206476e
206476e
cairo_surface_create_similar_image is >= cairo 1.12.0
206476e
206476e
(cherry picked from commit 2ca4b505b25e13c9f422c28252f5b7533b8e3270)
206476e
206476e
Change-Id: I1805e5680beff6c632016686aa661efe25a8c2f8
206476e
---
206476e
 vcl/headless/svpgdi.cxx     | 20 ++++++++++++++++----
206476e
 vcl/headless/svpinst.cxx    |  6 ++++--
206476e
 vcl/headless/svpvd.cxx      | 40 ++++++++++++++++++++++++++--------------
206476e
 vcl/inc/headless/svpgdi.hxx |  1 +
206476e
 vcl/inc/headless/svpvd.hxx  |  9 ++-------
206476e
 vcl/qt5/Qt5Instance.cxx     |  8 +++++---
206476e
 vcl/unx/gtk/gtkinst.cxx     |  2 +-
206476e
 7 files changed, 55 insertions(+), 31 deletions(-)
206476e
206476e
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
206476e
index 67433a2b30e1..b490121750db 100644
206476e
--- a/vcl/headless/svpgdi.cxx
206476e
+++ b/vcl/headless/svpgdi.cxx
206476e
@@ -1239,7 +1239,13 @@ SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeigh
206476e
 
206476e
 SalColor SvpSalGraphics::getPixel( long nX, long nY )
206476e
 {
206476e
-    cairo_surface_t *target = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
206476e
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
206476e
+    cairo_surface_t *target = cairo_surface_create_similar_image(m_pSurface,
206476e
+#else
206476e
+    cairo_surface_t *target = cairo_image_surface_create(
206476e
+#endif
206476e
+            CAIRO_FORMAT_ARGB32, 1, 1);
206476e
+
206476e
     cairo_t* cr = cairo_create(target);
206476e
 
206476e
     cairo_rectangle(cr, 0, 0, 1, 1);
206476e
@@ -1398,9 +1404,15 @@ cairo_surface_t* SvpSalGraphics::createCairoSurface(const BitmapBuffer *pBuffer)
206476e
 
206476e
 cairo_t* SvpSalGraphics::createTmpCompatibleCairoContext() const
206476e
 {
206476e
-    cairo_surface_t *target = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
206476e
-                                                         m_aFrameSize.getX() * m_fScale,
206476e
-                                                         m_aFrameSize.getY() * m_fScale);
206476e
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
206476e
+    cairo_surface_t *target = cairo_surface_create_similar_image(m_pSurface,
206476e
+#else
206476e
+    cairo_surface_t *target = cairo_image_surface_create(
206476e
+#endif
206476e
+            CAIRO_FORMAT_ARGB32,
206476e
+            m_aFrameSize.getX() * m_fScale,
206476e
+            m_aFrameSize.getY() * m_fScale);
206476e
+
206476e
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
206476e
     cairo_surface_set_device_scale(target, m_fScale, m_fScale);
206476e
 #endif
206476e
diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx
206476e
index 9912186c729c..c39ffaeb5205 100644
206476e
--- a/vcl/headless/svpinst.cxx
206476e
+++ b/vcl/headless/svpinst.cxx
206476e
@@ -219,12 +219,14 @@ void SvpSalInstance::DestroyObject( SalObject* pObject )
206476e
 
206476e
 #ifndef IOS
206476e
 
206476e
-SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics */,
206476e
+SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
206476e
                                                        long &nDX, long &nDY,
206476e
                                                        DeviceFormat eFormat,
206476e
                                                        const SystemGraphicsData* /* pData */ )
206476e
 {
206476e
-    SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat, 1);
206476e
+    SvpSalGraphics *pSvpSalGraphics = dynamic_cast<SvpSalGraphics*>(pGraphics);
206476e
+    assert(pSvpSalGraphics);
206476e
+    SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat, pSvpSalGraphics->getSurface());
206476e
     pNew->SetSize( nDX, nDY );
206476e
     return pNew;
206476e
 }
206476e
diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx
206476e
index cf78ebc8eb7d..4172fc383744 100644
206476e
--- a/vcl/headless/svpvd.cxx
206476e
+++ b/vcl/headless/svpvd.cxx
206476e
@@ -30,9 +30,18 @@
206476e
 
206476e
 using namespace basegfx;
206476e
 
206476e
+SvpSalVirtualDevice::SvpSalVirtualDevice(DeviceFormat eFormat, cairo_surface_t* pRefSurface)
206476e
+    : m_eFormat(eFormat)
206476e
+    , m_pRefSurface(pRefSurface)
206476e
+    , m_pSurface(nullptr)
206476e
+{
206476e
+    cairo_surface_reference(m_pRefSurface);
206476e
+}
206476e
+
206476e
 SvpSalVirtualDevice::~SvpSalVirtualDevice()
206476e
 {
206476e
     cairo_surface_destroy(m_pSurface);
206476e
+    cairo_surface_destroy(m_pRefSurface);
206476e
 }
206476e
 
206476e
 SalGraphics* SvpSalVirtualDevice::AcquireGraphics()
206476e
@@ -67,9 +76,6 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY,
206476e
     {
206476e
         m_aFrameSize = basegfx::B2IVector(nNewDX, nNewDY);
206476e
 
206476e
-        nNewDX *= m_fScale;
206476e
-        nNewDY *= m_fScale;
206476e
-
206476e
         if (m_pSurface)
206476e
         {
206476e
             cairo_surface_destroy(m_pSurface);
206476e
@@ -77,23 +83,29 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY,
206476e
 
206476e
         if (m_eFormat == DeviceFormat::BITMASK)
206476e
         {
206476e
-            m_pSurface = cairo_image_surface_create(CAIRO_FORMAT_A1,
206476e
+            m_pSurface = cairo_surface_create_similar(m_pRefSurface, CAIRO_CONTENT_ALPHA,
206476e
                                 nNewDX, nNewDY);
206476e
         }
206476e
-        else
206476e
+        else if (pBuffer)
206476e
         {
206476e
-            m_pSurface = pBuffer ?
206476e
-                             cairo_image_surface_create_for_data(pBuffer, CAIRO_FORMAT_ARGB32,
206476e
-                                   nNewDX, nNewDY,
206476e
-                                   cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, nNewDX))
206476e
-                                 :
206476e
-                             cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
206476e
-                                   nNewDX, nNewDY);
206476e
-        }
206476e
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
206476e
+            double fXScale, fYScale;
206476e
+            cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
206476e
+            nNewDX *= fXScale;
206476e
+            nNewDY *= fYScale;
206476e
+#endif
206476e
+
206476e
+            m_pSurface = cairo_image_surface_create_for_data(pBuffer, CAIRO_FORMAT_ARGB32,
206476e
+                                nNewDX, nNewDY, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, nNewDX));
206476e
 
206476e
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
206476e
-        cairo_surface_set_device_scale(m_pSurface, m_fScale, m_fScale);
206476e
+            cairo_surface_set_device_scale(m_pSurface, fXScale, fYScale);
206476e
 #endif
206476e
+        }
206476e
+        else
206476e
+        {
206476e
+            m_pSurface = cairo_surface_create_similar(m_pRefSurface, CAIRO_CONTENT_COLOR_ALPHA, nNewDX, nNewDY);
206476e
+        }
206476e
 
206476e
         // update device in existing graphics
206476e
         for (auto const& graphic : m_aGraphics)
206476e
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
206476e
index 8204538cb132..dae0145b8c58 100644
206476e
--- a/vcl/inc/headless/svpgdi.hxx
206476e
+++ b/vcl/inc/headless/svpgdi.hxx
206476e
@@ -89,6 +89,7 @@ class VCL_DLLPUBLIC SvpSalGraphics : public SalGraphics
206476e
 public:
206476e
     static GlyphCache& getPlatformGlyphCache();
206476e
     void setSurface(cairo_surface_t* pSurface, const basegfx::B2IVector& rSize);
206476e
+    cairo_surface_t* getSurface() const { return m_pSurface; }
206476e
     static cairo_user_data_key_t* getDamageKey();
206476e
 
206476e
 private:
206476e
diff --git a/vcl/inc/headless/svpvd.hxx b/vcl/inc/headless/svpvd.hxx
206476e
index 704488cdfae0..51d6af9cb499 100644
206476e
--- a/vcl/inc/headless/svpvd.hxx
206476e
+++ b/vcl/inc/headless/svpvd.hxx
206476e
@@ -30,18 +30,13 @@ typedef struct _cairo_surface cairo_surface_t;
206476e
 class VCL_DLLPUBLIC SvpSalVirtualDevice : public SalVirtualDevice
206476e
 {
206476e
     DeviceFormat                        m_eFormat;
206476e
+    cairo_surface_t*                    m_pRefSurface;
206476e
     cairo_surface_t*                    m_pSurface;
206476e
     basegfx::B2IVector                  m_aFrameSize;
206476e
-    double                              m_fScale;
206476e
     std::vector< SvpSalGraphics* >      m_aGraphics;
206476e
 
206476e
 public:
206476e
-    SvpSalVirtualDevice(DeviceFormat eFormat, double fScale)
206476e
-        : m_eFormat(eFormat)
206476e
-        , m_pSurface(nullptr)
206476e
-        , m_fScale(fScale)
206476e
-    {
206476e
-    }
206476e
+    SvpSalVirtualDevice(DeviceFormat eFormat, cairo_surface_t* pRefSurface);
206476e
     virtual ~SvpSalVirtualDevice() override;
206476e
 
206476e
     // SalVirtualDevice
206476e
diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
206476e
index c61a29a01935..0d128c2bc97c 100644
206476e
--- a/vcl/qt5/Qt5Instance.cxx
206476e
+++ b/vcl/qt5/Qt5Instance.cxx
206476e
@@ -84,13 +84,15 @@ SalObject* Qt5Instance::CreateObject(SalFrame* pParent, SystemWindowData*, bool
206476e
 
206476e
 void Qt5Instance::DestroyObject(SalObject* pObject) { delete pObject; }
206476e
 
206476e
-SalVirtualDevice* Qt5Instance::CreateVirtualDevice(SalGraphics* /* pGraphics */, long& nDX,
206476e
-                                                   long& nDY, DeviceFormat eFormat,
206476e
+SalVirtualDevice* Qt5Instance::CreateVirtualDevice(SalGraphics* pGraphics, long& nDX, long& nDY,
206476e
+                                                   DeviceFormat eFormat,
206476e
                                                    const SystemGraphicsData* /* pData */)
206476e
 {
206476e
     if (m_bUseCairo)
206476e
     {
206476e
-        SvpSalVirtualDevice* pVD = new SvpSalVirtualDevice(eFormat, 1);
206476e
+        SvpSalGraphics* pSvpSalGraphics = dynamic_cast<SvpSalGraphics*>(pGraphics);
206476e
+        assert(pSvpSalGraphics);
206476e
+        SvpSalVirtualDevice* pVD = new SvpSalVirtualDevice(eFormat, pSvpSalGraphics->getSurface());
206476e
         pVD->SetSize(nDX, nDY);
206476e
         return pVD;
206476e
     }
206476e
diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx
206476e
index 62b02a36a33f..ee03a340a12f 100644
206476e
--- a/vcl/unx/gtk/gtkinst.cxx
206476e
+++ b/vcl/unx/gtk/gtkinst.cxx
206476e
@@ -336,7 +336,7 @@ SalVirtualDevice* GtkInstance::CreateVirtualDevice( SalGraphics *pG,
206476e
     (void) pGd;
206476e
     SvpSalGraphics *pSvpSalGraphics = dynamic_cast<SvpSalGraphics*>(pG);
206476e
     assert(pSvpSalGraphics);
206476e
-    SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat, pSvpSalGraphics->getScale());
206476e
+    SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat, pSvpSalGraphics->getSurface());
206476e
     pNew->SetSize( nDX, nDY );
206476e
     return pNew;
206476e
 #else
206476e
-- 
206476e
2.14.3
206476e