summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Ehrlicher <ch.ehrlicher@gmx.de>2024-04-28 13:48:39 +0200
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2024-05-03 20:53:34 +0200
commitbbff35a343f607fde64a71b651db9f35365e3c67 (patch)
treeed948759d7453a9619be242704ae6a4ec81c1cf9 /src
parentccbff2c08b4506317860019e32d5d906c3a45594 (diff)
QCommonStyle: Fix painting arrows when size is even
Rework the painting code to not use floating point numbers and make sure the tip of the arrow is painted with one or two points (depending on the size is odd or even) so the arrow is always symmetric. Therefore also no anti-aliasing is needed. Sadly the dpr scaling and also QPainter::drawPolygon() screw things up a little bit with such small sizes, therefore do the dpr handling by ourself to get nice results. Pick-to: 6.7 Fixes: QTBUG-124554 Task-number: QTBUG-114539 Change-Id: I8ab8c2ce3ceb90af5d7c3a0dfeec7f7445e92a4d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/widgets/styles/qcommonstyle.cpp58
1 files changed, 32 insertions, 26 deletions
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 6ff85e2c1b..aab1192d50 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -761,56 +761,62 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
% HexString<uint>(pe),
opt, QSize(size, size), dpr);
if (!QPixmapCache::find(pixmapName, &pixmap)) {
- const qreal border = dpr * (size / 5.);
- const qreal sqsize = dpr * size;
- pixmap = QPixmap(QSize(size, size));
- pixmap.fill(Qt::transparent);
- QPainter imagePainter(&pixmap);
-
- QPolygonF poly;
+ // dpr scaling does not work well on such small pixel sizes, do it on our own
+ const int border = 1 * dpr;
+ const int sizeDpr = size * dpr;
+ int width = sizeDpr - 2 * border - 1;
+ int height = width / 2;
+ const int add = ((width & 1) == 1);
+ if (pe == PE_IndicatorArrowRight || pe == PE_IndicatorArrowLeft)
+ std::swap(width, height);
+ pixmap = styleCachePixmap(QSize(sizeDpr, sizeDpr), 1);
+
+ std::array<QPointF, 4> poly;
switch (pe) {
case PE_IndicatorArrowUp:
- poly = {QPointF(border, sqsize / 2), QPointF(sqsize / 2, border), QPointF(sqsize - border, sqsize / 2)};
+ poly = {QPointF(0, height), QPointF(width, height),
+ QPointF(width / 2 + add, 0), QPointF(width / 2, 0)};
break;
case PE_IndicatorArrowDown:
- poly = {QPointF(border, sqsize / 2), QPointF(sqsize / 2, sqsize - border), QPointF(sqsize - border, sqsize / 2)};
+ poly = {QPointF(0, 0), QPointF(width, 0),
+ QPointF(width / 2 + add, height), QPointF(width / 2, height)};
break;
case PE_IndicatorArrowRight:
- poly = {QPointF(sqsize - border, sqsize / 2), QPointF(sqsize / 2, border), QPointF(sqsize / 2, sqsize - border)};
+ poly = {QPointF(0, 0), QPointF(0, height),
+ QPointF(width, height / 2 + add), QPointF(width, height / 2)};
break;
case PE_IndicatorArrowLeft:
- poly = {QPointF(border, sqsize / 2), QPointF(sqsize / 2, border), QPointF(sqsize / 2, sqsize - border)};
+ poly = {QPointF(width, 0), QPointF(width, height),
+ QPointF(0, height / 2 + add), QPointF(0, height / 2)};
break;
default:
break;
}
- int bsx = 0;
- int bsy = 0;
-
+ QPainter imagePainter(&pixmap);
+ imagePainter.translate((sizeDpr - width) / 2, (sizeDpr - height) / 2);
if (opt->state & State_Sunken) {
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget);
+ const auto bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget);
+ const auto bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget);
+ imagePainter.translate(bsx, bsy);
}
-
- const QPointF boundsCenter = poly.boundingRect().center();
- const qreal sx = sqsize / 2 - boundsCenter.x();
- const qreal sy = sqsize / 2 - boundsCenter.y();
- imagePainter.translate(sx + bsx, sy + bsy);
imagePainter.setPen(opt->palette.buttonText().color());
imagePainter.setBrush(opt->palette.buttonText());
if (!(opt->state & State_Enabled)) {
- imagePainter.translate(1, 1);
+ const int ofs = qRound(1 * dpr);
+ imagePainter.translate(ofs, ofs);
imagePainter.setBrush(opt->palette.light().color());
imagePainter.setPen(opt->palette.light().color());
- imagePainter.drawPolygon(poly);
- imagePainter.translate(-1, -1);
+ imagePainter.drawPolygon(poly.data(), int(poly.size()));
+ imagePainter.drawPoints(poly.data(), int(poly.size()));
+ imagePainter.translate(-ofs, -ofs);
imagePainter.setBrush(opt->palette.mid().color());
imagePainter.setPen(opt->palette.mid().color());
}
-
- imagePainter.drawPolygon(poly);
+ imagePainter.drawPolygon(poly.data(), int(poly.size()));
+ // sometimes the corners are not drawn by drawPolygon for unknown reaons, so re-draw them again
+ imagePainter.drawPoints(poly.data(), int(poly.size()));
imagePainter.end();
pixmap.setDevicePixelRatio(dpr);
QPixmapCache::insert(pixmapName, pixmap);