QIcon: Use the @nx pixmaps in the paint method

Make use of the device pixel ratio in the QIcon paint method so the @nx
hi-dpi pixmaps are selected when appropriate when painting to a
QPainter.

Pick-to: 6.0
Fixes: QTBUG-90042
Change-Id: I53995a2285ef879e3c4fddb9f8da702e256a260f
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
Bastien Bouclet 2021-01-22 11:14:22 +01:00 committed by Eirik Aavitsland
parent 127a1ada32
commit b69b04c479
2 changed files with 49 additions and 1 deletions

View File

@ -174,7 +174,7 @@ void QPixmapIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode
auto paintDevice = painter->device();
qreal dpr = paintDevice ? paintDevice->devicePixelRatio() : qApp->devicePixelRatio();
const QSize pixmapSize = rect.size() * dpr;
QPixmap px = pixmap(pixmapSize, mode, state);
QPixmap px = scaledPixmap(pixmapSize, mode, state, dpr);
painter->drawPixmap(rect, px);
}

View File

@ -30,6 +30,7 @@
#include <QImageReader>
#include <QBuffer>
#include <QStandardPaths>
#include <QPainter>
#include <QProcess>
#include <qicon.h>
@ -57,6 +58,7 @@ private slots:
void detach();
void addFile();
void pixmap();
void paint();
void availableSizes();
void name();
void streamAvailableSizes_data();
@ -462,6 +464,52 @@ void tst_QIcon::pixmap()
QVERIFY(icon.pixmap(QSize(16, 16), -1).size().width() >= 16);
}
void tst_QIcon::paint()
{
QImage img16_1x(16, 16, QImage::Format_ARGB32);
img16_1x.fill(qRgb(0, 0, 0xff));
img16_1x.setDevicePixelRatio(1.);
QImage img16_2x(32, 32, QImage::Format_ARGB32);
img16_2x.fill(qRgb(0, 0xff, 0xff));
img16_2x.setDevicePixelRatio(2.);
QImage img32_1x(32, 32, QImage::Format_ARGB32);
img32_1x.fill(qRgb(0xff, 0, 0));
img32_1x.setDevicePixelRatio(1.);
QImage img32_2x(64, 64, QImage::Format_ARGB32);
img32_2x.fill(qRgb(0x0, 0xff, 0));
img32_2x.setDevicePixelRatio(2.);
QIcon icon;
icon.addPixmap(QPixmap::fromImage(img16_1x));
icon.addPixmap(QPixmap::fromImage(img16_2x));
icon.addPixmap(QPixmap::fromImage(img32_1x));
icon.addPixmap(QPixmap::fromImage(img32_2x));
// Test painting the icon version with a device independent size of 32x32
QRect iconRect(0, 0, 32, 32);
auto imageWithPaintedIconAtDpr = [&](qreal dpr) {
QImage paintDevice(64 * dpr, 64 * dpr, QImage::Format_ARGB32);
paintDevice.setDevicePixelRatio(dpr);
QPainter painter(&paintDevice);
icon.paint(&painter, iconRect);
return paintDevice;
};
QImage imageWithIcon1x = imageWithPaintedIconAtDpr(1.0);
QCOMPARE(imageWithIcon1x.pixel(iconRect.center()), qRgb(0xff, 0, 0));
QImage imageWithIcon2x = imageWithPaintedIconAtDpr(2.0);
QCOMPARE(imageWithIcon2x.pixel(iconRect.center()), qRgb(0, 0xff, 0));
QImage imageWithIcon3x = imageWithPaintedIconAtDpr(3.0);
QCOMPARE(imageWithIcon3x.pixel(iconRect.center()), qRgb(0, 0xff, 0));
}
static bool sizeLess(const QSize &a, const QSize &b)
{
return a.width() < b.width();