summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2017-07-07 14:01:29 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2017-07-07 14:25:20 +0000
commitb6d5026b1f8d7ed6424f9a395d47fc4c62d4751b (patch)
treed497f5253a808bafe385f3ecd741e019f29d05b5 /src
parent9d3cd2268ce3beafcf6fa886bb70d8463260d602 (diff)
QWidgets/drawutils: Handle device pixel ratio != 1
The panel drawing helpers have code drawing shadows that relies on working with integer coordinates and one pixel lines, which causes artifacts when Qt High DPI scaling is in effect. Add code that checks for device pixel ratio != 1 and in that case reverts out the Qt High DPI scaling transformation and scales the parameters so that the drawing code used device pixels. Task-number: QTBUG-58611 Task-number: QTBUG-59116 Change-Id: I8402044f3fd4dfcd349b31c573dcad12ae1f609f Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/widgets/styles/qdrawutil.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp
index 0b0583ea94..299dbb9f82 100644
--- a/src/widgets/styles/qdrawutil.cpp
+++ b/src/widgets/styles/qdrawutil.cpp
@@ -49,6 +49,35 @@
QT_BEGIN_NAMESPACE
+namespace {
+class PainterStateGuard {
+ Q_DISABLE_COPY(PainterStateGuard)
+public:
+ explicit PainterStateGuard(QPainter *p) : m_painter(p) {}
+ ~PainterStateGuard()
+ {
+ for ( ; m_level > 0; --m_level)
+ m_painter->restore();
+ }
+
+ void save()
+ {
+ m_painter->save();
+ ++m_level;
+ }
+
+ void restore()
+ {
+ m_painter->restore();
+ --m_level;
+ }
+
+private:
+ QPainter *m_painter;
+ int m_level= 0;
+};
+} // namespace
+
/*!
\headerfile <qdrawutil.h>
\title Drawing Utility Functions
@@ -213,6 +242,21 @@ void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
qWarning("qDrawShadeRect: Invalid parameters");
return;
}
+
+ PainterStateGuard painterGuard(p);
+ const qreal devicePixelRatio = p->device()->devicePixelRatioF();
+ if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
+ painterGuard.save();
+ const qreal inverseScale = qreal(1) / devicePixelRatio;
+ p->scale(inverseScale, inverseScale);
+ x = qRound(devicePixelRatio * x);
+ y = qRound(devicePixelRatio * y);
+ w = qRound(devicePixelRatio * w);
+ h = qRound(devicePixelRatio * h);
+ lineWidth = qRound(devicePixelRatio * lineWidth);
+ midLineWidth = qRound(devicePixelRatio * midLineWidth);
+ }
+
QPen oldPen = p->pen();
if (sunken)
p->setPen(pal.dark().color());
@@ -312,6 +356,20 @@ void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
qWarning("qDrawShadePanel: Invalid parameters");
}
+
+ PainterStateGuard painterGuard(p);
+ const qreal devicePixelRatio = p->device()->devicePixelRatioF();
+ if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
+ painterGuard.save();
+ const qreal inverseScale = qreal(1) / devicePixelRatio;
+ p->scale(inverseScale, inverseScale);
+ x = qRound(devicePixelRatio * x);
+ y = qRound(devicePixelRatio * y);
+ w = qRound(devicePixelRatio * w);
+ h = qRound(devicePixelRatio * h);
+ lineWidth = qRound(devicePixelRatio * lineWidth);
+ }
+
QColor shade = pal.dark().color();
QColor light = pal.light().color();
if (fill) {
@@ -389,6 +447,19 @@ static void qDrawWinShades(QPainter *p,
{
if (w < 2 || h < 2) // can't do anything with that
return;
+
+ PainterStateGuard painterGuard(p);
+ const qreal devicePixelRatio = p->device()->devicePixelRatioF();
+ if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
+ painterGuard.save();
+ const qreal inverseScale = qreal(1) / devicePixelRatio;
+ p->scale(inverseScale, inverseScale);
+ x = qRound(devicePixelRatio * x);
+ y = qRound(devicePixelRatio * y);
+ w = qRound(devicePixelRatio * w);
+ h = qRound(devicePixelRatio * h);
+ }
+
QPen oldPen = p->pen();
QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
p->setPen(c1);
@@ -518,6 +589,20 @@ void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
qWarning("qDrawPlainRect: Invalid parameters");
}
+
+ PainterStateGuard painterGuard(p);
+ const qreal devicePixelRatio = p->device()->devicePixelRatioF();
+ if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
+ painterGuard.save();
+ const qreal inverseScale = qreal(1) / devicePixelRatio;
+ p->scale(inverseScale, inverseScale);
+ x = qRound(devicePixelRatio * x);
+ y = qRound(devicePixelRatio * y);
+ w = qRound(devicePixelRatio * w);
+ h = qRound(devicePixelRatio * h);
+ lineWidth = qRound(devicePixelRatio * lineWidth);
+ }
+
QPen oldPen = p->pen();
QBrush oldBrush = p->brush();
p->setPen(c);