summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2017-10-30 16:11:09 +0100
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-11-06 12:05:32 +0100
commitefb96db1095c07155e30eac270d1ddcfb4c0fec2 (patch)
tree6adc2957313eba74bf7cf8588bbd0aa7e6b8e9ca /vcl
parente391db0974d6c3a8188b883a0927bed339436fbc (diff)
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
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vclplug_qt5.mk1
-rw-r--r--vcl/qt5/Qt5Graphics.cxx28
-rw-r--r--vcl/qt5/Qt5Graphics.hxx7
-rw-r--r--vcl/qt5/Qt5Graphics_GDI.cxx107
-rw-r--r--vcl/qt5/Qt5Painter.cxx56
-rw-r--r--vcl/qt5/Qt5Painter.hxx67
-rw-r--r--vcl/qt5/Qt5Widget.cxx1
7 files changed, 198 insertions, 69 deletions
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