From 7dd454e1b94aa48ab6a6886782f83ad9b590f170 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 22 Mar 2022 14:19:36 +0100 Subject: Improve style drawing under DPR scaling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Pick-to: 6.3 Change-Id: I617b0ecc0be2593b34bf78349043f72b9ea4b20c Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qdrawutil.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'src/widgets/styles') diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp index 91c9275bb6..17837ace0d 100644 --- a/src/widgets/styles/qdrawutil.cpp +++ b/src/widgets/styles/qdrawutil.cpp @@ -127,6 +127,20 @@ void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, qWarning("qDrawShadeLine: Invalid parameters"); 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 QPen oldPen = p->pen(); // save pen if (sunken) @@ -256,6 +270,7 @@ void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, h = qRound(devicePixelRatio * h); lineWidth = qRound(devicePixelRatio * lineWidth); midLineWidth = qRound(devicePixelRatio * midLineWidth); + p->translate(0.5, 0.5); } QPen oldPen = p->pen(); @@ -360,6 +375,7 @@ void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, PainterStateGuard painterGuard(p); const qreal devicePixelRatio = p->device()->devicePixelRatio(); + bool isTranslated = false; if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { painterGuard.save(); 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); h = qRound(devicePixelRatio * h); lineWidth = qRound(devicePixelRatio * lineWidth); + p->translate(0.5, 0.5); + isTranslated = true; } 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); } 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->setPen(oldPen); // restore pen } @@ -451,6 +472,7 @@ static void qDrawWinShades(QPainter *p, PainterStateGuard painterGuard(p); const qreal devicePixelRatio = p->device()->devicePixelRatio(); + bool isTranslated = false; if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { painterGuard.save(); const qreal inverseScale = qreal(1) / devicePixelRatio; @@ -459,6 +481,8 @@ static void qDrawWinShades(QPainter *p, y = qRound(devicePixelRatio * y); w = qRound(devicePixelRatio * w); h = qRound(devicePixelRatio * h); + p->translate(0.5, 0.5); + isTranslated = true; } 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) }; p->setPen(c4); 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->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); h = qRound(devicePixelRatio * h); lineWidth = qRound(devicePixelRatio * lineWidth); + p->translate(0.5, 0.5); } QPen oldPen = p->pen(); -- cgit v1.2.3