Improve style drawing under DPR scaling

Line painting code originally designed for unscaled, aliased, pre-Qt4
drawing generally behaves better with a half pixel offset
applied. This fixes a heap of glitches when this code is run with a
device pixel ratio > 1.

Fixes: QTBUG-88934
Task-number: QTBUG-96223
Change-Id: I617b0ecc0be2593b34bf78349043f72b9ea4b20c
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit 7dd454e1b94aa48ab6a6886782f83ad9b590f170)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Eirik Aavitsland 2022-03-22 14:19:36 +01:00 committed by Qt Cherry-pick Bot
parent d8dce5aae6
commit 2643b98f27

View File

@ -127,6 +127,20 @@ void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
qWarning("qDrawShadeLine: Invalid parameters"); qWarning("qDrawShadeLine: Invalid parameters");
return; return;
} }
PainterStateGuard painterGuard(p);
const qreal devicePixelRatio = p->device()->devicePixelRatio();
if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
painterGuard.save();
const qreal inverseScale = qreal(1) / devicePixelRatio;
p->scale(inverseScale, inverseScale);
x1 = qRound(devicePixelRatio * x1);
y1 = qRound(devicePixelRatio * y1);
x2 = qRound(devicePixelRatio * x2);
y2 = qRound(devicePixelRatio * y2);
lineWidth = qRound(devicePixelRatio * lineWidth);
midLineWidth = qRound(devicePixelRatio * midLineWidth);
p->translate(0.5, 0.5);
}
int tlw = lineWidth*2 + midLineWidth; // total line width int tlw = lineWidth*2 + midLineWidth; // total line width
QPen oldPen = p->pen(); // save pen QPen oldPen = p->pen(); // save pen
if (sunken) if (sunken)
@ -256,6 +270,7 @@ void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
h = qRound(devicePixelRatio * h); h = qRound(devicePixelRatio * h);
lineWidth = qRound(devicePixelRatio * lineWidth); lineWidth = qRound(devicePixelRatio * lineWidth);
midLineWidth = qRound(devicePixelRatio * midLineWidth); midLineWidth = qRound(devicePixelRatio * midLineWidth);
p->translate(0.5, 0.5);
} }
QPen oldPen = p->pen(); QPen oldPen = p->pen();
@ -360,6 +375,7 @@ void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
PainterStateGuard painterGuard(p); PainterStateGuard painterGuard(p);
const qreal devicePixelRatio = p->device()->devicePixelRatio(); const qreal devicePixelRatio = p->device()->devicePixelRatio();
bool isTranslated = false;
if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
painterGuard.save(); painterGuard.save();
const qreal inverseScale = qreal(1) / devicePixelRatio; const qreal inverseScale = qreal(1) / devicePixelRatio;
@ -369,6 +385,8 @@ void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
w = qRound(devicePixelRatio * w); w = qRound(devicePixelRatio * w);
h = qRound(devicePixelRatio * h); h = qRound(devicePixelRatio * h);
lineWidth = qRound(devicePixelRatio * lineWidth); lineWidth = qRound(devicePixelRatio * lineWidth);
p->translate(0.5, 0.5);
isTranslated = true;
} }
QColor shade = pal.dark().color(); QColor shade = pal.dark().color();
@ -419,8 +437,11 @@ void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
lines << QLineF(x1--, y1++, x2--, y2); lines << QLineF(x1--, y1++, x2--, y2);
} }
p->drawLines(lines); p->drawLines(lines);
if (fill) // fill with fill color if (fill) { // fill with fill color
if (isTranslated)
p->translate(-0.5, -0.5);
p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill); p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
}
p->setPen(oldPen); // restore pen p->setPen(oldPen); // restore pen
} }
@ -451,6 +472,7 @@ static void qDrawWinShades(QPainter *p,
PainterStateGuard painterGuard(p); PainterStateGuard painterGuard(p);
const qreal devicePixelRatio = p->device()->devicePixelRatio(); const qreal devicePixelRatio = p->device()->devicePixelRatio();
bool isTranslated = false;
if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
painterGuard.save(); painterGuard.save();
const qreal inverseScale = qreal(1) / devicePixelRatio; const qreal inverseScale = qreal(1) / devicePixelRatio;
@ -459,6 +481,8 @@ static void qDrawWinShades(QPainter *p,
y = qRound(devicePixelRatio * y); y = qRound(devicePixelRatio * y);
w = qRound(devicePixelRatio * w); w = qRound(devicePixelRatio * w);
h = qRound(devicePixelRatio * h); h = qRound(devicePixelRatio * h);
p->translate(0.5, 0.5);
isTranslated = true;
} }
QPen oldPen = p->pen(); QPen oldPen = p->pen();
@ -475,8 +499,11 @@ static void qDrawWinShades(QPainter *p,
QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) }; QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
p->setPen(c4); p->setPen(c4);
p->drawPolyline(d, 3); p->drawPolyline(d, 3);
if (fill) if (fill) {
if (isTranslated)
p->translate(-0.5, -0.5);
p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill); p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
}
} }
p->setPen(oldPen); p->setPen(oldPen);
} }
@ -602,6 +629,7 @@ void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
w = qRound(devicePixelRatio * w); w = qRound(devicePixelRatio * w);
h = qRound(devicePixelRatio * h); h = qRound(devicePixelRatio * h);
lineWidth = qRound(devicePixelRatio * lineWidth); lineWidth = qRound(devicePixelRatio * lineWidth);
p->translate(0.5, 0.5);
} }
QPen oldPen = p->pen(); QPen oldPen = p->pen();