[Libreoffice-commits] core.git: Branch 'private/jmux/qt5' - 575 commits - android/source avmedia/Library_avmedia.mk avmedia/Library_avmediaogl.mk avmedia/Module_avmedia.mk avmedia/source basctl/source basegfx/source basegfx/test basic/inc basic/source bean/native binaryurp/source bin/gbuild-to-ide bin/gbuild-to-ideNS bridges/inc bridges/source canvas/source chart2/inc chart2/qa chart2/source codemaker/source comphelper/qa comphelper/source compilerplugins/clang config_host/config_features.h.in config_host/config_lgpl.h.in config_host/config_qt5.h.in config_host.mk.in configmgr/source configure.ac connectivity/qa connectivity/source cppcanvas/source cppuhelper/source cppu/qa cppu/source cpputools/source cui/inc cui/source cui/uiconfig dbaccess/inc dbaccess/source desktop/inc desktop/qa desktop/source dictionaries distro-configs/LibreOfficeFlatpak.conf distro-configs/LibreOfficeOssFuzz.conf download.lst drawinglayer/inc drawinglayer/source dtrans/source editeng/inc editeng/qa editeng/source embedde dobj/source embedserv/source emfio/inc emfio/source extensions/source external/coinmp external/collada2gltf external/curl external/firebird external/gpgme external/icu external/libabw external/libassuan external/libcdr external/libebook external/libepubgen external/libetonyek external/libfreehand external/libgltf external/libgpg-error external/libjpeg-turbo external/libmspub external/libmwaw external/libodfgen external/liborcus external/libpagemaker external/libqxp external/librevenge external/libstaroffice external/libvisio external/libwpd external/libwpg external/libwps external/libxslt external/libzmf external/Module_external.mk external/nss external/opencollada external/redland extras/Package_tplpresnt.mk extras/source filter/source forms/source formula/inc formula/source fpicker/source framework/inc framework/source .git-hooks/pre-commit helpcompiler/inc helpcompiler/source helpcontent2 hwpfilter/source i18nlangtag/source i18npool/inc i18npool/source i18npool/util i18nutil/sour ce icon-themes/tango idlc/inc idlc/source idl/inc idl/source include/avmedia include/basegfx include/com include/comphelper include/cppu include/cppuhelper include/helpcompiler include/i18nlangtag include/i18nutil include/jvmaccess include/jvmfwk include/LibreOfficeKit include/o3tl include/osl include/rtl include/sal include/salhelper include/sax include/sfx2 include/svl include/svtools include/svx include/systools include/test include/tools include/typelib include/ucbhelper include/uno include/unotools include/vcl io/qa ios/CustomTarget_iOS.mk ios/LibreOfficeKit ios/LibreOfficeLight io/source javaunohelper/source jurt/source jvmaccess/source jvmfwk/inc jvmfwk/plugins jvmfwk/source l10ntools/inc l10ntools/source libreofficekit/qa libreofficekit/source lingucomponent/source linguistic/source lotuswordpro/inc lotuswordpro/source Makefile.fetch mysqlc/source o3tl/CppunitTest_o3tl_tests.mk o3tl/qa odk/qa odk/source offapi/com offapi/UnoApi_offapi.mk officecfg/qa officecfg/registry onlin eupdate/inc oox/inc oox/qa oox/source opencl/inc opencl/source package/inc package/source postprocess/Rdb_services.mk pyuno/source pyuno/zipcore qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/tests readlicense_oo/license README.md registry/source registry/tools remotebridges/source reportdesign/source RepositoryExternal.mk Repository.mk sal/cppunittester salhelper/qa salhelper/source sal/osl sal/qa sal/rtl sal/textenc sax/inc sax/qa sax/source scaddins/source sccomp/source sc/CppunitTest_sc_cellrangesobj.mk sc/CppunitTest_sc_filterdescriptorbaseobj.mk sc/CppunitTest_sc_subtotaldescriptorbaseobj.mk sc/inc sc/Module_sc.mk scp2/InstallScript_setup_osl.mk scp2/Module_scp2.mk scp2/source sc/qa sc/res scripting/source sc/source sc/uiconfig sdext/source sd/inc sd/qa sd/sdi sd/source setup_native/source sfx2/CppunitTest_sfx2_misc.mk sfx2/Module_sfx2.mk sfx2/qa sfx2/sdi sfx2/source sfx2/uiconfig shell/inc shell/qa shell/source slideshow/source smoketest/smoketest.cxx smoketest/smoketest_ too.cxx solenv/bin solenv/clang-cl solenv/CompilerTest_compilerplugins_clang.mk solenv/flatpak-manifest.in solenv/gbuild soltools/cpp sot/source starmath/inc starmath/qa starmath/source stoc/source store/source svgio/inc svl/qa svl/source svtools/inc svtools/qa svtools/source svx/inc svx/source svx/uiconfig sw/CppunitTest_sw_ooxmlexport10.mk sw/CppunitTest_sw_ooxmlexport11.mk sw/inc sw/Module_sw.mk sw/qa sw/source sw/uiconfig sysui/CustomTarget_share.mk test/Library_subsequenttest.mk test/source testtools/source toolkit/inc toolkit/source tools/qa tools/source ucbhelper/source ucb/qa ucb/source UnoControls/inc UnoControls/source unodevtools/inc unodevtools/source unoidl/source unotest/source unotools/qa unotools/source unoxml/source uui/source vbahelper/source vcl/backendtest vcl/CustomTarget_kde5_moc.mk vcl/CustomTarget_kf5_moc.mk vcl/CustomTarget_qt5_moc.mk vcl/Executable_cgmfuzzer.mk vcl/Executable_pptfuzzer.mk vcl/headless vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_kde5.mk v cl/Library_vclplug_qt5.mk vcl/Module_vcl.mk vcl/opengl vcl/osx vcl/qa vcl/qt5 vcl/quartz vcl/source vcl/uiconfig vcl/unx vcl/win vcl/workben winaccessibility/inc winaccessibility/source wizards/source writerfilter/source writerperfect/inc writerperfect/qa writerperfect/source xmlhelp/source xmloff/inc xmloff/qa xmloff/source xmlscript/source xmlsecurity/inc xmlsecurity/source
Jan-Marek Glogowski
glogow at fbihome.de
Tue Oct 31 02:21:38 UTC 2017
Rebased ref, commits from common ancestor:
commit 0bb69b373af256ab93a63175724040f436a9b738
Author: Jan-Marek Glogowski <glogow at 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 6fcdf9b9f83ff33bd3e517f9ca767e074daed4a2
Author: Jan-Marek Glogowski <glogow at 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 44671223a93ea06d18d46fb32563e6596d62f6b7
Author: Jan-Marek Glogowski <glogow at 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 f8b9c00e737456777a287918d149e8578a2fa4f7
Author: Jan-Marek Glogowski <glogow at 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 fe37c49d8d8e9d9368de9ab4f95c39754450bb11
Author: Jan-Marek Glogowski <glogow at 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 18b26a8e317ff5e75ceb0715844ceb2ee4fd7cd4
Author: Jan-Marek Glogowski <glogow at 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 ca1d00f1da5ddf7bade826d24ad0a44e8a4438bf
Author: Jan-Marek Glogowski <glogow at 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 35a3b9804eedfce65699c61a380331a29b17cf81
Author: Jan-Marek Glogowski <glogow at 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 c41fce6b4ee2432a50aea9f45ea56b0fa03d8375
Author: Jan-Marek Glogowski <glogow at 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 7f55a0e397e4b76259fc2b4d6a222a9b4fac834c
Author: Jan-Marek Glogowski <glogow at 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 c5480300a882339df311839763f17b1129811e55
Author: Jan-Marek Glogowski <glogow at 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 );
}
void Qt5Graphics::drawMask( const SalTwoRect& rPosAry,
- const SalBitmap& rSalBitmap,
- SalColor nMaskColor )
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor )
{
+ if( rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0
+ || rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0 )
+ return;
+
+ assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
+ assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
}
SalBitmap* Qt5Graphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
index dd2daf7e8b8b..4e36c6684936 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -27,8 +27,11 @@
#include "Qt5Object.hxx"
#include "Qt5Bitmap.hxx"
+#include <headless/svpvd.hxx>
+
#include <QtCore/QThread>
#include <QtWidgets/QApplication>
+#include <QtWidgets/QWidget>
#include <QtCore/QAbstractEventDispatcher>
#include <vclpluginapi.h>
@@ -38,9 +41,10 @@
#include <headless/svpdummies.hxx>
#include <headless/svpbmp.hxx>
-Qt5Instance::Qt5Instance( SalYieldMutex* pMutex )
+Qt5Instance::Qt5Instance( SalYieldMutex* pMutex, bool bUseCairo )
: SalGenericInstance( pMutex )
, m_postUserEventId( -1 )
+ , m_bUseCairo( bUseCairo )
{
m_postUserEventId = QEvent::registerEventType();
@@ -61,13 +65,13 @@ Qt5Instance::~Qt5Instance()
SalFrame* Qt5Instance::CreateChildFrame( SystemParentData* /*pParent*/, SalFrameStyleFlags nStyle )
{
- return new Qt5Frame( nullptr, nStyle );
+ return new Qt5Frame( nullptr, nStyle, m_bUseCairo );
}
SalFrame* Qt5Instance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
{
assert( !pParent || dynamic_cast<Qt5Frame*>( pParent ) );
- return new Qt5Frame( static_cast<Qt5Frame*>( pParent ), nStyle );
+ return new Qt5Frame( static_cast<Qt5Frame*>( pParent ), nStyle, m_bUseCairo );
}
void Qt5Instance::DestroyFrame( SalFrame* pFrame )
@@ -91,9 +95,18 @@ SalVirtualDevice* Qt5Instance::CreateVirtualDevice( SalGraphics* /* pGraphics */
DeviceFormat eFormat,
const SystemGraphicsData* /* pData */ )
{
- Qt5VirtualDevice* pVD = new Qt5VirtualDevice( eFormat, 1 );
- pVD->SetSize( nDX, nDY );
- return pVD;
+ if ( m_bUseCairo )
+ {
+ SvpSalVirtualDevice *pVD = new SvpSalVirtualDevice( eFormat, 1 );
+ pVD->SetSize( nDX, nDY );
+ return pVD;
+ }
+ else
+ {
+ Qt5VirtualDevice* pVD = new Qt5VirtualDevice( eFormat, 1 );
+ pVD->SetSize( nDX, nDY );
+ return pVD;
+ }
}
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list