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>
This commit is contained in:
parent
9d3cd2268c
commit
b6d5026b1f
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user