[Libreoffice-commits] core.git: Branch 'private/jmux/qt5' - vcl/Library_vclplug_qt5.mk vcl/unx

Jan-Marek Glogowski glogow at fbihome.de
Tue Oct 24 18:00:21 UTC 2017


Rebased ref, commits from common ancestor:
commit f81fae5e8fa4ff3c3b1aac3a5477e5c3f759b0e6
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Oct 24 19:49:45 2017 +0200

    Implement cairo rendering
    
    Change-Id: Ieddda9bad2596ce46d7d07d4d7060e40d44997db

diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index f388f17933b9..73b9042d3a79 100644
--- a/vcl/Library_vclplug_qt5.mk
+++ b/vcl/Library_vclplug_qt5.mk
@@ -54,6 +54,7 @@ $(eval $(call gb_Library_use_libraries,vclplug_qt5,\
 
 $(eval $(call gb_Library_use_externals,vclplug_qt5,\
 	boost_headers \
+	cairo \
 	icuuc \
 	qt5 \
 	epoxy \
@@ -89,6 +90,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\
     vcl/unx/qt5/Qt5Object \
     vcl/unx/qt5/Qt5Printer \
     vcl/unx/qt5/Qt5Timer \
+    vcl/unx/qt5/Qt5Tools \
     vcl/unx/qt5/Qt5VirtualDevice \
     vcl/unx/qt5/Qt5Widget \
 ))
diff --git a/vcl/unx/qt5/Qt5Bitmap.cxx b/vcl/unx/qt5/Qt5Bitmap.cxx
index 572b5ab4d867..4529010a9b7e 100644
--- a/vcl/unx/qt5/Qt5Bitmap.cxx
+++ b/vcl/unx/qt5/Qt5Bitmap.cxx
@@ -195,7 +195,7 @@ BitmapBuffer* Qt5Bitmap::AcquireBuffer( BitmapAccessMode nMode )
     switch( pBuffer->mnBitCount )
     {
         case 1:
-            pBuffer->mnFormat = ScanlineFormat::N1BitMsbPal;
+            pBuffer->mnFormat = ScanlineFormat::N1BitLsbPal;
             pBuffer->maPalette = m_aPalette;
             break;
         case 4:
@@ -223,12 +223,12 @@ BitmapBuffer* Qt5Bitmap::AcquireBuffer( BitmapAccessMode nMode )
             break;
         }
         case 24:
-            pBuffer->mnFormat = ScanlineFormat::N24BitTcRgb;
+            pBuffer->mnFormat = ScanlineFormat::N24BitTcRgb | ScanlineFormat::TopDown;
             pBuffer->maPalette = aEmptyPalette;
             break;
         case 32:
         {
-            pBuffer->mnFormat = ScanlineFormat::N32BitTcArgb;
+            pBuffer->mnFormat = ScanlineFormat::N32BitTcArgb | ScanlineFormat::TopDown;
             pBuffer->maPalette = aEmptyPalette;
             break;
         }
diff --git a/vcl/unx/qt5/Qt5Frame.cxx b/vcl/unx/qt5/Qt5Frame.cxx
index b507d45f94da..ab9b55e319b6 100644
--- a/vcl/unx/qt5/Qt5Frame.cxx
+++ b/vcl/unx/qt5/Qt5Frame.cxx
@@ -34,12 +34,27 @@
 #include <saldatabasic.hxx>
 #include <vcl/syswin.hxx>
 
-Qt5Frame::Qt5Frame( Qt5Frame* pParent, SalFrameStyleFlags nStyle )
-    : m_bGraphicsInUse( false )
+#include <cairo.h>
+#include <headless/svpgdi.hxx>
+
+static void SvpDamageHandler( void *handle,
+                              sal_Int32 nExtentsX, sal_Int32 nExtentsY,
+                              sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight )
+{
+    Qt5Frame* pThis = static_cast< Qt5Frame* >( handle );
+    pThis->Damage( nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight );
+}
+
+Qt5Frame::Qt5Frame( Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo )
+    : m_bUseCairo( bUseCairo )
+    , m_bGraphicsInUse( false )
 {
     Qt5Instance *pInst = static_cast<Qt5Instance*>( GetSalData()->m_pInstance );
     pInst->insertFrame( this );
 
+    m_aDamageHandler.handle = this;
+    m_aDamageHandler.damaged = ::SvpDamageHandler;
+
     if( nStyle & SalFrameStyleFlags::DEFAULT ) // ensure default style
     {
         nStyle |= SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE;
@@ -84,6 +99,12 @@ Qt5Frame::~Qt5Frame()
     pInst->eraseFrame( this );
 }
 
+void Qt5Frame::Damage( sal_Int32 nExtentsX, sal_Int32 nExtentsY,
+                       sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight) const
+{
+    m_pQWidget->update( nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight );
+}
+
 QPaintDevice* Qt5Frame::GetQPaintDevice() const
 {
     QWidget *window = m_pQWidget->window();
@@ -95,9 +116,15 @@ QPaintDevice* Qt5Frame::GetQPaintDevice() const
 void Qt5Frame::TriggerPaintEvent()
 {
     QSize aSize( m_pQWidget->size() );
-    SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height(), true);
-    CallCallback(SalEvent::Paint, &aPaintEvt);
-    m_pQWidget->update();
+    SalPaintEvent aPaintEvt( 0, 0, aSize.width(), aSize.height(), true );
+    CallCallback( SalEvent::Paint, &aPaintEvt );
+}
+
+void Qt5Frame::TriggerPaintEvent( QRect aRect )
+{
+    SalPaintEvent aPaintEvt( aRect.x(), aRect.y(),
+                             aRect.width(), aRect.height(), true );
+    CallCallback( SalEvent::Paint, &aPaintEvt );
 }
 
 SalGraphics* Qt5Frame::AcquireGraphics()
@@ -105,22 +132,43 @@ SalGraphics* Qt5Frame::AcquireGraphics()
     if( m_bGraphicsInUse )
         return nullptr;
 
-    if( !m_pGraphics.get() )
-    {
-        m_pGraphics.reset( new Qt5Graphics( this ) );
-        m_pQImage.reset( new QImage( m_pQWidget->size(), QImage::Format_ARGB32 ) );
-        m_pGraphics->ChangePaintDevice( m_pQImage.get() );
-        TriggerPaintEvent();
-    }
     m_bGraphicsInUse = true;
 
-    return m_pGraphics.get();
+    if( m_bUseCairo )
+    {
+        if( !m_pSvpGraphics.get() )
+        {
+            int width = m_pQWidget->size().width();
+            int height = m_pQWidget->size().height();
+            m_pSvpGraphics.reset( new SvpSalGraphics() );
+            m_pSurface.reset( cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ));
+            m_pSvpGraphics->setSurface( m_pSurface.get(), basegfx::B2IVector(width, height) );
+            cairo_surface_set_user_data( m_pSurface.get(), SvpSalGraphics::getDamageKey(),
+                                         &m_aDamageHandler, nullptr );
+            TriggerPaintEvent();
+        }
+        return m_pSvpGraphics.get();
+    }
+    else
+    {
+        if( !m_pQt5Graphics.get() )
+        {
+            m_pQt5Graphics.reset( new Qt5Graphics( this ) );
+            m_pQImage.reset( new QImage( m_pQWidget->size(), Qt5_DefaultFormat32 ) );
+            m_pQt5Graphics->ChangePaintDevice( m_pQImage.get() );
+            TriggerPaintEvent();
+        }
+        return m_pQt5Graphics.get();
+    }
 }
 
 void Qt5Frame::ReleaseGraphics( SalGraphics* pSalGraph )
 {
     (void) pSalGraph;
-    assert( pSalGraph == m_pGraphics.get() );
+    if( m_bUseCairo )
+        assert( pSalGraph == m_pSvpGraphics.get() );
+    else
+        assert( pSalGraph == m_pQt5Graphics.get() );
     m_bGraphicsInUse = false;
 }
 
@@ -291,7 +339,6 @@ bool Qt5Frame::GetWindowState( SalFrameState* pState )
                            WindowStateMask::Height;
     }
 
-    TriggerPaintEvent();
     return true;
 }
 
@@ -330,7 +377,7 @@ void Qt5Frame::Flush()
 
 void Qt5Frame::Flush( const tools::Rectangle& rRect )
 {
-    TriggerPaintEvent();
+    TriggerPaintEvent( toQRect( rRect ) );
 }
 
 void Qt5Frame::SetInputContext( SalInputContext* pContext )
diff --git a/vcl/unx/qt5/Qt5Frame.hxx b/vcl/unx/qt5/Qt5Frame.hxx
index 3c58a7bff0cd..6d6ec9a97192 100644
--- a/vcl/unx/qt5/Qt5Frame.hxx
+++ b/vcl/unx/qt5/Qt5Frame.hxx
@@ -21,7 +21,9 @@
 
 #include <salframe.hxx>
 
-#include <memory>
+#include "Qt5Tools.hxx"
+
+#include <headless/svpgdi.hxx>
 
 class Qt5Graphics;
 class Qt5Instance;
@@ -29,15 +31,22 @@ class Qt5Widget;
 class QWidget;
 class QPaintDevice;
 class QImage;
+class SvpSalGraphics;
 
 class Qt5Frame
     : public SalFrame
 {
     friend class Qt5Widget;
 
-    std::unique_ptr< QWidget >      m_pQWidget;
-    std::unique_ptr< QImage >       m_pQImage;
-    std::unique_ptr< Qt5Graphics >  m_pGraphics;
+    std::unique_ptr< QWidget >        m_pQWidget;
+
+    const bool                        m_bUseCairo;
+    std::unique_ptr< QImage >         m_pQImage;
+    std::unique_ptr< Qt5Graphics >    m_pQt5Graphics;
+    UniqueCairoSurface                m_pSurface;
+    std::unique_ptr< SvpSalGraphics>  m_pSvpGraphics;
+    DamageHandler                     m_aDamageHandler;
+
     bool                            m_bGraphicsInUse;
     SalFrameStyleFlags              m_nStyle;
     Qt5Frame                       *m_pParent;
@@ -53,15 +62,20 @@ class Qt5Frame
     }
 
     void TriggerPaintEvent();
+    void TriggerPaintEvent( QRect aRect );
 
 public:
     Qt5Frame( Qt5Frame* pParent,
-              SalFrameStyleFlags nSalFrameStyle );
+              SalFrameStyleFlags nSalFrameStyle,
+              bool bUseCairo );
     virtual ~Qt5Frame() override;
 
     QWidget* GetQWidget() const { return m_pQWidget.get(); }
     QPaintDevice* GetQPaintDevice() const;
 
+    void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY,
+                sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight) const;
+
     virtual SalGraphics*        AcquireGraphics() override;
     virtual void                ReleaseGraphics( SalGraphics* pGraphics ) override;
 
diff --git a/vcl/unx/qt5/Qt5Graphics_GDI.cxx b/vcl/unx/qt5/Qt5Graphics_GDI.cxx
index e3af408f8d63..730827292567 100644
--- a/vcl/unx/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/unx/qt5/Qt5Graphics_GDI.cxx
@@ -187,6 +187,7 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBi
 
     PreparePainter();
     const QImage *pImage = static_cast< const Qt5Bitmap* >( &rSalBitmap )->GetQImage();
+    assert( pImage );
 
     m_pPainter->drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
         *pImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
@@ -200,14 +201,31 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry,
                               const SalBitmap& rSalBitmap,
                               const SalBitmap& rTransparentBitmap )
 {
-// assert( !"Impl" );
+    if( rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0
+            || rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0 )
+        return;
+
+    assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
+    assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
+
+    PreparePainter();
+    const QImage *pImage = static_cast< const Qt5Bitmap* >( &rSalBitmap )->GetQImage();
+    const QImage *pAlpha = static_cast< const Qt5Bitmap* >( &rTransparentBitmap )->GetQImage();
 }
 
 void Qt5Graphics::drawMask( const SalTwoRect& rPosAry,
-                                      const SalBitmap& rSalBitmap,
-                                      SalColor nMaskColor )
+                            const SalBitmap& rSalBitmap,
+                            SalColor nMaskColor )
 {
-// assert( !"Impl" );
+    if( rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0
+            || rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0 )
+        return;
+
+    assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
+    assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
+
+    PreparePainter();
+    const QImage *pImage = static_cast< const Qt5Bitmap* >( &rSalBitmap )->GetQImage();
 }
 
 SalBitmap* Qt5Graphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
diff --git a/vcl/unx/qt5/Qt5Instance.cxx b/vcl/unx/qt5/Qt5Instance.cxx
index 88c149159464..041b74d112cc 100644
--- a/vcl/unx/qt5/Qt5Instance.cxx
+++ b/vcl/unx/qt5/Qt5Instance.cxx
@@ -27,8 +27,11 @@
 #include "Qt5Object.hxx"
 #include "Qt5Bitmap.hxx"
 
+#include <headless/svpvd.hxx>
+
 #include <QtCore/QThread>
 #include <QtWidgets/QApplication>
+#include <QtWidgets/QWidget>
 #include <QtCore/QAbstractEventDispatcher>
 
 #include <vclpluginapi.h>
@@ -39,9 +42,10 @@
 #include <headless/svpdummies.hxx>
 #include <headless/svpbmp.hxx>
 
-Qt5Instance::Qt5Instance( SalYieldMutex* pMutex )
+Qt5Instance::Qt5Instance( SalYieldMutex* pMutex, bool bUseCairo )
     : SalGenericInstance( pMutex )
     , m_postUserEventId( -1 )
+    , m_bUseCairo( bUseCairo )
 {
     m_postUserEventId = QEvent::registerEventType();
 
@@ -60,13 +64,13 @@ Qt5Instance::~Qt5Instance()
 
 SalFrame* Qt5Instance::CreateChildFrame( SystemParentData* /*pParent*/, SalFrameStyleFlags nStyle )
 {
-    return new Qt5Frame( nullptr, nStyle );
+    return new Qt5Frame( nullptr, nStyle, m_bUseCairo );
 }
 
 SalFrame* Qt5Instance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
 {
     assert( !pParent || dynamic_cast<Qt5Frame*>( pParent ) );
-    return new Qt5Frame( static_cast<Qt5Frame*>( pParent ), nStyle );
+    return new Qt5Frame( static_cast<Qt5Frame*>( pParent ), nStyle, m_bUseCairo );
 }
 
 void Qt5Instance::DestroyFrame( SalFrame* pFrame )
@@ -77,7 +81,7 @@ void Qt5Instance::DestroyFrame( SalFrame* pFrame )
 SalObject* Qt5Instance::CreateObject( SalFrame* pParent, SystemWindowData*, bool bShow )
 {
     assert( !pParent || dynamic_cast<Qt5Frame*>( pParent ) );
-    return new Qt5Object( static_cast<Qt5Frame*>( pParent ), bShow );
+    return new Qt5Object( static_cast<Qt5Frame*>( pParent ), bShow, m_bUseCairo );
 }
 
 void Qt5Instance::DestroyObject( SalObject* pObject )
@@ -90,9 +94,18 @@ SalVirtualDevice* Qt5Instance::CreateVirtualDevice( SalGraphics* /* pGraphics */
                                                     DeviceFormat eFormat,
                                                     const SystemGraphicsData* /* pData */ )
 {
-    Qt5VirtualDevice* pVD = new Qt5VirtualDevice( eFormat, 1 );
-    pVD->SetSize( nDX, nDY );
-    return pVD;
+    if ( m_bUseCairo )
+    {
+        SvpSalVirtualDevice *pVD = new SvpSalVirtualDevice( eFormat, 1 );
+        pVD->SetSize( nDX, nDY );
+        return pVD;
+    }
+    else
+    {
+        Qt5VirtualDevice* pVD = new Qt5VirtualDevice( eFormat, 1 );
+        pVD->SetSize( nDX, nDY );
+        return pVD;
+    }
 }
 
 SalTimer* Qt5Instance::CreateSalTimer()
@@ -107,7 +120,10 @@ SalSystem* Qt5Instance::CreateSalSystem()
 
 SalBitmap* Qt5Instance::CreateSalBitmap()
 {
-    return new Qt5Bitmap();
+    if ( m_bUseCairo )
+        return new SvpSalBitmap();
+    else
+        return new Qt5Bitmap();
 }
 
 bool Qt5Instance::ImplYield( bool bWait, bool bHandleAllCurrentEvents )
@@ -191,13 +207,14 @@ void Qt5Instance::TriggerUserEventProcessing()
 void Qt5Instance::ProcessEvent( SalUserEvent aEvent )
 {
     aEvent.m_pFrame->CallCallback( aEvent.m_nEvent, aEvent.m_pData );
+    static_cast<Qt5Frame*>( aEvent.m_pFrame )->GetQWidget()->update();
 }
 
 extern "C" {
     VCLPLUG_QT5_PUBLIC SalInstance* create_SalInstance()
     {
         OString aVersion( qVersion() );
-        SAL_INFO( "vcl.kf5", "qt version string is " << aVersion );
+        SAL_INFO( "vcl.qt5", "qt version string is " << aVersion );
 
         QApplication *pQApplication;
         char **pFakeArgvFreeable = nullptr;
diff --git a/vcl/unx/qt5/Qt5Instance.hxx b/vcl/unx/qt5/Qt5Instance.hxx
index ff0cacc7be97..0fea7673b59c 100644
--- a/vcl/unx/qt5/Qt5Instance.hxx
+++ b/vcl/unx/qt5/Qt5Instance.hxx
@@ -39,6 +39,7 @@ class Qt5Instance
 
     osl::Condition m_aWaitingYieldCond;
     int m_postUserEventId;
+    const bool m_bUseCairo;
 
 public:
     std::unique_ptr< QApplication > m_pQApplication;
@@ -53,7 +54,7 @@ Q_SIGNALS:
     bool ImplYieldSignal( bool bWait, bool bHandleAllCurrentEvents );
 
 public:
-    explicit Qt5Instance( SalYieldMutex* pMutex );
+    explicit Qt5Instance( SalYieldMutex* pMutex, bool bUseCairo = false );
     virtual ~Qt5Instance() override;
 
     virtual SalFrame*          CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) override;
diff --git a/vcl/unx/qt5/Qt5Object.cxx b/vcl/unx/qt5/Qt5Object.cxx
index df1ffefaa54e..a4c259979a9f 100644
--- a/vcl/unx/qt5/Qt5Object.cxx
+++ b/vcl/unx/qt5/Qt5Object.cxx
@@ -23,8 +23,9 @@
 
 #include <QtWidgets/QWidget>
 
-Qt5Object::Qt5Object( Qt5Frame* pParent, bool bShow )
+Qt5Object::Qt5Object( Qt5Frame* pParent, bool bShow, bool bUseCairo )
     : m_pParent( pParent )
+    , m_bUseCairo( bUseCairo )
 {
     if ( !pParent || !pParent->GetQWidget() )
         return;
diff --git a/vcl/unx/qt5/Qt5Object.hxx b/vcl/unx/qt5/Qt5Object.hxx
index b66f55063d2c..93b1a475f160 100644
--- a/vcl/unx/qt5/Qt5Object.hxx
+++ b/vcl/unx/qt5/Qt5Object.hxx
@@ -35,9 +35,10 @@ class Qt5Object : public SalObject
     std::unique_ptr< QWidget >  m_pQWidget;
     Qt5Frame*                   m_pParent;
     QRegion                     m_pRegion;
+    const bool                  m_bUseCairo;
 
 public:
-    Qt5Object( Qt5Frame* pParent, bool bShow );
+    Qt5Object( Qt5Frame* pParent, bool bShow, bool bUseCairo );
     virtual ~Qt5Object() override;
 
     virtual void                  ResetClipRegion() override;
diff --git a/vcl/unx/qt5/Qt5Tools.cxx b/vcl/unx/qt5/Qt5Tools.cxx
new file mode 100644
index 000000000000..5ce038b2b054
--- /dev/null
+++ b/vcl/unx/qt5/Qt5Tools.cxx
@@ -0,0 +1,28 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "Qt5Tools.hxx"
+
+#include <cairo.h>
+
+void CairoDeleter::operator()(cairo_surface_t *pSurface) const
+{
+    cairo_surface_destroy( pSurface );
+}
+
diff --git a/vcl/unx/qt5/Qt5Tools.hxx b/vcl/unx/qt5/Qt5Tools.hxx
index 40c34d9d4303..e429f4d9c56c 100644
--- a/vcl/unx/qt5/Qt5Tools.hxx
+++ b/vcl/unx/qt5/Qt5Tools.hxx
@@ -25,8 +25,11 @@
 #include <QtGui/QImage>
 
 #include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
 #include <tools/gen.hxx>
 
+#include <memory>
+
 inline OUString toOUString(const QString& s)
 {
     // QString stores UTF16, just like OUString
@@ -55,6 +58,8 @@ inline Size toSize( const QSize& rSize )
     return Size( rSize.width(), rSize.height() );
 }
 
+static constexpr QImage::Format Qt5_DefaultFormat32 = QImage::Format_ARGB32;
+
 inline QImage::Format getBitFormat( sal_uInt16 nBitCount )
 {
     switch ( nBitCount )
@@ -63,7 +68,7 @@ inline QImage::Format getBitFormat( sal_uInt16 nBitCount )
     case 8  : return QImage::Format_Indexed8;
     case 16 : return QImage::Format_RGB16;
     case 24 : return QImage::Format_RGB888;
-    case 32 : return QImage::Format_ARGB32;
+    case 32 : return Qt5_DefaultFormat32;
     default :
         std::abort();
         break;
@@ -79,11 +84,19 @@ inline sal_uInt16 getFormatBits( QImage::Format eFormat )
         case QImage::Format_Indexed8 : return 8;
         case QImage::Format_RGB16 : return 16;
         case QImage::Format_RGB888 : return 24;
-        case QImage::Format_ARGB32 : return 32;
+        case Qt5_DefaultFormat32 : return 32;
         default :
             std::abort();
             return 0;
     }
 }
 
+typedef struct _cairo_surface cairo_surface_t;
+struct CairoDeleter
+{
+    void operator()(cairo_surface_t *pSurface) const;
+};
+
+typedef std::unique_ptr<cairo_surface_t, CairoDeleter> UniqueCairoSurface;
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/qt5/Qt5VirtualDevice.cxx b/vcl/unx/qt5/Qt5VirtualDevice.cxx
index 0adf25b9c035..ef22c59baeed 100644
--- a/vcl/unx/qt5/Qt5VirtualDevice.cxx
+++ b/vcl/unx/qt5/Qt5VirtualDevice.cxx
@@ -20,6 +20,7 @@
 #include "Qt5VirtualDevice.hxx"
 
 #include "Qt5Graphics.hxx"
+#include "Qt5Tools.hxx"
 
 #include <QtGui/QImage>
 
@@ -76,9 +77,9 @@ bool Qt5VirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY,
     else
     {
         if ( pBuffer )
-            m_pImage.reset( new QImage( pBuffer, nNewDX, nNewDY, QImage::Format_ARGB32 ) );
+            m_pImage.reset( new QImage( pBuffer, nNewDX, nNewDY, Qt5_DefaultFormat32 ) );
         else
-            m_pImage.reset( new QImage( nNewDX, nNewDY, QImage::Format_ARGB32 ) );
+            m_pImage.reset( new QImage( nNewDX, nNewDY, Qt5_DefaultFormat32 ) );
     }
 
     m_pImage->setDevicePixelRatio( m_fScale );
diff --git a/vcl/unx/qt5/Qt5Widget.cxx b/vcl/unx/qt5/Qt5Widget.cxx
index 1ecb84319e8e..a225dc65f50a 100644
--- a/vcl/unx/qt5/Qt5Widget.cxx
+++ b/vcl/unx/qt5/Qt5Widget.cxx
@@ -22,12 +22,16 @@
 
 #include "Qt5Frame.hxx"
 #include "Qt5Graphics.hxx"
+#include "Qt5Tools.hxx"
 
 #include <sal/log.hxx>
 
 #include <QtGui/QPainter>
 #include <QtGui/QImage>
 
+#include <cairo.h>
+#include <headless/svpgdi.hxx>
+
 Qt5Widget::Qt5Widget( Qt5Frame &rFrame, QWidget *parent, Qt::WindowFlags f )
     : QWidget( parent, f )
     , m_pFrame( &rFrame )
@@ -50,14 +54,38 @@ Qt5Widget::~Qt5Widget()
 void Qt5Widget::paintEvent( QPaintEvent* )
 {
     QPainter p( this );
-    p.drawImage( QPoint( 0, 0 ), *(m_pFrame->m_pQImage) );
+    if( m_pFrame->m_bUseCairo )
+    {
+        cairo_surface_t *pSurface = m_pFrame->m_pSurface.get();
+        cairo_surface_flush( pSurface );
+
+        QImage aImage( cairo_image_surface_get_data( pSurface ),
+            size().width(), size().height(), Qt5_DefaultFormat32 );
+        p.drawImage( QPoint( 0, 0 ), aImage );
+    }
+    else
+        p.drawImage( QPoint( 0, 0 ), *(m_pFrame->m_pQImage) );
 }
 
 void Qt5Widget::resizeEvent( QResizeEvent* )
 {
-    QImage *pImage = new QImage( m_pFrame->m_pQWidget->size(), QImage::Format_ARGB32 );
-    m_pFrame->m_pGraphics->ChangePaintDevice( pImage );
-    m_pFrame->m_pQImage.reset( pImage );
+    if( m_pFrame->m_bUseCairo )
+    {
+        int width = size().width();
+        int height = size().height();
+        cairo_surface_t *pSurface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height );
+        cairo_surface_set_user_data( pSurface, SvpSalGraphics::getDamageKey(),
+                                     &m_pFrame->m_aDamageHandler, nullptr );
+        m_pFrame->m_pSvpGraphics->setSurface( pSurface, basegfx::B2IVector(width, height) );
+        m_pFrame->m_pSurface.reset( pSurface );
+    }
+    else
+    {
+        QImage *pImage = new QImage( size(), Qt5_DefaultFormat32 );
+        m_pFrame->m_pQt5Graphics->ChangePaintDevice( pImage );
+        m_pFrame->m_pQImage.reset( pImage );
+    }
+
     m_pFrame->CallCallback( SalEvent::Resize, nullptr );
 }
 


More information about the Libreoffice-commits mailing list