summaryrefslogtreecommitdiff
path: root/vcl/inc
diff options
context:
space:
mode:
authorLuca Carlon <carlon.luca@gmail.com>2020-02-29 13:39:29 +0100
committerJan-Marek Glogowski <glogow@fbihome.de>2020-03-09 14:19:49 +0100
commit358991e3b0a49bb201c2f1e4be900ee99aac9aa8 (patch)
tree320852cd425045cbd1eff4198357bbaa05f348fe /vcl/inc
parent2c5655d72401e6b6e917ece381e879b30680d20f (diff)
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled, but it turns out, you can't really scale QStyle painting then. This patch series had a 2nd approach also used by Gtk+ currently, which relied on the scaling of ths Cairo surface, which works surprisingly good, but has to lie about the real DPI value, so nothing is scaled twice. Also all icons are then scaled instead of rendered with the proper resolution. When HiDPI support in Qt is enabled, and the application is started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported resolution, keeps the logical DPI value of 96 and changes the devicePixelRatio to the specified value. But LO still expects the real DPI values and sizes, so we have to multiply a lot of rectangles, sizes and positions. The current result is far from perfect, which you can see with the various graphics glitches, but it at least doesn't crash anymore in the ControlType::Editbox sizing code. The main problem is all the up and downscaling in the getNativeControlRegion code, so LO knows the size of the widgets for the correct layouting, since there seem to be no API to get the scaled values from Qt / QStyle. Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/inc')
-rw-r--r--vcl/inc/qt5/Qt5Frame.hxx1
-rw-r--r--vcl/inc/qt5/Qt5Graphics.hxx4
-rw-r--r--vcl/inc/qt5/Qt5GraphicsBase.hxx30
-rw-r--r--vcl/inc/qt5/Qt5Graphics_Controls.hxx40
-rw-r--r--vcl/inc/qt5/Qt5Painter.hxx10
-rw-r--r--vcl/inc/qt5/Qt5SvpGraphics.hxx4
-rw-r--r--vcl/inc/qt5/Qt5Tools.hxx12
7 files changed, 85 insertions, 16 deletions
diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx
index 5a88221565a3..0caf1bc3ef49 100644
--- a/vcl/inc/qt5/Qt5Frame.hxx
+++ b/vcl/inc/qt5/Qt5Frame.hxx
@@ -141,6 +141,7 @@ public:
QWidget* GetQWidget() const { return m_pQWidget; }
Qt5MainWindow* GetTopLevelWindow() const { return m_pTopLevel; }
QWidget* asChild() const;
+ qreal devicePixelRatioF() const;
void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
sal_Int32 nExtentsHeight) const;
diff --git a/vcl/inc/qt5/Qt5Graphics.hxx b/vcl/inc/qt5/Qt5Graphics.hxx
index c36d22267fd2..0a66271c34e5 100644
--- a/vcl/inc/qt5/Qt5Graphics.hxx
+++ b/vcl/inc/qt5/Qt5Graphics.hxx
@@ -27,6 +27,8 @@
#include <QtGui/QPainterPath>
#include <QtGui/QRegion>
+#include "Qt5GraphicsBase.hxx"
+
class PhysicalFontCollection;
class QImage;
class QPushButton;
@@ -35,7 +37,7 @@ class Qt5FontFace;
class Qt5Frame;
class Qt5Painter;
-class Qt5Graphics final : public SalGraphics
+class Qt5Graphics final : public SalGraphics, public Qt5GraphicsBase
{
friend class Qt5Bitmap;
friend class Qt5Painter;
diff --git a/vcl/inc/qt5/Qt5GraphicsBase.hxx b/vcl/inc/qt5/Qt5GraphicsBase.hxx
new file mode 100644
index 000000000000..ef7955186a6e
--- /dev/null
+++ b/vcl/inc/qt5/Qt5GraphicsBase.hxx
@@ -0,0 +1,30 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <QtWidgets/QApplication>
+
+class Qt5GraphicsBase
+{
+ qreal m_fDPR;
+
+protected:
+ Qt5GraphicsBase()
+ : m_fDPR(qApp ? qApp->devicePixelRatio() : 1.0)
+ {
+ }
+
+ void setDevicePixelRatioF(qreal fDPR) { m_fDPR = fDPR; }
+
+public:
+ qreal devicePixelRatioF() const { return m_fDPR; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/Qt5Graphics_Controls.hxx b/vcl/inc/qt5/Qt5Graphics_Controls.hxx
index f70804cea844..04503c7bdf17 100644
--- a/vcl/inc/qt5/Qt5Graphics_Controls.hxx
+++ b/vcl/inc/qt5/Qt5Graphics_Controls.hxx
@@ -31,13 +31,16 @@
#include <QtWidgets/QStyle>
#include <QtWidgets/QStyleOption>
+class Qt5GraphicsBase;
+
class Qt5Graphics_Controls final : public vcl::WidgetDrawInterface
{
std::unique_ptr<QImage> m_image;
QRect m_lastPopupRect;
+ Qt5GraphicsBase const& m_rGraphics;
public:
- Qt5Graphics_Controls();
+ Qt5Graphics_Controls(const Qt5GraphicsBase& rGraphics);
QImage* getImage() { return m_image.get(); }
@@ -60,19 +63,34 @@ private:
const QSize& contentsSize);
static QRect subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex* option,
QStyle::SubControl subControl);
+ static QRect subElementRect(QStyle::SubElement element, const QStyleOption* option);
- static void draw(QStyle::ControlElement element, QStyleOption* option, QImage* image,
- QStyle::State const state = QStyle::State_None, QRect rect = QRect());
- static void draw(QStyle::PrimitiveElement element, QStyleOption* option, QImage* image,
- QStyle::State const state = QStyle::State_None, QRect rect = QRect());
- static void draw(QStyle::ComplexControl element, QStyleOptionComplex* option, QImage* image,
- QStyle::State const state = QStyle::State_None);
- static void drawFrame(QStyle::PrimitiveElement element, QImage* image,
- QStyle::State const& state, bool bClip = true,
- QStyle::PixelMetric eLineMetric = QStyle::PM_DefaultFrameWidth);
+ void draw(QStyle::ControlElement element, QStyleOption* option, QImage* image,
+ QStyle::State const state = QStyle::State_None, QRect rect = QRect());
+ void draw(QStyle::PrimitiveElement element, QStyleOption* option, QImage* image,
+ QStyle::State const state = QStyle::State_None, QRect rect = QRect());
+ void draw(QStyle::ComplexControl element, QStyleOptionComplex* option, QImage* image,
+ QStyle::State const state = QStyle::State_None);
+ void drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State const& state,
+ bool bClip = true,
+ QStyle::PixelMetric eLineMetric = QStyle::PM_DefaultFrameWidth);
static void fillQStyleOptionTab(const ImplControlValue& value, QStyleOptionTab& sot);
- static void fullQStyleOptionTabWidgetFrame(QStyleOptionTabWidgetFrame& option);
+ void fullQStyleOptionTabWidgetFrame(QStyleOptionTabWidgetFrame& option, bool bDownscale);
+
+ enum class Round
+ {
+ Floor,
+ Ceil,
+ };
+
+ int downscale(int value, Round eRound);
+ int upscale(int value, Round eRound);
+ QRect downscale(const QRect& rect);
+ QRect upscale(const QRect& rect);
+ QSize downscale(const QSize& size, Round eRound);
+ QSize upscale(const QSize& size, Round eRound);
+ QPoint upscale(const QPoint& point, Round eRound);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/Qt5Painter.hxx b/vcl/inc/qt5/Qt5Painter.hxx
index 3434d80741a4..51ddc3d69695 100644
--- a/vcl/inc/qt5/Qt5Painter.hxx
+++ b/vcl/inc/qt5/Qt5Painter.hxx
@@ -42,16 +42,20 @@ public:
void update(int nx, int ny, int nw, int nh)
{
if (m_rGraphics.m_pFrame)
- m_aRegion += QRect(nx, ny, nw, nh);
+ m_aRegion += scaledQRect({ nx, ny, nw, nh }, 1 / m_rGraphics.devicePixelRatioF());
}
void update(const QRect& rRect)
{
if (m_rGraphics.m_pFrame)
- m_aRegion += rRect;
+ m_aRegion += scaledQRect(rRect, 1 / m_rGraphics.devicePixelRatioF());
}
- void update(const QRectF& rRectF) { update(rRectF.toAlignedRect()); }
+ void update(const QRectF& rRectF)
+ {
+ if (m_rGraphics.m_pFrame)
+ update(scaledQRect(rRectF.toAlignedRect(), 1 / m_rGraphics.devicePixelRatioF()));
+ }
void update()
{
diff --git a/vcl/inc/qt5/Qt5SvpGraphics.hxx b/vcl/inc/qt5/Qt5SvpGraphics.hxx
index 895023033468..2ea5e6ad9b09 100644
--- a/vcl/inc/qt5/Qt5SvpGraphics.hxx
+++ b/vcl/inc/qt5/Qt5SvpGraphics.hxx
@@ -22,9 +22,11 @@
#include <vclpluginapi.h>
#include <headless/svpgdi.hxx>
+#include "Qt5GraphicsBase.hxx"
+
class Qt5Frame;
-class VCLPLUG_QT5_PUBLIC Qt5SvpGraphics : public SvpSalGraphics
+class VCLPLUG_QT5_PUBLIC Qt5SvpGraphics : public SvpSalGraphics, public Qt5GraphicsBase
{
Qt5Frame* const m_pFrame;
diff --git a/vcl/inc/qt5/Qt5Tools.hxx b/vcl/inc/qt5/Qt5Tools.hxx
index 47f37d85c74d..88a85f89be55 100644
--- a/vcl/inc/qt5/Qt5Tools.hxx
+++ b/vcl/inc/qt5/Qt5Tools.hxx
@@ -54,6 +54,18 @@ inline QRect toQRect(const tools::Rectangle& rRect)
return QRect(rRect.Left(), rRect.Top(), rRect.GetWidth(), rRect.GetHeight());
}
+inline QRect toQRect(const tools::Rectangle& rRect, const qreal fScale)
+{
+ return QRect(floor(rRect.Left() * fScale), floor(rRect.Top() * fScale),
+ ceil(rRect.GetWidth() * fScale), ceil(rRect.GetHeight() * fScale));
+}
+
+inline QRect scaledQRect(const QRect& rRect, const qreal fScale)
+{
+ return QRect(floor(rRect.x() * fScale), floor(rRect.y() * fScale), ceil(rRect.width() * fScale),
+ ceil(rRect.height() * fScale));
+}
+
inline tools::Rectangle toRectangle(const QRect& rRect)
{
return tools::Rectangle(rRect.left(), rRect.top(), rRect.right(), rRect.bottom());