Rebased ref, commits from common ancestor:
commit 47b82eb72d89db9081cca17a43ad4b091d565e56
Author: Thorsten Behrens <thorsten.behr...@cib.de>
Date:   Thu Nov 2 01:49:00 2017 +0100

    QT5 fixup non-qt5 build
    
    Change-Id: Ifea73d81ba3863fd6a99453cb38303eb729f6ff4

diff --git a/vcl/source/gdi/CommonSalLayout.cxx 
b/vcl/source/gdi/CommonSalLayout.cxx
index 132766753174..936369983d14 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -70,8 +70,8 @@ hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t 
nTableTag, void* pUserData
     }
 #else
     const char* pBuffer = nullptr;
-    CommonSalLayout *pLayout = static_cast<CommonSalLayout*>( pUserData );
 #if ENABLE_QT5
+    CommonSalLayout *pLayout = static_cast<CommonSalLayout*>( pUserData );
     QByteArray aTable;
     if ( pLayout->mbUseQt5 )
     {
@@ -83,8 +83,9 @@ hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t 
nTableTag, void* pUserData
     else
 #endif
     {
+        FreetypeFont* pFont = static_cast<FreetypeFont*>(pUserData);
         pBuffer = reinterpret_cast<const char*>(
-            pLayout->mpFreetypeFont->GetTable(pTagName, &nLength) );
+            pFont->GetTable(pTagName, &nLength) );
     }
 #endif
 
@@ -256,41 +257,44 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& 
rCoreTextStyle)
 
 #else
 
+#if ENABLE_QT5
 CommonSalLayout::CommonSalLayout(const FontSelectPattern &rFSP,
                                  FreetypeFont *pFreetypeFont,
                                  Qt5Font *pQt5Font, bool bUseQt5)
     : mrFontSelData(rFSP)
     , mpFreetypeFont(pFreetypeFont)
-#if ENABLE_QT5
     , mbUseQt5(bUseQt5)
     , mpQFont(pQt5Font)
-#endif
     , mpVertGlyphs(nullptr)
 {
-#if ENABLE_QT5
     if (mbUseQt5)
         mpHbFont = mpQFont->GetHbFont();
     else
-#endif
         mpHbFont = mpFreetypeFont->GetHbFont();
     if (!mpHbFont)
     {
         hb_face_t* pHbFace = hb_face_create_for_tables(getFontTable, this, 
nullptr);
 
         mpHbFont = createHbFont(pHbFace);
-#if ENABLE_QT5
         if (mbUseQt5)
             mpQFont->SetHbFont(mpHbFont);
         else
-#endif
             mpFreetypeFont->SetHbFont(mpHbFont);
     }
 }
+#endif
 
-CommonSalLayout::CommonSalLayout(FreetypeFont& rFreetypeFont)
-    : CommonSalLayout(rFreetypeFont.GetFontSelData(),
-                      &rFreetypeFont, nullptr, false)
+CommonSalLayout::CommonSalLayout(FreetypeFont& rFreetypeFont) :
+    mrFontSelData(rFreetypeFont.GetFontSelData())
+,   mpFreetypeFont(&rFreetypeFont)
+,   mpVertGlyphs(nullptr)
 {
+    mpHbFont = rFreetypeFont.GetHbFont();
+    if (!mpHbFont)
+    {
+        hb_face_t* pHbFace = hb_face_create_for_tables(getFontTable, 
&rFreetypeFont, nullptr);
+        mpHbFont = createHbFont(pHbFace);
+    }
 }
 
 #if ENABLE_QT5
commit 4bceffaa07ba464a7e9d083e989981ba1d896f85
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 16:11:09 2017 +0100

    QT5 implement Graphics damage tracking
    
    Since we implement SalGraphics handling like the gtk3 backend, we
    need damage tracking to queue updates.
    
    Since there is no native damage tracking in Qt5, we have to log
    the damage in our subclassed QPainter, which will queue an update
    on destruction.
    
    Change-Id: Ife17770750a5be9959c2fc2633b422908d196869

diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index d82b7d2fcd31..fba78d738883 100644
--- a/vcl/Library_vclplug_qt5.mk
+++ b/vcl/Library_vclplug_qt5.mk
@@ -91,6 +91,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\
     vcl/qt5/Qt5Instance \
     vcl/qt5/Qt5Instance_Print \
     vcl/qt5/Qt5Object \
+    vcl/qt5/Qt5Painter \
     vcl/qt5/Qt5Printer \
     vcl/qt5/Qt5Timer \
     vcl/qt5/Qt5Tools \
diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx
index 676e9e54664e..eae47c5f21e9 100644
--- a/vcl/qt5/Qt5Graphics.cxx
+++ b/vcl/qt5/Qt5Graphics.cxx
@@ -18,7 +18,11 @@
  */
 
 #include "Qt5Graphics.hxx"
+
 #include "Qt5Frame.hxx"
+#include "Qt5Painter.hxx"
+
+#include <qt5/Qt5Font.hxx>
 
 #include <QtWidgets/QWidget>
 
@@ -46,30 +50,6 @@ Qt5Graphics::~Qt5Graphics()
         delete m_pTextStyle[ i ];
 }
 
-void Qt5Graphics::PreparePainter( QPainter& rPainter, sal_uInt8 nTransparency )
-{
-    if ( m_pQImage )
-        rPainter.begin( m_pQImage );
-    else
-    {
-        assert( dynamic_cast< QPaintDevice* >( m_pFrame->GetQWidget() ) );
-        rPainter.begin( m_pFrame->GetQWidget() );
-    }
-    if ( !m_aClipPath.isEmpty() )
-        rPainter.setClipPath( m_aClipPath );
-    else
-        rPainter.setClipRegion( m_aClipRegion );
-    if ( SALCOLOR_NONE != m_aLineColor )
-    {
-        QColor aColor = QColor::fromRgb( QRgb( m_aLineColor ) );
-        aColor.setAlpha( nTransparency );
-        rPainter.setPen( aColor );
-    }
-    else
-        rPainter.setPen( Qt::NoPen );
-    rPainter.setCompositionMode( m_eCompositionMode );
-}
-
 void Qt5Graphics::ChangeQImage( QImage *pQImage )
 {
     m_pQImage = pQImage;
diff --git a/vcl/qt5/Qt5Graphics.hxx b/vcl/qt5/Qt5Graphics.hxx
index 52c1c90ec5df..9ffe2c47e461 100644
--- a/vcl/qt5/Qt5Graphics.hxx
+++ b/vcl/qt5/Qt5Graphics.hxx
@@ -30,16 +30,14 @@
 class Qt5Font;
 class Qt5FontFace;
 class Qt5Frame;
+class Qt5Painter;
 class PhysicalFontCollection;
 class QImage;
 
-#define PREPARE_PAINTER \
-    QPainter aPainter; \
-    PreparePainter( aPainter );
-
 class Qt5Graphics : public SalGraphics
 {
     friend class Qt5Bitmap;
+    friend class Qt5Painter;
 
     Qt5Frame                     *m_pFrame;
     QImage                       *m_pQImage;
@@ -55,7 +53,6 @@ class Qt5Graphics : public SalGraphics
     SalColor                      m_aTextColor;
 
     Qt5Graphics( Qt5Frame *pFrame, QImage *pQImage );
-    void PreparePainter( QPainter &rPainter, sal_uInt8 nTransparency = 0xff );
 
 public:
     Qt5Graphics( Qt5Frame *pFrame )
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index f8434bb3bc32..a1e407e088e1 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -20,8 +20,7 @@
 #include "Qt5Graphics.hxx"
 
 #include "Qt5Bitmap.hxx"
-#include "Qt5Frame.hxx"
-#include "Qt5Tools.hxx"
+#include "Qt5Painter.hxx"
 
 #include <QtGui/QPainter>
 #include <QtGui/QScreen>
@@ -164,48 +163,88 @@ void Qt5Graphics::ResetClipRegion()
 
 void Qt5Graphics::drawPixel( long nX, long nY )
 {
-    PREPARE_PAINTER;
+    Qt5Painter aPainter( *this );
     aPainter.drawPoint( nX, nY );
+    aPainter.update( nX, nY, 1, 1 );
 }
 
 void Qt5Graphics::drawPixel( long nX, long nY, SalColor nSalColor )
 {
-    PREPARE_PAINTER;
+    Qt5Painter aPainter( *this );
     aPainter.setPen( QColor( QRgb( nSalColor )  ) );
     aPainter.setPen( Qt::SolidLine );
     aPainter.drawPoint( nX, nY );
+    aPainter.update( nX, nY, 1, 1 );
 }
 
 void Qt5Graphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
 {
-    PREPARE_PAINTER;
+    Qt5Painter aPainter( *this );
     aPainter.drawLine( nX1, nY1, nX2, nY2 );
+
+    long tmp;
+    if ( nX1 > nX2 )
+    {
+        tmp = nX1;
+        nX1 = nX2;
+        nX2 = tmp;
+    }
+    if ( nY1 > nY2 )
+    {
+        tmp = nY1;
+        nY1 = nY2;
+        nY2 = tmp;
+    }
+    aPainter.update( nX1, nY1, nX2 - nX1, nY2 - nY1 );
 }
 
 void Qt5Graphics::drawRect( long nX, long nY, long nWidth, long nHeight )
 {
-    PREPARE_PAINTER;
-    aPainter.drawRect( nX, nY, nWidth, nHeight );
+    if (SALCOLOR_NONE == m_aFillColor && SALCOLOR_NONE == m_aLineColor )
+        return;
+
+    Qt5Painter aPainter( *this, true );
+    if ( SALCOLOR_NONE != m_aFillColor )
+        aPainter.fillRect( nX, nY, nWidth, nHeight, aPainter.brush() );
+    else
+        aPainter.drawRect( nX, nY, nWidth, nHeight );
+    aPainter.update( nX, nY, nWidth, nHeight );
 }
 
 void Qt5Graphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
 {
-    PREPARE_PAINTER;
+    if ( 0 == nPoints )
+        return;
+
+    Qt5Painter aPainter( *this );
     QPoint *pPoints = new QPoint[ nPoints ];
+    QPoint aTopLeft( pPtAry->mnX, pPtAry->mnY );
+    QPoint aBottomRight = aTopLeft;
     for ( sal_uInt32 i = 0; i < nPoints; ++i, ++pPtAry )
+    {
         pPoints[ i ] = QPoint( pPtAry->mnX, pPtAry->mnY );
+        if ( pPtAry->mnX < aTopLeft.x() )
+            aTopLeft.setX( pPtAry->mnX );
+        if ( pPtAry->mnY < aTopLeft.y() )
+            aTopLeft.setY( pPtAry->mnY );
+        if ( pPtAry->mnX > aBottomRight.x() )
+            aBottomRight.setX( pPtAry->mnX );
+        if ( pPtAry->mnY > aBottomRight.y())
+            aBottomRight.setY( pPtAry->mnY );
+    }
     aPainter.drawPolyline( pPoints, nPoints );
     delete [] pPoints;
+    aPainter.update( QRect( aTopLeft, aBottomRight ) );
 }
 
 void Qt5Graphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
 {
-    PREPARE_PAINTER;
-    QPoint *pPoints = new QPoint[ nPoints ];
+    Qt5Painter aPainter( *this, true );
+    QPolygon aPolygon( nPoints );
     for ( sal_uInt32 i = 0; i < nPoints; ++i, ++pPtAry )
-        pPoints[ i ] = QPoint( pPtAry->mnX, pPtAry->mnY );
-    aPainter.drawPolygon( pPoints, nPoints );
-    delete [] pPoints;
+        aPolygon.setPoint( i, pPtAry->mnX, pPtAry->mnY );
+    aPainter.drawPolygon( aPolygon );
+    aPainter.update( aPolygon.boundingRect() );
 }
 
 void Qt5Graphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* 
pPoints, PCONSTSALPOINT* pPtAry )
@@ -227,14 +266,9 @@ bool Qt5Graphics::drawPolyPolygon( const 
basegfx::B2DPolyPolygon& rPolyPoly,
                                m_aLineColor != SALCOLOR_NONE ) )
         return true;
 
-    PREPARE_PAINTER;
-
-    QBrush aBrush = aPainter.brush();
-    aBrush.setStyle( SALCOLOR_NONE == m_aFillColor ? Qt::NoBrush : 
Qt::SolidPattern );
-    aPainter.setBrush( aBrush );
-
+    Qt5Painter aPainter( *this, true, 255 * (1.0 - fTransparency) );
     aPainter.drawPath( aPath );
-
+    aPainter.update( aPath.boundingRect() );
     return true;
 }
 
@@ -277,8 +311,7 @@ bool Qt5Graphics::drawPolyLine( const basegfx::B2DPolygon& 
rPolyLine,
     AddPolygonToPath( aPath, rPolyLine, rPolyLine.isClosed(),
                       !getAntiAliasB2DDraw(), true );
 
-    QPainter aPainter;
-    PreparePainter( aPainter, 255 * fTransparency );
+    Qt5Painter aPainter( *this, false, 255 * (1.0 - fTransparency) );
 
     // setup line attributes
     QPen aPen = aPainter.pen();
@@ -305,6 +338,7 @@ bool Qt5Graphics::drawPolyLine( const basegfx::B2DPolygon& 
rPolyLine,
 
     aPainter.setPen( aPen );
     aPainter.drawPath( aPath );
+    aPainter.update( aPath.boundingRect() );
     return true;
 }
 
@@ -345,11 +379,12 @@ void Qt5Graphics::copyBits( const SalTwoRect& rPosAry, 
SalGraphics* pSrcGraphics
     else
         pImage = static_cast< Qt5Graphics* >( pSrcGraphics )->m_pQImage;
 
-    PREPARE_PAINTER;
-
+    Qt5Painter aPainter( *this );
     aPainter.drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
         *pImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
                         rPosAry.mnSrcWidth, rPosAry.mnSrcHeight) );
+    aPainter.update( rPosAry.mnDestX, rPosAry.mnDestY,
+                     rPosAry.mnDestWidth, rPosAry.mnDestHeight );
 }
 
 void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& 
rSalBitmap )
@@ -361,7 +396,7 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry, 
const SalBitmap& rSalBi
     assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
     assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
 
-    PREPARE_PAINTER;
+    Qt5Painter aPainter( *this );
 
     const QImage *pImage = static_cast< const Qt5Bitmap* >( &rSalBitmap 
)->GetQImage();
     assert( pImage );
@@ -369,10 +404,8 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry, 
const SalBitmap& rSalBi
     aPainter.drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
         *pImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
                         rPosAry.mnSrcWidth, rPosAry.mnSrcHeight) );
-
-    // Workaround to get updates
-    if ( m_pFrame )
-        m_pFrame->GetQWidget()->update();
+    aPainter.update( rPosAry.mnDestX, rPosAry.mnDestY,
+                     rPosAry.mnDestWidth, rPosAry.mnDestHeight );
 }
 
 void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry,
@@ -487,8 +520,8 @@ bool Qt5Graphics::drawAlphaBitmap( const SalTwoRect& 
rPosAry,
     QImage aImage;
     if ( !getAlphaImage( rSourceBitmap, rAlphaBitmap, aImage ) )
         return false;
-    PREPARE_PAINTER;
 
+    Qt5Painter aPainter( *this );
     aPainter.drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
         aImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
                        rPosAry.mnSrcWidth, rPosAry.mnSrcHeight) );
@@ -510,8 +543,7 @@ bool Qt5Graphics::drawTransformedBitmap( const 
basegfx::B2DPoint& rNull,
         aImage = pBitmap->convertToFormat( Qt5_DefaultFormat32 );
     }
 
-    PREPARE_PAINTER;
-
+    Qt5Painter aPainter( *this );
     const basegfx::B2DVector aXRel = rX - rNull;
     const basegfx::B2DVector aYRel = rY - rNull;
     aPainter.setTransform( QTransform(
@@ -519,6 +551,7 @@ bool Qt5Graphics::drawTransformedBitmap( const 
basegfx::B2DPoint& rNull,
         aYRel.getX() / aImage.height(), aYRel.getY() / aImage.height(),
         rNull.getX(), rNull.getY() ));
     aPainter.drawImage( QPoint(0, 0), aImage );
+    aPainter.update( aImage.rect() );
     return true;
 }
 
@@ -528,16 +561,12 @@ bool Qt5Graphics::drawAlphaRect( long nX, long nY, long 
nWidth,
     if (SALCOLOR_NONE == m_aFillColor && SALCOLOR_NONE == m_aLineColor )
         return true;
 
-    QPainter aPainter;
-    PreparePainter( aPainter, 255 - nTransparency );
+    Qt5Painter aPainter( *this, true, nTransparency );
     if ( SALCOLOR_NONE != m_aFillColor )
-    {
-        QColor aFillColor = QColor::fromRgb( QRgb( m_aFillColor ) );
-        aFillColor.setAlpha( nTransparency );
-        aPainter.fillRect( nX, nY, nWidth, nHeight, aFillColor );
-    }
+        aPainter.fillRect( nX, nY, nWidth, nHeight, aPainter.brush() );
     else
         aPainter.drawRect( nX, nY, nWidth, nHeight );
+    aPainter.update( nX, nY, nWidth, nHeight );
     return true;
 }
 
diff --git a/vcl/qt5/Qt5Painter.cxx b/vcl/qt5/Qt5Painter.cxx
new file mode 100644
index 000000000000..ab7789f854e5
--- /dev/null
+++ b/vcl/qt5/Qt5Painter.cxx
@@ -0,0 +1,56 @@
+/* -*- 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 "Qt5Painter.hxx"
+
+#include <QtGui/QColor>
+
+Qt5Painter::Qt5Painter( Qt5Graphics &rGraphics,
+                        bool bPrepareBrush, sal_uInt8 nTransparency )
+    : m_rGraphics( rGraphics )
+{
+    if ( rGraphics.m_pQImage )
+        begin( rGraphics.m_pQImage );
+    else
+    {
+        assert( rGraphics.m_pFrame );
+        begin( rGraphics.m_pFrame->GetQWidget() );
+    }
+    if ( !rGraphics.m_aClipPath.isEmpty() )
+        setClipPath( rGraphics.m_aClipPath );
+    else
+        setClipRegion( rGraphics.m_aClipRegion );
+    if ( SALCOLOR_NONE != rGraphics.m_aLineColor )
+    {
+        QColor aColor = QColor::fromRgb( QRgb( rGraphics.m_aLineColor ) );
+        aColor.setAlpha( nTransparency );
+        setPen( aColor );
+    }
+    else
+        setPen( Qt::NoPen );
+    if ( bPrepareBrush && SALCOLOR_NONE != rGraphics.m_aFillColor )
+    {
+        QColor aColor = QColor::fromRgb( QRgb( rGraphics.m_aFillColor ) );
+        aColor.setAlpha( nTransparency );
+        setBrush( Qt::SolidPattern );
+        setBrush( aColor );
+    }
+    setCompositionMode( rGraphics.m_eCompositionMode );
+}
+
diff --git a/vcl/qt5/Qt5Painter.hxx b/vcl/qt5/Qt5Painter.hxx
new file mode 100644
index 000000000000..864ac38fbb0f
--- /dev/null
+++ b/vcl/qt5/Qt5Painter.hxx
@@ -0,0 +1,67 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <QtCore/QRectF>
+#include <QtGui/QPainter>
+#include <QtWidgets/QWidget>
+
+#include "Qt5Frame.hxx"
+#include "Qt5Graphics.hxx"
+
+class Qt5Painter final : public QPainter
+{
+    Qt5Graphics &m_rGraphics;
+    QRegion      m_aRegion;
+
+public:
+    Qt5Painter( Qt5Graphics& rGraphics, bool bPrepareBrush = false,
+                sal_uInt8 nTransparency = 255 );
+    ~Qt5Painter()
+    {
+        if ( m_rGraphics.m_pFrame && !m_aRegion.isEmpty() )
+            m_rGraphics.m_pFrame->GetQWidget()->update( m_aRegion );
+    }
+
+    void update(int nx, int ny, int nw, int nh)
+    {
+        if ( m_rGraphics.m_pFrame )
+            m_aRegion += QRect( nx, ny, nw, nh );
+    }
+
+    void update(const QRect &rRect)
+    {
+        if ( m_rGraphics.m_pFrame )
+            m_aRegion += rRect;
+    }
+
+    void update(const QRectF &rRectF)
+    {
+        update( rRectF.toAlignedRect() );
+    }
+
+    void update()
+    {
+        if ( m_rGraphics.m_pFrame )
+            m_aRegion += m_rGraphics.m_pFrame->GetQWidget()->rect();
+    }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index 90ef68e9e9a7..195b5f2b341e 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -55,7 +55,6 @@ void Qt5Widget::paintEvent( QPaintEvent *pEvent )
 
         QImage aImage( cairo_image_surface_get_data( pSurface ),
             size().width(), size().height(), Qt5_DefaultFormat32 );
-        p.drawImage( QPoint( 0, 0 ), aImage );
         p.drawImage( pEvent->rect().topLeft(), aImage, pEvent->rect() );
     }
     else
commit 02064dc40410e475c4fce0c32787ac7c9afacc14
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 20:50:19 2017 +0100

    QT5 implement alpha based drawing
    
    Change-Id: Ide2ef42110798ed061f7e32e49e38b6428c22c01

diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx
index 727e2dd9e833..676e9e54664e 100644
--- a/vcl/qt5/Qt5Graphics.cxx
+++ b/vcl/qt5/Qt5Graphics.cxx
@@ -91,6 +91,7 @@ bool Qt5Graphics::supportsOperation( OutDevSupportType eType 
) const
     switch( eType )
     {
     case OutDevSupportType::B2DDraw:
+    case OutDevSupportType::TransparentRect:
         return true;
     default:
         return false;
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 60efb28fba30..f8434bb3bc32 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -436,27 +436,109 @@ bool Qt5Graphics::blendAlphaBitmap( const SalTwoRect&,
     return false;
 }
 
-bool Qt5Graphics::drawAlphaBitmap( const SalTwoRect&,
-                                             const SalBitmap& rSourceBitmap,
-                                             const SalBitmap& rAlphaBitmap )
+static bool getAlphaImage( const SalBitmap& rSourceBitmap,
+                           const SalBitmap& rAlphaBitmap,
+                           QImage &rAlphaImage )
 {
-    return false;
+    if (rAlphaBitmap.GetBitCount() != 8 && rAlphaBitmap.GetBitCount() != 1)
+    {
+        SAL_WARN( "vcl.gdi", "unsupported alpha depth case: "
+                  << rAlphaBitmap.GetBitCount() );
+        return false;
+    }
+
+    const QImage *pBitmap = static_cast< const Qt5Bitmap* >( &rSourceBitmap 
)->GetQImage();
+    const QImage *pAlpha = static_cast< const Qt5Bitmap* >( &rAlphaBitmap 
)->GetQImage();
+    rAlphaImage = pBitmap->convertToFormat( Qt5_DefaultFormat32 );
+
+    if ( rAlphaBitmap.GetBitCount() == 8 )
+    {
+        for (int y = 0; y < rAlphaImage.height(); ++y )
+        {
+            uchar* image_line = rAlphaImage.scanLine( y );
+            const uchar* alpha_line = pAlpha->scanLine( y );
+            for (int x = 0; x < rAlphaImage.width(); ++x, image_line += 4 )
+                image_line[ 3 ] = 255 - alpha_line[ x ];
+        }
+    }
+    else
+    {
+        for (int y = 0; y < rAlphaImage.height(); ++y )
+        {
+            uchar* image_line = rAlphaImage.scanLine( y );
+            const uchar* alpha_line = pAlpha->scanLine( y );
+            for (int x = 0; x < rAlphaImage.width(); ++x, image_line += 4 )
+            {
+                if ( x && !(x % 8) )
+                    ++alpha_line;
+                if ( 0 == (*alpha_line & (1 << (x % 8))) )
+                    image_line[0] = 0;
+            }
+        }
+    }
+
+    return true;
 }
 
-bool Qt5Graphics::drawTransformedBitmap(
-                                            const basegfx::B2DPoint& rNull,
-                                            const basegfx::B2DPoint& rX,
-                                            const basegfx::B2DPoint& rY,
-                                            const SalBitmap& rSourceBitmap,
-                                            const SalBitmap* pAlphaBitmap)
+bool Qt5Graphics::drawAlphaBitmap( const SalTwoRect& rPosAry,
+                                   const SalBitmap& rSourceBitmap,
+                                   const SalBitmap& rAlphaBitmap )
 {
-    return false;
+    QImage aImage;
+    if ( !getAlphaImage( rSourceBitmap, rAlphaBitmap, aImage ) )
+        return false;
+    PREPARE_PAINTER;
+
+    aPainter.drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
+        aImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
+                       rPosAry.mnSrcWidth, rPosAry.mnSrcHeight) );
+    return true;
+}
+
+bool Qt5Graphics::drawTransformedBitmap( const basegfx::B2DPoint& rNull,
+                                         const basegfx::B2DPoint& rX,
+                                         const basegfx::B2DPoint& rY,
+                                         const SalBitmap& rSourceBitmap,
+                                         const SalBitmap* pAlphaBitmap )
+{
+    QImage aImage;
+    if ( pAlphaBitmap && !getAlphaImage( rSourceBitmap, *pAlphaBitmap, aImage 
) )
+        return false;
+    else
+    {
+        const QImage *pBitmap = static_cast< const Qt5Bitmap* >( 
&rSourceBitmap )->GetQImage();
+        aImage = pBitmap->convertToFormat( Qt5_DefaultFormat32 );
+    }
+
+    PREPARE_PAINTER;
+
+    const basegfx::B2DVector aXRel = rX - rNull;
+    const basegfx::B2DVector aYRel = rY - rNull;
+    aPainter.setTransform( QTransform(
+        aXRel.getX() / aImage.width(),  aXRel.getY() / aImage.width(),
+        aYRel.getX() / aImage.height(), aYRel.getY() / aImage.height(),
+        rNull.getX(), rNull.getY() ));
+    aPainter.drawImage( QPoint(0, 0), aImage );
+    return true;
 }
 
 bool Qt5Graphics::drawAlphaRect( long nX, long nY, long nWidth,
-                                           long nHeight, sal_uInt8 
nTransparency )
+                                 long nHeight, sal_uInt8 nTransparency )
 {
-    return false;
+    if (SALCOLOR_NONE == m_aFillColor && SALCOLOR_NONE == m_aLineColor )
+        return true;
+
+    QPainter aPainter;
+    PreparePainter( aPainter, 255 - nTransparency );
+    if ( SALCOLOR_NONE != m_aFillColor )
+    {
+        QColor aFillColor = QColor::fromRgb( QRgb( m_aFillColor ) );
+        aFillColor.setAlpha( nTransparency );
+        aPainter.fillRect( nX, nY, nWidth, nHeight, aFillColor );
+    }
+    else
+        aPainter.drawRect( nX, nY, nWidth, nHeight );
+    return true;
 }
 
 void Qt5Graphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
commit fbb64714c9cf1e263db87bffe1f1aeb790018ddd
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 20:31:42 2017 +0100

    QT5 port quarz Polgon and PolyPolygon handling
    
    Change-Id: I53807bff3db9c9e4300f03e56857381cad7c9431

diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx
index e49c959879a8..727e2dd9e833 100644
--- a/vcl/qt5/Qt5Graphics.cxx
+++ b/vcl/qt5/Qt5Graphics.cxx
@@ -55,7 +55,10 @@ void Qt5Graphics::PreparePainter( QPainter& rPainter, 
sal_uInt8 nTransparency )
         assert( dynamic_cast< QPaintDevice* >( m_pFrame->GetQWidget() ) );
         rPainter.begin( m_pFrame->GetQWidget() );
     }
-    rPainter.setClipRegion( m_aClipRegion );
+    if ( !m_aClipPath.isEmpty() )
+        rPainter.setClipPath( m_aClipPath );
+    else
+        rPainter.setClipRegion( m_aClipRegion );
     if ( SALCOLOR_NONE != m_aLineColor )
     {
         QColor aColor = QColor::fromRgb( QRgb( m_aLineColor ) );
@@ -83,9 +86,15 @@ SystemGraphicsData Qt5Graphics::GetGraphicsData() const
     return SystemGraphicsData();
 }
 
-bool Qt5Graphics::supportsOperation( OutDevSupportType ) const
+bool Qt5Graphics::supportsOperation( OutDevSupportType eType ) const
 {
-    return false;
+    switch( eType )
+    {
+    case OutDevSupportType::B2DDraw:
+        return true;
+    default:
+        return false;
+    }
 }
 
 #if ENABLE_CAIRO_CANVAS
diff --git a/vcl/qt5/Qt5Graphics.hxx b/vcl/qt5/Qt5Graphics.hxx
index 6077f4122e12..52c1c90ec5df 100644
--- a/vcl/qt5/Qt5Graphics.hxx
+++ b/vcl/qt5/Qt5Graphics.hxx
@@ -24,6 +24,7 @@
 #include <memory>
 
 #include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
 #include <QtGui/QRegion>
 
 class Qt5Font;
@@ -43,6 +44,7 @@ class Qt5Graphics : public SalGraphics
     Qt5Frame                     *m_pFrame;
     QImage                       *m_pQImage;
     QRegion                       m_aClipRegion;
+    QPainterPath                  m_aClipPath;
     SalColor                      m_aLineColor;
     SalColor                      m_aFillColor;
     QPainter::CompositionMode     m_eCompositionMode;
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 89d1758f09ea..60efb28fba30 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -28,10 +28,101 @@
 #include <QtGui/QWindow>
 #include <QtWidgets/QWidget>
 
+static const basegfx::B2DPoint aHalfPointOfs ( 0.5, 0.5 );
+
+static void AddPolygonToPath( QPainterPath& rPath,
+                              const basegfx::B2DPolygon& rPolygon,
+                              bool bClosePath, bool bPixelSnap, bool bLineDraw 
)
+{
+    // short circuit if there is nothing to do
+    const int nPointCount = rPolygon.count();
+    if( nPointCount <= 0 )
+        return;
+
+    const bool bHasCurves = rPolygon.areControlPointsUsed();
+    for( int nPointIdx = 0, nPrevIdx = 0;; nPrevIdx = nPointIdx++ )
+    {
+        int nClosedIdx = nPointIdx;
+        if( nPointIdx >= nPointCount )
+        {
+            // prepare to close last curve segment if needed
+            if( bClosePath && (nPointIdx == nPointCount) )
+                nClosedIdx = 0;
+            else
+                break;
+        }
+
+        basegfx::B2DPoint aPoint = rPolygon.getB2DPoint( nClosedIdx );
+
+        if( bPixelSnap )
+        {
+            // snap device coordinates to full pixels
+            aPoint.setX( basegfx::fround( aPoint.getX() ) );
+            aPoint.setY( basegfx::fround( aPoint.getY() ) );
+        }
+
+        if( bLineDraw )
+            aPoint += aHalfPointOfs;
+        if( !nPointIdx )
+        {
+            // first point => just move there
+            rPath.moveTo( aPoint.getX(), aPoint.getY() );
+            continue;
+        }
+
+        bool bPendingCurve = false;
+        if( bHasCurves )
+        {
+            bPendingCurve = rPolygon.isNextControlPointUsed( nPrevIdx );
+            bPendingCurve |= rPolygon.isPrevControlPointUsed( nClosedIdx );
+        }
+
+        if( !bPendingCurve )    // line segment
+            rPath.lineTo( aPoint.getX(), aPoint.getY() );
+        else                    // cubic bezier segment
+        {
+            basegfx::B2DPoint aCP1 = rPolygon.getNextControlPoint( nPrevIdx );
+            basegfx::B2DPoint aCP2 = rPolygon.getPrevControlPoint( nClosedIdx 
);
+            if( bLineDraw )
+            {
+                aCP1 += aHalfPointOfs;
+                aCP2 += aHalfPointOfs;
+            }
+            rPath.cubicTo( aCP1.getX(), aCP1.getY(),
+                           aCP2.getX(), aCP2.getY(), aPoint.getX(), 
aPoint.getY() );
+        }
+    }
+
+    if( bClosePath )
+        rPath.closeSubpath();
+}
+
+static bool AddPolyPolygonToPath( QPainterPath& rPath,
+                                  const basegfx::B2DPolyPolygon& rPolyPoly,
+                                  bool bPixelSnap, bool bLineDraw )
+{
+    const int nPolyCount = rPolyPoly.count();
+    if( nPolyCount <= 0 )
+        return false;
+    for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+    {
+        const basegfx::B2DPolygon rPolygon = rPolyPoly.getB2DPolygon( nPolyIdx 
);
+        AddPolygonToPath( rPath, rPolygon, true, bPixelSnap, bLineDraw );
+    }
+    return true;
+}
+
 bool Qt5Graphics::setClipRegion( const vcl::Region& rRegion )
 {
     if ( rRegion.IsRectangle() )
+    {
         m_aClipRegion = toQRect( rRegion.GetBoundRect() );
+        if ( !m_aClipPath.isEmpty() )
+        {
+            QPainterPath aPath;
+            m_aClipPath.swap( aPath );
+        }
+    }
     else if( !rRegion.HasPolyPolygonOrB2DPolyPolygon() )
     {
         QRegion aQRegion;
@@ -40,10 +131,23 @@ bool Qt5Graphics::setClipRegion( const vcl::Region& 
rRegion )
         for ( auto & rRect : aRectangles )
             aQRegion += toQRect( rRect );
         m_aClipRegion = aQRegion;
+        if ( !m_aClipPath.isEmpty() )
+        {
+            QPainterPath aPath;
+            m_aClipPath.swap( aPath );
+        }
     }
     else
     {
-        QPolygon aPolygon;
+        QPainterPath aPath;
+        const basegfx::B2DPolyPolygon aPolyClip( rRegion.GetAsB2DPolyPolygon() 
);
+        AddPolyPolygonToPath( aPath, aPolyClip, !getAntiAliasB2DDraw(), false 
);
+        m_aClipPath.swap( aPath );
+        if ( !m_aClipRegion.isEmpty() )
+        {
+            QRegion aRegion;
+            m_aClipRegion.swap( aRegion );
+        }
     }
     return true;
 }
@@ -51,6 +155,11 @@ bool Qt5Graphics::setClipRegion( const vcl::Region& rRegion 
)
 void Qt5Graphics::ResetClipRegion()
 {
     m_aClipRegion = QRegion( m_pQImage->rect() );
+    if ( !m_aClipPath.isEmpty() )
+    {
+        QPainterPath aPath;
+        m_aClipPath.swap( aPath );
+    }
 }
 
 void Qt5Graphics::drawPixel( long nX, long nY )
@@ -101,13 +210,32 @@ void Qt5Graphics::drawPolygon( sal_uInt32 nPoints, const 
SalPoint* pPtAry )
 
 void Qt5Graphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* 
pPoints, PCONSTSALPOINT* pPtAry )
 {
-    if( 0 == nPoly )
-        return;
 }
 
-bool Qt5Graphics::drawPolyPolygon( const basegfx::B2DPolyPolygon&, double 
fTransparency )
+bool Qt5Graphics::drawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly,
+                                   double fTransparency )
 {
-    return false;
+    // ignore invisible polygons
+    if (SALCOLOR_NONE == m_aFillColor && SALCOLOR_NONE == m_aLineColor )
+        return true;
+    if( (fTransparency >= 1.0) || (fTransparency < 0) )
+        return true;
+
+    QPainterPath aPath;
+    // ignore empty polygons
+    if( !AddPolyPolygonToPath( aPath, rPolyPoly, !getAntiAliasB2DDraw(),
+                               m_aLineColor != SALCOLOR_NONE ) )
+        return true;
+
+    PREPARE_PAINTER;
+
+    QBrush aBrush = aPainter.brush();
+    aBrush.setStyle( SALCOLOR_NONE == m_aFillColor ? Qt::NoBrush : 
Qt::SolidPattern );
+    aPainter.setBrush( aBrush );
+
+    aPainter.drawPath( aPath );
+
+    return true;
 }
 
 bool Qt5Graphics::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* 
pPtAry, const PolyFlags* pFlgAry )
@@ -126,14 +254,58 @@ bool Qt5Graphics::drawPolyPolygonBezier( sal_uInt32 
nPoly, const sal_uInt32* pPo
     return false;
 }
 
-bool Qt5Graphics::drawPolyLine( const basegfx::B2DPolygon&,
+bool Qt5Graphics::drawPolyLine( const basegfx::B2DPolygon& rPolyLine,
                                 double fTransparency,
                                 const basegfx::B2DVector& rLineWidths,
-                                basegfx::B2DLineJoin,
+                                basegfx::B2DLineJoin eLineJoin,
                                 css::drawing::LineCap eLineCap,
                                 double fMiterMinimumAngle )
 {
-    return false;
+    if (SALCOLOR_NONE == m_aFillColor && SALCOLOR_NONE == m_aLineColor )
+        return true;
+
+    if( basegfx::B2DLineJoin::NONE == eLineJoin )
+        return false;
+
+    // short circuit if there is nothing to do
+    const int nPointCount = rPolyLine.count();
+    if( nPointCount <= 0 )
+        return true;
+
+    // setup poly-polygon path
+    QPainterPath aPath;
+    AddPolygonToPath( aPath, rPolyLine, rPolyLine.isClosed(),
+                      !getAntiAliasB2DDraw(), true );
+
+    QPainter aPainter;
+    PreparePainter( aPainter, 255 * fTransparency );
+
+    // setup line attributes
+    QPen aPen = aPainter.pen();
+    aPen.setWidth( rLineWidths.getX() );
+
+    switch( eLineJoin )
+    {
+    case basegfx::B2DLineJoin::NONE: std::abort(); return false;
+    case basegfx::B2DLineJoin::Bevel: aPen.setJoinStyle( Qt::BevelJoin ); 
break;
+    case basegfx::B2DLineJoin::Round: aPen.setJoinStyle( Qt::RoundJoin ); 
break;
+    case basegfx::B2DLineJoin::Miter:
+        aPen.setMiterLimit( 1.0 / sin(fMiterMinimumAngle / 2.0) );
+        aPen.setJoinStyle( Qt::MiterJoin );
+        break;
+    }
+
+    switch(eLineCap)
+    {
+    default: // css::drawing::LineCap_BUTT:
+        aPen.setCapStyle( Qt::FlatCap ); break;
+    case css::drawing::LineCap_ROUND: aPen.setCapStyle( Qt::RoundCap ); break;
+    case css::drawing::LineCap_SQUARE: aPen.setCapStyle( Qt::SquareCap ); 
break;
+    }
+
+    aPainter.setPen( aPen );
+    aPainter.drawPath( aPath );
+    return true;
 }
 
 bool Qt5Graphics::drawGradient( const tools::PolyPolygon&, const Gradient& )
commit e7e8dab5ab0c0b5016cc57b0719a5d984859d2cb
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 20:22:56 2017 +0100

    QT5 unify Graphics constructors
    
    Change-Id: I85ce73e0e79927fa9233230bc4a9134db4c513dc

diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx
index 7c33c2781df4..e49c959879a8 100644
--- a/vcl/qt5/Qt5Graphics.cxx
+++ b/vcl/qt5/Qt5Graphics.cxx
@@ -26,19 +26,12 @@
 
 #include <QtGui/QImage>
 
-Qt5Graphics::Qt5Graphics( Qt5Frame *pFrame )
+Qt5Graphics::Qt5Graphics( Qt5Frame *pFrame, QImage *pQImage )
     : m_pFrame( pFrame )
-    , m_pQImage( nullptr )
-    , m_pFontCollection( nullptr )
-    , m_pFontData{ nullptr, }
-    , m_pTextStyle{ nullptr, }
-    , m_aTextColor( MAKE_SALCOLOR(0x00, 0x00, 0x00) )
-{
-}
-
-Qt5Graphics::Qt5Graphics( QImage *pQImage )
-    : m_pFrame( nullptr )
     , m_pQImage( pQImage )
+    , m_aLineColor( MAKE_SALCOLOR(0x00, 0x00, 0x00) )
+    , m_aFillColor( MAKE_SALCOLOR(0xFF, 0xFF, 0XFF) )
+    , m_eCompositionMode( QPainter::CompositionMode_SourceOver )
     , m_pFontCollection( nullptr )
     , m_pFontData{ nullptr, }
     , m_pTextStyle{ nullptr, }
diff --git a/vcl/qt5/Qt5Graphics.hxx b/vcl/qt5/Qt5Graphics.hxx
index 30fcc2f7d5fe..6077f4122e12 100644
--- a/vcl/qt5/Qt5Graphics.hxx
+++ b/vcl/qt5/Qt5Graphics.hxx
@@ -52,11 +52,14 @@ class Qt5Graphics : public SalGraphics
     Qt5Font                      *m_pTextStyle[ MAX_FALLBACK ];
     SalColor                      m_aTextColor;
 
+    Qt5Graphics( Qt5Frame *pFrame, QImage *pQImage );
     void PreparePainter( QPainter &rPainter, sal_uInt8 nTransparency = 0xff );
 
 public:
-    Qt5Graphics( Qt5Frame *pFrame );
-    Qt5Graphics( QImage *pImage );
+    Qt5Graphics( Qt5Frame *pFrame )
+        : Qt5Graphics( pFrame, nullptr ) {}
+    Qt5Graphics( QImage *pQImage )
+        : Qt5Graphics( nullptr, pQImage ) {}
     virtual ~Qt5Graphics() override;
 
     void ChangeQImage( QImage *pImage );
commit 867e920703e66572df46a006d11cb89941b714f2
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 20:19:45 2017 +0100

    QT5 always generate a QPainter
    
    Change-Id: Ie8684cd4be56fb6d88d9643a6326307590115a80

diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx
index aebb486c2453..7c33c2781df4 100644
--- a/vcl/qt5/Qt5Graphics.cxx
+++ b/vcl/qt5/Qt5Graphics.cxx
@@ -53,25 +53,31 @@ Qt5Graphics::~Qt5Graphics()
         delete m_pTextStyle[ i ];
 }
 
-void Qt5Graphics::PreparePainter()
+void Qt5Graphics::PreparePainter( QPainter& rPainter, sal_uInt8 nTransparency )
 {
-    if ( m_pPainter.get() )
-        return;
     if ( m_pQImage )
-        m_pPainter.reset( new QPainter( m_pQImage ) );
+        rPainter.begin( m_pQImage );
     else
     {
         assert( dynamic_cast< QPaintDevice* >( m_pFrame->GetQWidget() ) );
-        m_pPainter.reset( new QPainter( m_pFrame->GetQWidget() ) );
+        rPainter.begin( m_pFrame->GetQWidget() );
     }
-    if (!m_aClipRegion.isEmpty())
-        m_pPainter->setClipRegion( m_aClipRegion );
+    rPainter.setClipRegion( m_aClipRegion );
+    if ( SALCOLOR_NONE != m_aLineColor )
+    {
+        QColor aColor = QColor::fromRgb( QRgb( m_aLineColor ) );
+        aColor.setAlpha( nTransparency );
+        rPainter.setPen( aColor );
+    }
+    else
+        rPainter.setPen( Qt::NoPen );
+    rPainter.setCompositionMode( m_eCompositionMode );
 }
 
 void Qt5Graphics::ChangeQImage( QImage *pQImage )
 {
-    m_pPainter.reset();
     m_pQImage = pQImage;
+    ResetClipRegion();
 }
 
 SalGraphicsImpl* Qt5Graphics::GetImpl() const
diff --git a/vcl/qt5/Qt5Graphics.hxx b/vcl/qt5/Qt5Graphics.hxx
index d9f74a05b919..30fcc2f7d5fe 100644
--- a/vcl/qt5/Qt5Graphics.hxx
+++ b/vcl/qt5/Qt5Graphics.hxx
@@ -23,6 +23,7 @@
 
 #include <memory>
 
+#include <QtGui/QPainter>
 #include <QtGui/QRegion>
 
 class Qt5Font;
@@ -30,7 +31,10 @@ class Qt5FontFace;
 class Qt5Frame;
 class PhysicalFontCollection;
 class QImage;
-class QPainter;
+
+#define PREPARE_PAINTER \
+    QPainter aPainter; \
+    PreparePainter( aPainter );
 
 class Qt5Graphics : public SalGraphics
 {
@@ -39,14 +43,16 @@ class Qt5Graphics : public SalGraphics
     Qt5Frame                     *m_pFrame;
     QImage                       *m_pQImage;
     QRegion                       m_aClipRegion;
-    std::unique_ptr< QPainter >   m_pPainter;
+    SalColor                      m_aLineColor;
+    SalColor                      m_aFillColor;
+    QPainter::CompositionMode     m_eCompositionMode;
 
     PhysicalFontCollection       *m_pFontCollection;
     const Qt5FontFace            *m_pFontData[ MAX_FALLBACK ];
     Qt5Font                      *m_pTextStyle[ MAX_FALLBACK ];
     SalColor                      m_aTextColor;
 
-    void PreparePainter();
+    void PreparePainter( QPainter &rPainter, sal_uInt8 nTransparency = 0xff );
 
 public:
     Qt5Graphics( Qt5Frame *pFrame );
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index d44055b8e841..89d1758f09ea 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -30,7 +30,6 @@
 
 bool Qt5Graphics::setClipRegion( const vcl::Region& rRegion )
 {
-    PreparePainter();
     if ( rRegion.IsRectangle() )
         m_aClipRegion = toQRect( rRegion.GetBoundRect() );
     else if( !rRegion.HasPolyPolygonOrB2DPolyPolygon() )
@@ -46,58 +45,57 @@ bool Qt5Graphics::setClipRegion( const vcl::Region& rRegion 
)
     {
         QPolygon aPolygon;
     }
-    m_pPainter->setClipRegion( m_aClipRegion );
     return true;
 }
 
 void Qt5Graphics::ResetClipRegion()
 {
     m_aClipRegion = QRegion( m_pQImage->rect() );
-    PreparePainter();
 }
 
 void Qt5Graphics::drawPixel( long nX, long nY )
 {
-    PreparePainter();
-    m_pPainter->drawPoint( nX, nY );
+    PREPARE_PAINTER;
+    aPainter.drawPoint( nX, nY );
 }
 
 void Qt5Graphics::drawPixel( long nX, long nY, SalColor nSalColor )
 {
-    PreparePainter();
-    m_pPainter->setPen( QColor( QRgb( nSalColor )  ) );
-    m_pPainter->drawPoint( nX, nY );
+    PREPARE_PAINTER;
+    aPainter.setPen( QColor( QRgb( nSalColor )  ) );
+    aPainter.setPen( Qt::SolidLine );
+    aPainter.drawPoint( nX, nY );
 }
 
 void Qt5Graphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
 {
-    PreparePainter();
-    m_pPainter->drawLine( nX1, nY1, nX2, nY2 );
+    PREPARE_PAINTER;
+    aPainter.drawLine( nX1, nY1, nX2, nY2 );
 }
 
 void Qt5Graphics::drawRect( long nX, long nY, long nWidth, long nHeight )
 {
-    PreparePainter();
-    m_pPainter->drawRect( nX, nY, nWidth, nHeight );
+    PREPARE_PAINTER;
+    aPainter.drawRect( nX, nY, nWidth, nHeight );
 }
 
 void Qt5Graphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
 {
-    PreparePainter();
+    PREPARE_PAINTER;
     QPoint *pPoints = new QPoint[ nPoints ];
     for ( sal_uInt32 i = 0; i < nPoints; ++i, ++pPtAry )
         pPoints[ i ] = QPoint( pPtAry->mnX, pPtAry->mnY );
-    m_pPainter->drawPolyline( pPoints, nPoints );
+    aPainter.drawPolyline( pPoints, nPoints );
     delete [] pPoints;
 }
 
 void Qt5Graphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
 {
-    PreparePainter();
+    PREPARE_PAINTER;
     QPoint *pPoints = new QPoint[ nPoints ];
     for ( sal_uInt32 i = 0; i < nPoints; ++i, ++pPtAry )
         pPoints[ i ] = QPoint( pPtAry->mnX, pPtAry->mnY );
-    m_pPainter->drawPolygon( pPoints, nPoints );
+    aPainter.drawPolygon( pPoints, nPoints );
     delete [] pPoints;
 }
 
@@ -163,8 +161,7 @@ void Qt5Graphics::copyBits( const SalTwoRect& rPosAry, 
SalGraphics* pSrcGraphics
     assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
     assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
 
-    QImage *pImage;
-    QImage aImage;
+    QImage aImage, *pImage = &aImage;
     if ( !pSrcGraphics || this == pSrcGraphics )
     {
         if ( rPosAry.mnDestX == rPosAry.mnSrcX
@@ -172,13 +169,13 @@ void Qt5Graphics::copyBits( const SalTwoRect& rPosAry, 
SalGraphics* pSrcGraphics
             return;
         aImage = pImage->copy( rPosAry.mnSrcX, rPosAry.mnSrcY,
                                rPosAry.mnSrcWidth, rPosAry.mnSrcHeight );
-        pImage = &aImage;
     }
     else
         pImage = static_cast< Qt5Graphics* >( pSrcGraphics )->m_pQImage;
 
-    PreparePainter();
-    m_pPainter->drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
+    PREPARE_PAINTER;
+
+    aPainter.drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
         *pImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
                         rPosAry.mnSrcWidth, rPosAry.mnSrcHeight) );
 }
@@ -192,11 +189,12 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry, 
const SalBitmap& rSalBi
     assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
     assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
 
-    PreparePainter();
+    PREPARE_PAINTER;
+
     const QImage *pImage = static_cast< const Qt5Bitmap* >( &rSalBitmap 
)->GetQImage();
     assert( pImage );
 
-    m_pPainter->drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
+    aPainter.drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
         *pImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
                         rPosAry.mnSrcWidth, rPosAry.mnSrcHeight) );
 
@@ -319,22 +317,30 @@ long Qt5Graphics::GetGraphicsWidth() const
 
 void Qt5Graphics::SetLineColor()
 {
+    m_aLineColor = SALCOLOR_NONE;
 }
 
 void Qt5Graphics::SetLineColor( SalColor nSalColor )
 {
+    m_aLineColor = nSalColor;
 }
 
 void Qt5Graphics::SetFillColor()
 {
+    m_aFillColor = SALCOLOR_NONE;
 }
 
 void Qt5Graphics::SetFillColor( SalColor nSalColor )
 {
+    m_aFillColor = nSalColor;
 }
 
 void Qt5Graphics::SetXORMode( bool bSet )
 {
+    if ( bSet )
+        m_eCompositionMode = QPainter::CompositionMode_Xor;
+    else
+        m_eCompositionMode = QPainter::CompositionMode_SourceOver;
 }
 
 void Qt5Graphics::SetROPLineColor( SalROPColor nROPColor )
commit 5be926a3fd5a97a63a6d6dc07574ac99c7527b3d
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 19:55:18 2017 +0100

    QT5 implement some mouse handling
    
    Scrollwheel handling seems to work with mouse, but not correct
    when using a touchpad - at least for me.
    
    Change-Id: I4f1b32205516912e31f9c52605ba2bf4ec6059a8

diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 683f35146e2e..445029627279 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -30,6 +30,8 @@
 #include <QtGui/QIcon>
 #include <QtGui/QWindow>
 #include <QtGui/QScreen>
+#include <QtGui/QWindow>
+#include <QtWidgets/QApplication>
 
 #include <saldatabasic.hxx>
 #include <vcl/layout.hxx>
@@ -490,7 +492,12 @@ const SystemEnvData* Qt5Frame::GetSystemData() const
 
 SalFrame::SalPointerState Qt5Frame::GetPointerState()
 {
-    return SalPointerState();
+    SalPointerState aState;
+    QPoint pos = QCursor::pos();
+    aState.maPos = Point( pos.x(), pos.y() );
+    aState.mnState = GetMouseModCode( qApp->mouseButtons() ) |
+                     GetKeyModCode( qApp->keyboardModifiers() );
+    return aState;
 }
 
 KeyIndicatorState Qt5Frame::GetIndicatorState()
diff --git a/vcl/qt5/Qt5Tools.cxx b/vcl/qt5/Qt5Tools.cxx
index 5ce038b2b054..ec090a69dcbd 100644
--- a/vcl/qt5/Qt5Tools.cxx
+++ b/vcl/qt5/Qt5Tools.cxx
@@ -21,8 +21,37 @@
 
 #include <cairo.h>
 
+#include <vcl/event.hxx>
+
 void CairoDeleter::operator()(cairo_surface_t *pSurface) const
 {
     cairo_surface_destroy( pSurface );
 }
 
+sal_uInt16 GetKeyModCode( Qt::KeyboardModifiers eKeyModifiers )
+{
+    sal_uInt16 nCode = 0;
+    if( eKeyModifiers & Qt::ShiftModifier )
+        nCode |= KEY_SHIFT;
+    if( eKeyModifiers & Qt::ControlModifier )
+        nCode |= KEY_MOD1;
+    if( eKeyModifiers & Qt::AltModifier )
+        nCode |= KEY_MOD2;
+    if( eKeyModifiers & Qt::MetaModifier )
+        nCode |= KEY_MOD3;
+    return nCode;
+}
+
+sal_uInt16 GetMouseModCode( Qt::MouseButtons eButtons )
+{
+    sal_uInt16 nCode = 0;
+    if( eButtons & Qt::LeftButton )
+        nCode |= MOUSE_LEFT;
+    if( eButtons & Qt::MidButton )
+        nCode |= MOUSE_MIDDLE;
+    if( eButtons & Qt::RightButton )
+        nCode |= MOUSE_RIGHT;
+    return nCode;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Tools.hxx b/vcl/qt5/Qt5Tools.hxx
index e429f4d9c56c..b45f3c6c0738 100644
--- a/vcl/qt5/Qt5Tools.hxx
+++ b/vcl/qt5/Qt5Tools.hxx
@@ -99,4 +99,7 @@ struct CairoDeleter
 
 typedef std::unique_ptr<cairo_surface_t, CairoDeleter> UniqueCairoSurface;
 
+sal_uInt16 GetKeyModCode( Qt::KeyboardModifiers eKeyModifiers );
+sal_uInt16 GetMouseModCode( Qt::MouseButtons eButtons );
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index 7682a4717ae0..90ef68e9e9a7 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -25,8 +25,10 @@
 #include "Qt5Tools.hxx"
 
 #include <QtGui/QImage>
+#include <QtGui/QMouseEvent>
 #include <QtGui/QPainter>
 #include <QtGui/QPaintEvent>
+#include <QtGui/QWheelEvent>
 
 #include <cairo.h>
 #include <headless/svpgdi.hxx>
@@ -36,6 +38,7 @@ Qt5Widget::Qt5Widget( Qt5Frame &rFrame, QWidget *parent, 
Qt::WindowFlags f )
     , m_pFrame( &rFrame )
 {
     create();
+    setMouseTracking( true );
 }
 
 Qt5Widget::~Qt5Widget()
@@ -82,4 +85,88 @@ void Qt5Widget::resizeEvent( QResizeEvent* )
     m_pFrame->CallCallback( SalEvent::Resize, nullptr );
 }
 
+void Qt5Widget::mouseButtonEvent( QMouseEvent *pEvent, bool bReleased )
+{
+    SalMouseEvent aEvent;
+    switch( pEvent->button() )
+    {
+    case Qt::LeftButton: aEvent.mnButton = MOUSE_LEFT; break;
+    case Qt::MidButton: aEvent.mnButton = MOUSE_MIDDLE; break;
+    case Qt::RightButton: aEvent.mnButton = MOUSE_RIGHT; break;
+    default: return;
+    }
+
+    aEvent.mnTime   = pEvent->timestamp();
+    aEvent.mnX      = (long) pEvent->pos().x();
+    aEvent.mnY      = (long) pEvent->pos().y();
+    aEvent.mnCode   = GetKeyModCode( pEvent->modifiers() ) |
+                      GetMouseModCode( pEvent->buttons() );
+
+    SalEvent nEventType;
+    if ( bReleased )
+        nEventType = SalEvent::MouseButtonUp;
+    else
+        nEventType = SalEvent::MouseButtonDown;
+    m_pFrame->CallCallback( nEventType, &aEvent );
+}
+
+void Qt5Widget::mousePressEvent( QMouseEvent *pEvent )
+{
+    mouseButtonEvent( pEvent, false );
+}
+
+void Qt5Widget::mouseReleaseEvent( QMouseEvent *pEvent )
+{
+    mouseButtonEvent( pEvent, true );
+}
+
+void Qt5Widget::mouseMoveEvent( QMouseEvent *pEvent )
+{
+    SalMouseEvent aEvent;
+    aEvent.mnTime = pEvent->timestamp();
+    aEvent.mnX    = pEvent->pos().x();
+    aEvent.mnY    = pEvent->pos().y();
+    aEvent.mnCode = GetKeyModCode( pEvent->modifiers() ) |
+                    GetMouseModCode( pEvent->buttons() );
+    aEvent.mnButton = 0;
+
+    m_pFrame->CallCallback( SalEvent::MouseMove, &aEvent );
+    pEvent->accept();
+}
+
+void Qt5Widget::wheelEvent( QWheelEvent *pEvent )
+{
+    SalWheelMouseEvent aEvent;
+
+    aEvent.mnTime = pEvent->timestamp();
+    aEvent.mnX    = pEvent->pos().x();
+    aEvent.mnY    = pEvent->pos().y();
+    aEvent.mnCode = GetKeyModCode( pEvent->modifiers() ) |
+                    GetMouseModCode( pEvent->buttons() );
+
+    int nDelta = pEvent->angleDelta().x();
+    aEvent.mbHorz = true;
+    if ( !nDelta )
+    {
+        nDelta = pEvent->angleDelta().y();
+        aEvent.mbHorz = false;
+    }
+    if ( !nDelta )
+        return;
+    nDelta /= 8;
+
+    aEvent.mnDelta = nDelta;
+    aEvent.mnNotchDelta = nDelta > 0 ? 1 : -1;
+    aEvent.mnScrollLines = 3;
+
+    m_pFrame->CallCallback( SalEvent::WheelMouse, &aEvent );
+    pEvent->accept();
+}
+
+void Qt5Widget::moveEvent( QMoveEvent* )
+{
+    m_pFrame->CallCallback( SalEvent::Move, nullptr );
+}
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Widget.hxx b/vcl/qt5/Qt5Widget.hxx
index 3f6b32dfd613..83375278c738 100644
--- a/vcl/qt5/Qt5Widget.hxx
+++ b/vcl/qt5/Qt5Widget.hxx
@@ -23,8 +23,11 @@
 
 class Qt5Frame;
 class Qt5Object;
+class QMouseEvent;
+class QMoveEvent;
 class QPaintEvent;
 class QResizeEvent;
+class QWheelEvent;
 
 class Qt5Widget
     : public QWidget
@@ -33,8 +36,15 @@ class Qt5Widget
 
     Qt5Frame  *m_pFrame;
 
+    void mouseButtonEvent( QMouseEvent*, bool );
+
     void paintEvent( QPaintEvent* ) override;
     void resizeEvent( QResizeEvent* ) override;
+    void moveEvent( QMoveEvent* ) override;
+    void mouseMoveEvent( QMouseEvent*) override;
+    void mousePressEvent( QMouseEvent*) override;
+    void mouseReleaseEvent( QMouseEvent*) override;
+    void wheelEvent( QWheelEvent* ) override;
 
 public:
     Qt5Widget( Qt5Frame &rFrame,
commit 82f3ecd346c76465a513d071ceb9241e9398a567
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 19:44:40 2017 +0100

    QT5 port more of the gtk3 positioning code
    
    Change-Id: I36631c332ddffbca73768cdc4a596213e0b026ef

diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 0eb1a6e6bc05..683f35146e2e 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -29,8 +29,10 @@
 #include <QtCore/QSize>
 #include <QtGui/QIcon>
 #include <QtGui/QWindow>
+#include <QtGui/QScreen>
 
 #include <saldatabasic.hxx>
+#include <vcl/layout.hxx>
 #include <vcl/syswin.hxx>
 
 #include <cairo.h>
@@ -48,6 +50,8 @@ Qt5Frame::Qt5Frame( Qt5Frame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo
     : m_bUseCairo( bUseCairo )
     , m_bGraphicsInUse( false )
     , m_ePointerStyle( PointerStyle::Arrow )
+    , m_bDefaultSize( true )
+    , m_bDefaultPos( true )
 {
     Qt5Instance *pInst = static_cast<Qt5Instance*>( GetSalData()->m_pInstance 
);
     pInst->insertFrame( this );
@@ -240,8 +244,70 @@ void Qt5Frame::SetMaxClientSize( long nWidth, long nHeight 
)
         m_pQWidget->setMaximumSize( nWidth, nHeight );
 }
 
+void Qt5Frame::Center()
+{
+    if ( m_pParent )
+    {
+        QWidget *pWindow = m_pParent->GetQWidget()->window();
+        m_pQWidget->move(
+            pWindow->frameGeometry().topLeft() +
+            pWindow->rect().center() - m_pQWidget->rect().center() );
+    }
+}
+
+Size Qt5Frame::CalcDefaultSize()
+{
+    assert( m_pQWidget->isWindow() );
+    QScreen *pScreen = m_pQWidget->windowHandle()->screen();
+    if( !pScreen )
+        return Size();
+    return bestmaxFrameSizeForScreenSize( toSize( pScreen->size() ) );
+}
+
+void Qt5Frame::SetDefaultSize()
+{
+    Size aDefSize = CalcDefaultSize();
+    SetPosSize( 0, 0, aDefSize.Width(), aDefSize.Height(),
+                SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
+}
+
 void Qt5Frame::SetPosSize( long nX, long nY, long nWidth, long nHeight, 
sal_uInt16 nFlags )
 {
+    if( !m_pQWidget->isWindow() || isChild( true, false ) )
+        return;
+
+
+    if( (nFlags & ( SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT )) &&
+        (nWidth > 0 && nHeight > 0 ) // sometimes stupid things happen
+            )
+    {
+        m_bDefaultSize = false;
+        if( isChild( false ) || !m_pQWidget->isMaximized() )
+        {
+            m_pQWidget->resize( nWidth, nHeight );
+        }
+    }
+    else if( m_bDefaultSize )
+        SetDefaultSize();
+
+    m_bDefaultSize = false;
+
+    if( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) )
+    {
+        if( m_pParent )
+        {
+            QRect aRect = m_pParent->GetQWidget()->geometry();
+            nX += aRect.x();
+            nY += aRect.y();
+        }
+
+        m_bDefaultPos = false;
+        m_pQWidget->move( nX, nY );
+    }
+    else if( m_bDefaultPos )
+        Center();
+
+    m_bDefaultPos = false;
 }
 
 void Qt5Frame::GetClientSize( long& rWidth, long& rHeight )
@@ -252,6 +318,14 @@ void Qt5Frame::GetClientSize( long& rWidth, long& rHeight )
 
 void Qt5Frame::GetWorkArea( tools::Rectangle& rRect )
 {
+    if( !m_pQWidget->isWindow() )
+        return;
+    QScreen *pScreen = m_pQWidget->windowHandle()->screen();
+    if( !pScreen )
+        return;
+
+    QSize aSize = pScreen->availableVirtualSize();
+    rRect = tools::Rectangle( 0, 0, aSize.width(), aSize.height() );
 }
 
 SalFrame* Qt5Frame::GetParent() const
@@ -277,16 +351,26 @@ void Qt5Frame::SetWindowState( const SalFrameState* 
pState )
     else if( pState->mnMask & (WindowStateMask::X | WindowStateMask::Y |
                                WindowStateMask::Width | 
WindowStateMask::Height ) )
     {
-        QRect rect = m_pQWidget->geometry();
-        if ( pState->mnMask & WindowStateMask::X )
-            rect.setX( pState->mnX );
-        if ( pState->mnMask & WindowStateMask::Y )
-            rect.setY( pState->mnY );
-        if ( pState->mnMask & WindowStateMask::Width )
-            rect.setWidth( pState->mnWidth );
-        if ( pState->mnMask & WindowStateMask::Height )
-            rect.setHeight( pState->mnHeight );
-        m_pQWidget->setGeometry( rect );
+        sal_uInt16 nPosSizeFlags = 0;
+        QPoint aPos = m_pQWidget->pos();
+        QPoint aParentPos;
+        if( m_pParent )
+            aParentPos = m_pParent->GetQWidget()->window()->pos();
+        long nX = pState->mnX - aParentPos.x();
+        long nY = pState->mnY - aParentPos.y();
+        if( pState->mnMask & WindowStateMask::X )
+            nPosSizeFlags |= SAL_FRAME_POSSIZE_X;
+        else
+            nX = aPos.x() - aParentPos.x();
+        if( pState->mnMask & WindowStateMask::Y )
+            nPosSizeFlags |= SAL_FRAME_POSSIZE_Y;
+        else
+            nY = aPos.y() - aParentPos.y();
+        if( pState->mnMask & WindowStateMask::Width )
+            nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH;
+        if( pState->mnMask & WindowStateMask::Height )
+            nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT;
+        SetPosSize( nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags );
     }
     else if( pState->mnMask & WindowStateMask::State && ! isChild() )
     {
@@ -320,6 +404,7 @@ bool Qt5Frame::GetWindowState( SalFrameState* pState )
                            WindowStateMask::Height;
     }
 
+
     return true;
 }
 
diff --git a/vcl/qt5/Qt5Frame.hxx b/vcl/qt5/Qt5Frame.hxx
index 1d736bfb280f..5863c925a83b 100644
--- a/vcl/qt5/Qt5Frame.hxx
+++ b/vcl/qt5/Qt5Frame.hxx
@@ -52,6 +52,13 @@ class Qt5Frame
     Qt5Frame                       *m_pParent;
     PointerStyle                    m_ePointerStyle;
 
+    bool                            m_bDefaultSize;
+    bool                            m_bDefaultPos;
+
+    void                        Center();
+    Size                        CalcDefaultSize();
+    void                        SetDefaultSize();
+
     bool isChild( bool bPlug = true, bool bSysChild = true )
     {
         SalFrameStyleFlags nMask = SalFrameStyleFlags::NONE;
commit ae5ba0633d379cb3a548f0124d8a23b481db974f
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 19:39:18 2017 +0100

    QT5 rotate generated bitmap
    
    QImage stores the scanlines from top => bottom.
    
    Change-Id: I0a176066ab631179b8460b61a6c2b07ad2179d31

diff --git a/vcl/qt5/Qt5Bitmap.cxx b/vcl/qt5/Qt5Bitmap.cxx
index 524eaf6048c2..6fcff9e05663 100644
--- a/vcl/qt5/Qt5Bitmap.cxx
+++ b/vcl/qt5/Qt5Bitmap.cxx
@@ -193,23 +193,23 @@ BitmapBuffer* Qt5Bitmap::AcquireBuffer( BitmapAccessMode 
nMode )
     switch( pBuffer->mnBitCount )
     {
         case 1:
-            pBuffer->mnFormat = ScanlineFormat::N1BitLsbPal;
+            pBuffer->mnFormat = ScanlineFormat::N1BitLsbPal | 
ScanlineFormat::TopDown;
             pBuffer->maPalette = m_aPalette;
             break;
         case 4:
-            pBuffer->mnFormat = ScanlineFormat::N4BitMsnPal;
+            pBuffer->mnFormat = ScanlineFormat::N4BitMsnPal | 
ScanlineFormat::TopDown;
             pBuffer->maPalette = m_aPalette;
             break;
         case 8:
-            pBuffer->mnFormat = ScanlineFormat::N8BitPal;
+            pBuffer->mnFormat = ScanlineFormat::N8BitPal | 
ScanlineFormat::TopDown;
             pBuffer->maPalette = m_aPalette;
             break;
         case 16:
         {
 #ifdef OSL_BIGENDIAN
-            pBuffer->mnFormat= ScanlineFormat::N16BitTcMsbMask;
+            pBuffer->mnFormat= ScanlineFormat::N16BitTcMsbMask | 
ScanlineFormat::TopDown;
 #else
-            pBuffer->mnFormat= ScanlineFormat::N16BitTcLsbMask;
+            pBuffer->mnFormat= ScanlineFormat::N16BitTcLsbMask | 
ScanlineFormat::TopDown;
 #endif
             ColorMaskElement aRedMask(0xf800); // 5
             aRedMask.CalcMaskShift();
@@ -222,12 +222,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;
         }
@@ -239,6 +239,15 @@ BitmapBuffer* Qt5Bitmap::AcquireBuffer( BitmapAccessMode 
nMode )
 void Qt5Bitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode )
 {
     m_aPalette = pBuffer->maPalette;
+    auto count = m_aPalette.GetEntryCount();
+    if( pBuffer->mnBitCount != 4 && count )
+    {
+        QVector<QRgb> aColorTable( count );
+        for ( unsigned i = 0; i < count; ++i )
+            aColorTable[ i ] = qRgb( m_aPalette[ i ].GetRed(),
+                m_aPalette[ i ].GetGreen(), m_aPalette[ i ].GetBlue() );
+        m_pImage->setColorTable( aColorTable );
+    }
     delete pBuffer;
 }
 
commit ad69b6d5b3a97f7865cf6eb21377f46fb14b91f9
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 19:32:45 2017 +0100

    QT5 implement cursor support
    
    Change-Id: Ie47b8def36d67255b61eab04bc7e3818bb1d8ea8

diff --git a/vcl/qt5/Qt5Data.cxx b/vcl/qt5/Qt5Data.cxx
index f8d4483bf761..f05e30ce662f 100644
--- a/vcl/qt5/Qt5Data.cxx
+++ b/vcl/qt5/Qt5Data.cxx
@@ -17,14 +17,19 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <QtWidgets/QStyle>
-#include <QtWidgets/QApplication>
-
 #include "Qt5Data.hxx"
 
+#include <QtGui/QCursor>
+#include <QtGui/QBitmap>
+
+#include <unx/x11_cursors/salcursors.h>
+
 Qt5Data::Qt5Data( SalInstance *pInstance )
     : GenericUnixSalData( SAL_DATA_QT5, pInstance )
 {
+    for (QCursor* & rpCsr : m_aCursors)
+        rpCsr = nullptr;
+
     ImplSVData *pSVData = ImplGetSVData();
 
     // draw toolbars on separate lines
@@ -35,8 +40,162 @@ Qt5Data::Qt5Data( SalInstance *pInstance )
 
 Qt5Data::~Qt5Data()
 {
+    for (QCursor* & rpCsr : m_aCursors)
+        delete rpCsr;
+}
+
+static QCursor* getQCursorFromXBM( const unsigned char *pBitmap,
+                                   const unsigned char *pMask,
+                                   int nWidth, int nHeight,
+                                   int nXHot, int nYHot )
+{
+    QBitmap aPixmap;
+    aPixmap.loadFromData( pBitmap, nWidth * nHeight / 8, "XPM" );
+    QBitmap aMask;
+    aMask.loadFromData( pMask, nWidth * nHeight / 8, "XPM" );
+    aPixmap.setMask( aMask );
+    return new QCursor( aPixmap, nXHot, nYHot );
 }
 
+#define MAKE_CURSOR( vcl_name, name ) \
+    case vcl_name: \
+        pCursor = getQCursorFromXBM( name##curs##_bits, name##mask##_bits, \
+                                     name##curs_width, name##curs_height, \
+                                     name##curs_x_hot, name##curs_y_hot ); \
+        break
+
+#define MAP_BUILTIN( vcl_name, qt_enum ) \
+    case vcl_name: \
+        pCursor = new QCursor( qt_enum ); \
+        break
+
+QCursor& Qt5Data::getCursor( PointerStyle ePointerStyle )
+{
+    if ( !m_aCursors[ ePointerStyle ] )
+    {
+        QCursor *pCursor = nullptr;
+
+        switch( ePointerStyle )
+        {
+            MAP_BUILTIN( PointerStyle::Arrow, Qt::ArrowCursor );
+            MAP_BUILTIN( PointerStyle::Text, Qt::IBeamCursor );
+            MAP_BUILTIN( PointerStyle::Help, Qt::WhatsThisCursor );
+            MAP_BUILTIN( PointerStyle::Cross, Qt::CrossCursor );
+            MAP_BUILTIN( PointerStyle::Wait, Qt::WaitCursor );
+            MAP_BUILTIN( PointerStyle::NSize, Qt::SizeVerCursor );
+            MAP_BUILTIN( PointerStyle::SSize, Qt::SizeVerCursor );
+            MAP_BUILTIN( PointerStyle::WSize, Qt::SizeHorCursor );
+            MAP_BUILTIN( PointerStyle::ESize, Qt::SizeHorCursor );
+
+            MAP_BUILTIN( PointerStyle::NWSize, Qt::SizeFDiagCursor );
+            MAP_BUILTIN( PointerStyle::NESize, Qt::SizeBDiagCursor );
+            MAP_BUILTIN( PointerStyle::SWSize, Qt::SizeBDiagCursor );
+            MAP_BUILTIN( PointerStyle::SESize, Qt::SizeFDiagCursor );
+#if 0
+            MAP_BUILTIN( PointerStyle::WindowNSize, GDK_TOP_SIDE );
+            MAP_BUILTIN( PointerStyle::WindowSSize, GDK_BOTTOM_SIDE );
+            MAP_BUILTIN( PointerStyle::WindowWSize, GDK_LEFT_SIDE );
+            MAP_BUILTIN( PointerStyle::WindowESize, GDK_RIGHT_SIDE );
+#endif
+            MAP_BUILTIN( PointerStyle::WindowNWSize, Qt::SizeFDiagCursor );
+            MAP_BUILTIN( PointerStyle::WindowNESize, Qt::SizeBDiagCursor );
+            MAP_BUILTIN( PointerStyle::WindowSWSize, Qt::SizeBDiagCursor );
+            MAP_BUILTIN( PointerStyle::WindowSESize, Qt::SizeFDiagCursor );
+
+            MAP_BUILTIN( PointerStyle::HSizeBar, Qt::SizeHorCursor );
+            MAP_BUILTIN( PointerStyle::VSizeBar, Qt::SizeVerCursor );
+
+            MAP_BUILTIN( PointerStyle::RefHand, Qt::OpenHandCursor );
+            MAP_BUILTIN( PointerStyle::Hand, Qt::OpenHandCursor );
+#if 0
+            MAP_BUILTIN( PointerStyle::Pen, GDK_PENCIL );
+#endif
+            MAP_BUILTIN( PointerStyle::HSplit, Qt::SizeHorCursor );
+            MAP_BUILTIN( PointerStyle::VSplit, Qt::SizeVerCursor );
+
+            MAP_BUILTIN( PointerStyle::Move, Qt::SizeAllCursor );
+
+            MAP_BUILTIN( PointerStyle::Null, Qt::BlankCursor );
+            MAKE_CURSOR( PointerStyle::Magnify, magnify_ );
+            MAKE_CURSOR( PointerStyle::Fill, fill_ );
+            MAKE_CURSOR( PointerStyle::MoveData, movedata_ );
+            MAKE_CURSOR( PointerStyle::CopyData, copydata_ );
+            MAKE_CURSOR( PointerStyle::MoveFile, movefile_ );
+            MAKE_CURSOR( PointerStyle::CopyFile, copyfile_ );
+            MAKE_CURSOR( PointerStyle::MoveFiles, movefiles_ );
+            MAKE_CURSOR( PointerStyle::CopyFiles, copyfiles_ );
+            MAKE_CURSOR( PointerStyle::NotAllowed, nodrop_ );
+            MAKE_CURSOR( PointerStyle::Rotate, rotate_ );
+            MAKE_CURSOR( PointerStyle::HShear, hshear_ );
+            MAKE_CURSOR( PointerStyle::VShear, vshear_ );
+            MAKE_CURSOR( PointerStyle::DrawLine, drawline_ );
+            MAKE_CURSOR( PointerStyle::DrawRect, drawrect_ );
+            MAKE_CURSOR( PointerStyle::DrawPolygon, drawpolygon_ );
+            MAKE_CURSOR( PointerStyle::DrawBezier, drawbezier_ );
+            MAKE_CURSOR( PointerStyle::DrawArc, drawarc_ );
+            MAKE_CURSOR( PointerStyle::DrawPie, drawpie_ );
+            MAKE_CURSOR( PointerStyle::DrawCircleCut, drawcirclecut_ );
+            MAKE_CURSOR( PointerStyle::DrawEllipse, drawellipse_ );
+            MAKE_CURSOR( PointerStyle::DrawConnect, drawconnect_ );
+            MAKE_CURSOR( PointerStyle::DrawText, drawtext_ );
+            MAKE_CURSOR( PointerStyle::Mirror, mirror_ );
+            MAKE_CURSOR( PointerStyle::Crook, crook_ );
+            MAKE_CURSOR( PointerStyle::Crop, crop_ );
+            MAKE_CURSOR( PointerStyle::MovePoint, movepoint_ );
+            MAKE_CURSOR( PointerStyle::MoveBezierWeight, movebezierweight_ );
+            MAKE_CURSOR( PointerStyle::DrawFreehand, drawfreehand_ );
+            MAKE_CURSOR( PointerStyle::DrawCaption, drawcaption_ );
+            MAKE_CURSOR( PointerStyle::LinkData, linkdata_ );
+            MAKE_CURSOR( PointerStyle::MoveDataLink, movedlnk_ );
+            MAKE_CURSOR( PointerStyle::CopyDataLink, copydlnk_ );
+            MAKE_CURSOR( PointerStyle::LinkFile, linkfile_ );
+            MAKE_CURSOR( PointerStyle::MoveFileLink, moveflnk_ );
+            MAKE_CURSOR( PointerStyle::CopyFileLink, copyflnk_ );
+            MAKE_CURSOR( PointerStyle::Chart, chart_ );
+            MAKE_CURSOR( PointerStyle::Detective, detective_ );
+            MAKE_CURSOR( PointerStyle::PivotCol, pivotcol_ );
+            MAKE_CURSOR( PointerStyle::PivotRow, pivotrow_ );
+            MAKE_CURSOR( PointerStyle::PivotField, pivotfld_ );
+            MAKE_CURSOR( PointerStyle::PivotDelete, pivotdel_ );
+            MAKE_CURSOR( PointerStyle::Chain, chain_ );
+            MAKE_CURSOR( PointerStyle::ChainNotAllowed, chainnot_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollN, asn_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollS, ass_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollW, asw_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollE, ase_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollNW, asnw_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollNE, asne_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollSW, assw_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollSE, asse_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollNS, asns_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollWE, aswe_ );
+            MAKE_CURSOR( PointerStyle::AutoScrollNSWE, asnswe_ );
+            MAKE_CURSOR( PointerStyle::TextVertical, vertcurs_ );
+
+            MAKE_CURSOR( PointerStyle::TabSelectS, tblsels_ );
+            MAKE_CURSOR( PointerStyle::TabSelectE, tblsele_ );
+            MAKE_CURSOR( PointerStyle::TabSelectSE, tblselse_ );
+            MAKE_CURSOR( PointerStyle::TabSelectW, tblselw_ );
+            MAKE_CURSOR( PointerStyle::TabSelectSW, tblselsw_ );
+
+            MAKE_CURSOR( PointerStyle::HideWhitespace, hidewhitespace_ );
+            MAKE_CURSOR( PointerStyle::ShowWhitespace, showwhitespace_ );
+        default:
+            break;
+        }
+        if( !pCursor )
+        {
+            pCursor = new QCursor( Qt::ArrowCursor );
+            SAL_WARN( "vcl.qt5", "pointer " << static_cast<int>(ePointerStyle) 
<< "not implemented" );
+        }
+
+        m_aCursors[ ePointerStyle ] = pCursor;
+    }
+
+    return *m_aCursors[ ePointerStyle ];
+}
+
+
 void Qt5Data::ErrorTrapPush()
 {
 }
diff --git a/vcl/qt5/Qt5Data.hxx b/vcl/qt5/Qt5Data.hxx
index 31859ce9637c..75e1a813e1f9 100644
--- a/vcl/qt5/Qt5Data.hxx
+++ b/vcl/qt5/Qt5Data.hxx
@@ -21,14 +21,23 @@
 
 #include <unx/gendata.hxx>
 
+#include <o3tl/enumarray.hxx>
+#include <vcl/ptrstyle.hxx>
+
+class QCursor;
+
 class Qt5Data : public GenericUnixSalData
 {
+    o3tl::enumarray<PointerStyle, QCursor*> m_aCursors;
+
 public:
     explicit Qt5Data( SalInstance *pInstance );
     virtual ~Qt5Data() override;
 
     virtual void ErrorTrapPush() override;
     virtual bool ErrorTrapPop( bool bIgnoreError = true ) override;
+
+    QCursor& getCursor( PointerStyle ePointerStyle );
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index b6939863a125..0eb1a6e6bc05 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -23,6 +23,7 @@
 #include "Qt5Instance.hxx"
 #include "Qt5Graphics.hxx"
 #include "Qt5Widget.hxx"
+#include "Qt5Data.hxx"
 
 #include <QtCore/QPoint>
 #include <QtCore/QSize>
@@ -46,6 +47,7 @@ static void SvpDamageHandler( void *handle,
 Qt5Frame::Qt5Frame( Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool 
bUseCairo )
     : m_bUseCairo( bUseCairo )
     , m_bGraphicsInUse( false )
+    , m_ePointerStyle( PointerStyle::Arrow )
 {
     Qt5Instance *pInst = static_cast<Qt5Instance*>( GetSalData()->m_pInstance 
);
     pInst->insertFrame( this );
@@ -339,6 +341,14 @@ void Qt5Frame::ToTop( SalFrameToTop nFlags )
 
 void Qt5Frame::SetPointer( PointerStyle ePointerStyle )
 {
+    QWindow *pWindow = m_pQWidget->window()->windowHandle();
+    if( !pWindow )
+        return;
+    if( ePointerStyle == m_ePointerStyle )
+        return;
+    m_ePointerStyle = ePointerStyle;
+
+    pWindow->setCursor( static_cast<Qt5Data*>( GetSalData() )->getCursor( 
ePointerStyle ) );
 }
 
 void Qt5Frame::CaptureMouse( bool bMouse )
diff --git a/vcl/qt5/Qt5Frame.hxx b/vcl/qt5/Qt5Frame.hxx
index 538b5eabed9c..1d736bfb280f 100644
--- a/vcl/qt5/Qt5Frame.hxx
+++ b/vcl/qt5/Qt5Frame.hxx
@@ -50,6 +50,7 @@ class Qt5Frame
     bool                            m_bGraphicsInUse;
     SalFrameStyleFlags              m_nStyle;
     Qt5Frame                       *m_pParent;
+    PointerStyle                    m_ePointerStyle;
 
     bool isChild( bool bPlug = true, bool bSysChild = true )
     {
commit 1d46af843d4181d58bd3953634ec0909d62f1b4a
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Oct 30 19:05:41 2017 +0100

    QT5 first stab on implementing CommonSalLayout
    
    CommonSalLayout doesn't rally have an interface. It's cluttered
    with #ifdefs. Currently we have to move the Qt5Font into the
    VCL library. Someone should refactor this...
    
    Doen't render any text yet, but reports some sizes.
    
    Eventually that would cut down the public interface again.
    
    Change-Id: I12f32affb05b37e070c6cbc80db01779f84590b6

diff --git a/config_host/config_qt5.h.in b/config_host/config_qt5.h.in
index cdce1af7800c..51bb58566f2b 100644
--- a/config_host/config_qt5.h.in
+++ b/config_host/config_qt5.h.in
@@ -5,6 +5,7 @@ Settings for QT5 integration.
 #ifndef CONFIG_QT5_H
 #define CONFIG_QT5_H
 
+#define ENABLE_QT5 0
 #define QT5_HAVE_GLIB 0
 
 #endif
diff --git a/vcl/CustomTarget_qt5_moc.mk b/vcl/CustomTarget_qt5_moc.mk
index 8d22eb6e9288..60d5df34d405 100644
--- a/vcl/CustomTarget_qt5_moc.mk
+++ b/vcl/CustomTarget_qt5_moc.mk
@@ -9,12 +9,12 @@
 
 $(eval $(call gb_CustomTarget_CustomTarget,vcl/qt5))
 
-$(call gb_CustomTarget_get_target,vcl/unx/qt5) : \
+$(call gb_CustomTarget_get_target,vcl/qt5) : \
        $(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5Instance.moc \
        $(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5Timer.moc \
        $(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5Widget.moc \
 
-$(call gb_CustomTarget_get_workdir,vcl/unx/qt5)/%.moc : \
+$(call gb_CustomTarget_get_workdir,vcl/qt5)/%.moc : \
                $(SRCDIR)/vcl/qt5/%.hxx \
                | $(call gb_CustomTarget_get_workdir,vcl/qt5)/.dir
        $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),MOC,1)
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 7481e87ed705..29d280abd444 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -722,4 +722,22 @@ ifeq ($(OS),WNT)
 $(eval $(call gb_Library_use_package,vcl,postprocess_images))
 endif
 
+ifeq ($(ENABLE_QT5),TRUE)
+$(eval $(call gb_Library_use_externals,vcl,\
+       qt5 \
+))
+$(eval $(call gb_Library_add_defs,vcl,\
+    $(QT5_CFLAGS) \
+))
+$(eval $(call gb_Library_add_libs,vcl,\
+    $(QT5_LIBS) \
+))
+$(eval $(call gb_Library_add_cxxflags,vcl,\
+    $(QT5_CFLAGS) \
+))
+$(eval $(call gb_Library_add_exception_objects,vcl,\
+    vcl/qt5/Qt5Font \
+))
+endif
+
 # vim: set noet sw=4 ts=4:
diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index 333812f939bb..d82b7d2fcd31 100644
--- a/vcl/Library_vclplug_qt5.mk
+++ b/vcl/Library_vclplug_qt5.mk
@@ -53,11 +53,14 @@ $(eval $(call gb_Library_use_libraries,vclplug_qt5,\
 ))
 
 $(eval $(call gb_Library_use_externals,vclplug_qt5,\
-       boost_headers \
-       cairo \
-       icuuc \
-       qt5 \
-       epoxy \
+    boost_headers \
+    cairo \
+    epoxy \
+    graphite \
+    harfbuzz \
+    icu_headers \
+    icuuc \
+    qt5 \
 ))
 
 $(eval $(call gb_Library_add_defs,vclplug_qt5,\
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 02eef73a1dc8..a44fee5cfe10 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -20,6 +20,8 @@
 #ifndef INCLUDED_VCL_INC_COMMONSALLAYOUT_HXX
 #define INCLUDED_VCL_INC_COMMONSALLAYOUT_HXX
 
+#include <config_qt5.h>
+
 #include <com/sun/star/i18n/XBreakIterator.hpp>
 
 #ifdef _WIN32
@@ -37,8 +39,19 @@
 #include <hb-icu.h>
 #include <hb-ot.h>
 
-class CommonSalLayout : public GenericSalLayout
+#if ENABLE_QT5
+class Qt5Font;
+#endif
+
+class VCL_DLLPUBLIC CommonSalLayout : public GenericSalLayout
 {
+#if ENABLE_QT5
+    friend hb_blob_t*       getFontTable(hb_face_t*, hb_tag_t, void*);
+    explicit                CommonSalLayout(const FontSelectPattern &rFSP,
+                                            FreetypeFont *pFreetypeFont,
+                                            Qt5Font *pFont, bool bUseQt5);
+#endif
+
     hb_font_t*              mpHbFont;
     const FontSelectPattern& mrFontSelData;
     css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
@@ -50,7 +63,11 @@ class CommonSalLayout : public GenericSalLayout
 #elif defined(MACOSX) || defined(IOS)
     const CoreTextStyle&    mrCoreTextStyle;
 #else
-    FreetypeFont&           mrFreetypeFont;
+    FreetypeFont*           mpFreetypeFont;
+#if ENABLE_QT5
+    const bool              mbUseQt5;
+    Qt5Font*                mpQFont;
+#endif
 #endif
 
     void                    ParseFeatures(const OUString& name);
@@ -76,7 +93,11 @@ public:
     const CoreTextStyle&    getFontData() const { return mrCoreTextStyle; };
 #else
     explicit                CommonSalLayout(FreetypeFont&);
-    const FreetypeFont&     getFontData() const { return mrFreetypeFont; };
+    const FreetypeFont*     getFreetypeFont() const { return mpFreetypeFont; };
+#if ENABLE_QT5
+    explicit                CommonSalLayout(Qt5Font&);
+    const Qt5Font*          getQt5Font() const { return mpQFont; };
+#endif
 #endif
 
     virtual void            InitFont() const override;
diff --git a/vcl/inc/impfontmetricdata.hxx b/vcl/inc/impfontmetricdata.hxx
index 14ad323b9b77..fd15e5765164 100644
--- a/vcl/inc/impfontmetricdata.hxx
+++ b/vcl/inc/impfontmetricdata.hxx
@@ -32,7 +32,7 @@ typedef tools::SvRef<ImplFontMetricData> 
ImplFontMetricDataRef;
 class OutputDevice;
 class FontSelectPattern;
 
-class ImplFontMetricData : public FontAttributes, public SvRefBase
+class VCL_DLLPUBLIC ImplFontMetricData : public FontAttributes, public 
SvRefBase
 {
 public:
     explicit        ImplFontMetricData( const FontSelectPattern& );
diff --git a/vcl/inc/qt5/Qt5Font.hxx b/vcl/inc/qt5/Qt5Font.hxx
new file mode 100644
index 000000000000..d8981578831a
--- /dev/null
+++ b/vcl/inc/qt5/Qt5Font.hxx
@@ -0,0 +1,43 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/dllapi.h>
+#include <QtGui/QFont>
+
+#include <fontselect.hxx>
+#include <hb-ot.h>
+
+class VCL_DLLPUBLIC Qt5Font : public QFont
+{
+    const FontSelectPattern m_aFontSelData;
+    hb_font_t* m_pHbFont;
+
+public:
+    Qt5Font( const FontSelectPattern& rFSP)
+        : m_aFontSelData( rFSP ), m_pHbFont( nullptr ) {}
+    virtual ~Qt5Font();
+
+    hb_font_t*                GetHbFont() const { return m_pHbFont; }
+    void                      SetHbFont( hb_font_t* pHbFont ) { m_pHbFont = 
pHbFont; }
+    const FontSelectPattern&  GetFontSelData() const { return m_aFontSelData; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Font.cxx b/vcl/qt5/Qt5Font.cxx
new file mode 100644
index 000000000000..8ad5e2b0c040
--- /dev/null
+++ b/vcl/qt5/Qt5Font.cxx
@@ -0,0 +1,26 @@
+/* -*- 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 <qt5/Qt5Font.hxx>
+
+Qt5Font::~Qt5Font()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx
index 701509b06108..347f6bb58ba5 100644
--- a/vcl/qt5/Qt5FontFace.cxx
+++ b/vcl/qt5/Qt5FontFace.cxx
@@ -65,7 +65,7 @@ sal_IntPtr Qt5FontFace::GetFontId() const
     return reinterpret_cast<sal_IntPtr>( &m_aFontId );
 }
 
-const FontCharMapRef Qt5FontFace::GetFontCharMap()
+const FontCharMapRef Qt5FontFace::GetFontCharMap() const
 {
     if( m_xCharMap.is() )
         return m_xCharMap;
@@ -88,7 +88,7 @@ const FontCharMapRef Qt5FontFace::GetFontCharMap()
     return m_xCharMap;
 }
 
-bool Qt5FontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities)
+bool Qt5FontFace::GetFontCapabilities(vcl::FontCapabilities 
&rFontCapabilities) const
 {
     // read this only once per font
     if( m_bFontCapabilitiesRead )
diff --git a/vcl/qt5/Qt5FontFace.hxx b/vcl/qt5/Qt5FontFace.hxx
index 76b8fdee99f1..7cfbdf8be702 100644
--- a/vcl/qt5/Qt5FontFace.hxx
+++ b/vcl/qt5/Qt5FontFace.hxx
@@ -44,8 +44,8 @@ public:
 
     int                      GetFontTable( const char pTagName[5], unsigned 
char* ) const;
 
-    const FontCharMapRef     GetFontCharMap();
-    bool                     GetFontCapabilities( vcl::FontCapabilities 
&rFontCapabilities );
+    const FontCharMapRef     GetFontCharMap() const;
+    bool                     GetFontCapabilities( vcl::FontCapabilities 
&rFontCapabilities ) const;
     bool                     HasChar( sal_uInt32 cChar ) const;
 
 protected:
@@ -53,10 +53,10 @@ protected:
                              Qt5FontFace( const FontAttributes& rFA, const 
QString &rFontID );
 
 private:
-    const QString            m_aFontId;
-    FontCharMapRef           m_xCharMap;
-    vcl::FontCapabilities    m_aFontCapabilities;
-    bool                     m_bFontCapabilitiesRead;
+    const QString                    m_aFontId;
+    mutable FontCharMapRef           m_xCharMap;
+    mutable vcl::FontCapabilities    m_aFontCapabilities;
+    mutable bool                     m_bFontCapabilitiesRead;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx
index 1d0d15677eb4..aebb486c2453 100644
--- a/vcl/qt5/Qt5Graphics.cxx
+++ b/vcl/qt5/Qt5Graphics.cxx
@@ -30,6 +30,9 @@ Qt5Graphics::Qt5Graphics( Qt5Frame *pFrame )
     : m_pFrame( pFrame )
     , m_pQImage( nullptr )
     , m_pFontCollection( nullptr )
+    , m_pFontData{ nullptr, }
+    , m_pTextStyle{ nullptr, }
+    , m_aTextColor( MAKE_SALCOLOR(0x00, 0x00, 0x00) )
 {
 }
 
@@ -37,11 +40,17 @@ Qt5Graphics::Qt5Graphics( QImage *pQImage )
     : m_pFrame( nullptr )
     , m_pQImage( pQImage )
     , m_pFontCollection( nullptr )
+    , m_pFontData{ nullptr, }
+    , m_pTextStyle{ nullptr, }
+    , m_aTextColor( MAKE_SALCOLOR(0x00, 0x00, 0x00) )
 {
 }
 
 Qt5Graphics::~Qt5Graphics()
 {
+    // release the text styles
+    for (int i = 0; i < MAX_FALLBACK; ++i)
+        delete m_pTextStyle[ i ];
 }
 
 void Qt5Graphics::PreparePainter()
diff --git a/vcl/qt5/Qt5Graphics.hxx b/vcl/qt5/Qt5Graphics.hxx
index b021134e54b7..d9f74a05b919 100644
--- a/vcl/qt5/Qt5Graphics.hxx
+++ b/vcl/qt5/Qt5Graphics.hxx
@@ -25,9 +25,10 @@
 
 #include <QtGui/QRegion>
 
+class Qt5Font;
+class Qt5FontFace;
 class Qt5Frame;
 class PhysicalFontCollection;
-class PhysicalFontFace;
 class QImage;
 class QPainter;
 
@@ -39,8 +40,11 @@ class Qt5Graphics : public SalGraphics
     QImage                       *m_pQImage;
     QRegion                       m_aClipRegion;
     std::unique_ptr< QPainter >   m_pPainter;
+
     PhysicalFontCollection       *m_pFontCollection;
-    PhysicalFontFace             *m_pFont;
+    const Qt5FontFace            *m_pFontData[ MAX_FALLBACK ];
+    Qt5Font                      *m_pTextStyle[ MAX_FALLBACK ];
+    SalColor                      m_aTextColor;
 
     void PreparePainter();
 
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index fe6931c84458..0053a56c412d 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -19,34 +19,78 @@
 
 #include "Qt5Graphics.hxx"
 #include "Qt5FontFace.hxx"
+#include <qt5/Qt5Font.hxx>
 
 #include <vcl/fontcharmap.hxx>
 
+#include <CommonSalLayout.hxx>
 #include <PhysicalFontCollection.hxx>
 
 #include <QtGui/QFontDatabase>
+#include <QtGui/QRawFont>
 #include <QtCore/QStringList>
 
 void Qt5Graphics::SetTextColor( SalColor nSalColor )
 {
+    m_aTextColor = nSalColor;
 }
 
-void Qt5Graphics::SetFont( const FontSelectPattern*, int nFallbackLevel )
+void Qt5Graphics::SetFont( const FontSelectPattern* pReqFont, int 
nFallbackLevel )
 {
+    // release the text styles
+    for (int i = nFallbackLevel; i < MAX_FALLBACK; ++i)
+    {
+        if ( !m_pTextStyle[ i ] )
+            break;
+        delete m_pTextStyle[ i ];
+        m_pTextStyle[ i ] = nullptr;
+    }
+
+    if( !pReqFont )
+        // handle release-font-resources request
+        m_pFontData[ nFallbackLevel ] = nullptr;
+    else
+    {
+        m_pFontData[ nFallbackLevel ] = static_cast<const Qt5FontFace*>( 
pReqFont->mpFontData );
+        m_pTextStyle[ nFallbackLevel ] = new Qt5Font( *pReqFont );
+    }
 }
 
 void Qt5Graphics::GetFontMetric( ImplFontMetricDataRef &rFMD, int 
nFallbackLevel )
 {
+    QRawFont aRawFont( QRawFont::fromFont( *m_pTextStyle[ nFallbackLevel ] ) );
+
+    QByteArray aHheaTable = aRawFont.fontTable( "hhea" );
+    std::vector<uint8_t> rHhea(aHheaTable.data(), aHheaTable.data() + 
aHheaTable.size() );
+
+    QByteArray aOs2Table = aRawFont.fontTable( "OS/2" );
+    std::vector<uint8_t> rOS2(aHheaTable.data(), aHheaTable.data() + 
aHheaTable.size() );
+
+    rFMD->ImplCalcLineSpacing( rHhea, rOS2, aRawFont.unitsPerEm() );
+
+    rFMD->SetWidth( aRawFont.averageCharWidth() );
+
+    const QChar nKashidaCh[ 2 ] = { 0x06, 0x40 };
+    quint32 nKashidaGid = 0;
+    QPointF aPoint;
+    int nNumGlyphs;
+    if( aRawFont.glyphIndexesForChars( nKashidaCh, 1, &nKashidaGid, 
&nNumGlyphs )
+            && aRawFont.advancesForGlyphIndexes( &nKashidaGid, &aPoint, 1 ) )
+        rFMD->SetMinKashida( lrint(aPoint.rx()) );
 }
 
 const FontCharMapRef Qt5Graphics::GetFontCharMap() const
 {
-    return nullptr;
+    if( !m_pFontData[ 0 ] )
+        return FontCharMapRef( new FontCharMap() );
+    return m_pFontData[ 0 ]->GetFontCharMap();
 }
 
 bool Qt5Graphics::GetFontCapabilities(vcl::FontCapabilities 
&rFontCapabilities) const
 {
-    return false;
+    if( !m_pFontData[ 0 ] )
+        return false;
+    return m_pFontData[ 0 ]->GetFontCapabilities( rFontCapabilities );
 }
 
 void Qt5Graphics::GetDevFontList( PhysicalFontCollection* pPFC )
@@ -90,7 +134,7 @@ void Qt5Graphics::FreeEmbedFontData( const void* pData, long 
nDataLen )
 {
 }
 
-void Qt5Graphics::GetGlyphWidths( const PhysicalFontFace*, bool bVertical,
+void Qt5Graphics::GetGlyphWidths( const PhysicalFontFace* pPFF, bool bVertical,
                                   std::vector< sal_Int32 >& rWidths,
                                   Ucs2UIntMap& rUnicodeEnc )
 {
@@ -108,6 +152,8 @@ bool Qt5Graphics::GetGlyphOutline( const GlyphItem&, 
basegfx::B2DPolyPolygon& )
 
 SalLayout* Qt5Graphics::GetTextLayout( ImplLayoutArgs&, int nFallbackLevel )
 {
+    if( m_pTextStyle[ nFallbackLevel ] )
+        return new CommonSalLayout( *m_pTextStyle[ nFallbackLevel ] );
     return nullptr;
 }
 
diff --git a/vcl/source/gdi/CommonSalLayout.cxx 
b/vcl/source/gdi/CommonSalLayout.cxx
index 4f896e694b59..132766753174 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -29,7 +29,14 @@
 #include <unicode/uchar.h>
 #include <android/compatibility.hxx>
 
-static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* 
pUserData)
+#if ENABLE_QT5
+#include <qt5/Qt5Font.hxx>
+#include <QtGui/QRawFont>
+#else
+class Qt5Font;
+#endif
+
+hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* 
pUserData)
 {
     char pTagName[5];
     pTagName[0] = (char)(nTableTag >> 24);
@@ -62,9 +69,23 @@ static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t 
nTableTag, void* pU
         pFont->GetFontTable(pTagName, pBuffer);
     }
 #else
-    const unsigned char* pBuffer = nullptr;
-    FreetypeFont* pFont = static_cast<FreetypeFont*>(pUserData);
-    pBuffer = pFont->GetTable(pTagName, &nLength);
+    const char* pBuffer = nullptr;
+    CommonSalLayout *pLayout = static_cast<CommonSalLayout*>( pUserData );
+#if ENABLE_QT5
+    QByteArray aTable;
+    if ( pLayout->mbUseQt5 )
+    {
+        QRawFont aRawFont( QRawFont::fromFont( *pLayout->mpQFont ) );
+        aTable = aRawFont.fontTable( pTagName );
+        pBuffer = reinterpret_cast<const char*>( aTable.data() );
+        nLength = aTable.size();
+    }
+    else
+#endif
+    {
+        pBuffer = reinterpret_cast<const char*>(
+            pLayout->mpFreetypeFont->GetTable(pTagName, &nLength) );
+    }
 #endif
 
     hb_blob_t* pBlob = nullptr;
@@ -73,7 +94,7 @@ static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t 
nTableTag, void* pU
         pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), 
nLength, HB_MEMORY_MODE_READONLY,
                                pBuffer, [](void* data){ delete[] 
static_cast<unsigned char*>(data); });
 #else
-        pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), 
nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr);
+        pBlob = hb_blob_create(pBuffer, nLength, HB_MEMORY_MODE_READONLY, 
nullptr, nullptr);
 #endif
 
     return pBlob;
@@ -234,20 +255,51 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& 
rCoreTextStyle)
 }
 
 #else
-CommonSalLayout::CommonSalLayout(FreetypeFont& rFreetypeFont)
-:   mrFontSelData(rFreetypeFont.GetFontSelData())
-,   mrFreetypeFont(rFreetypeFont)
-,   mpVertGlyphs(nullptr)
+
+CommonSalLayout::CommonSalLayout(const FontSelectPattern &rFSP,
+                                 FreetypeFont *pFreetypeFont,
+                                 Qt5Font *pQt5Font, bool bUseQt5)
+    : mrFontSelData(rFSP)
+    , mpFreetypeFont(pFreetypeFont)
+#if ENABLE_QT5
+    , mbUseQt5(bUseQt5)
+    , mpQFont(pQt5Font)
+#endif
+    , mpVertGlyphs(nullptr)
 {
-    mpHbFont = rFreetypeFont.GetHbFont();
+#if ENABLE_QT5
+    if (mbUseQt5)
+        mpHbFont = mpQFont->GetHbFont();
+    else
+#endif
+        mpHbFont = mpFreetypeFont->GetHbFont();
     if (!mpHbFont)
     {
-        hb_face_t* pHbFace = hb_face_create_for_tables(getFontTable, 
&rFreetypeFont, nullptr);
+        hb_face_t* pHbFace = hb_face_create_for_tables(getFontTable, this, 
nullptr);
 
         mpHbFont = createHbFont(pHbFace);
-        mrFreetypeFont.SetHbFont(mpHbFont);
+#if ENABLE_QT5
+        if (mbUseQt5)
+            mpQFont->SetHbFont(mpHbFont);
+        else
+#endif
+            mpFreetypeFont->SetHbFont(mpHbFont);
     }
 }
+
+CommonSalLayout::CommonSalLayout(FreetypeFont& rFreetypeFont)
+    : CommonSalLayout(rFreetypeFont.GetFontSelData(),
+                      &rFreetypeFont, nullptr, false)
+{
+}
+
+#if ENABLE_QT5
+CommonSalLayout::CommonSalLayout(Qt5Font& rQFont)
+    : CommonSalLayout(rQFont.GetFontSelData(),
+                      nullptr, &rQFont, true)
+{
+}
+#endif
 #endif
 
 void CommonSalLayout::InitFont() const
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx 
b/vcl/unx/generic/gdi/cairotextrender.cxx
index 5b03eda92eef..d868ff701049 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -157,7 +157,7 @@ namespace
 
 void CairoTextRender::DrawTextLayout(const CommonSalLayout& rLayout)
 {
-    const FreetypeFont& rFont = rLayout.getFontData();
+    const FreetypeFont& rFont = *rLayout.getFreetypeFont();
 
     std::vector<cairo_glyph_t> cairo_glyphs;
     std::vector<int> glyph_extrarotation;
commit e2e948bf9fa7238d46cdb37e4a07dbc1672bd69e
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Tue Oct 24 19:49:45 2017 +0200

    QT5 implement cairo rendering path
    
    Instead of QImage, this uses cairo_surface_t internally and just
    blits the composed image in the Qt5Widgets paint function.
    
    To enable this rendering path set SAL_VCL_QT5_USE_CAIRO.
    
    Change-Id: Ieddda9bad2596ce46d7d07d4d7060e40d44997db

diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index 8274d90e8820..333812f939bb 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/qt5/Qt5Object \
     vcl/qt5/Qt5Printer \
     vcl/qt5/Qt5Timer \
+    vcl/qt5/Qt5Tools \
     vcl/qt5/Qt5VirtualDevice \
     vcl/qt5/Qt5Widget \
 ))
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index ff9dc769f00b..b6939863a125 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -32,12 +32,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;
@@ -85,11 +100,24 @@ 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 );
+}
+
 void Qt5Frame::TriggerPaintEvent()
 {
     QSize aSize( m_pQWidget->size() );
-    SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height(), true);
-    CallCallback(SalEvent::Paint, &aPaintEvt);
+    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()
@@ -97,22 +125,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->ChangeQImage( 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->ChangeQImage( 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;
 }
 
@@ -269,7 +318,6 @@ bool Qt5Frame::GetWindowState( SalFrameState* pState )
                            WindowStateMask::Height;
     }
 
-    TriggerPaintEvent();
     return true;
 }
 
diff --git a/vcl/qt5/Qt5Frame.hxx b/vcl/qt5/Qt5Frame.hxx
index 209561780414..538b5eabed9c 100644
--- a/vcl/qt5/Qt5Frame.hxx
+++ b/vcl/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,14 +62,19 @@ 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(); }
 
+    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/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index b790278cdce0..d44055b8e841 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -194,6 +194,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,
@@ -208,12 +209,24 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry,
                               const SalBitmap& rSalBitmap,
                               const SalBitmap& rTransparentBitmap )
 {
+    if( rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0
+            || rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0 )
+        return;
+
+    assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
+    assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
 }
 

... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to