From 0d9387a942cd947ed04527661c9628c491484ba4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 19 Apr 2023 10:14:43 +0200 Subject: [PATCH] QIcon: prefer downscaling over upscaling pixmap icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... instead of just choosing the closest scaling factor. Otherwise we end up with the 1x pixmap for a 1.25 scaling factor instead of a the better fitting 2x pixmap. Task-number: QTBUG-90634 Change-Id: Ic554fc8d2715deea43bc22e71414902a263b2fef Reviewed-by: Morten Johan Sørvig --- src/gui/image/qicon.cpp | 3 +++ .../image/qiconhighdpi/tst_qiconhighdpi.cpp | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 41f9e7541ef..35f6cad4e28 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -169,6 +169,9 @@ static QPixmapIconEngineEntry *bestSizeScaleMatch(const QSize &size, qreal scale qreal ascore = pa->scale - scale; qreal bscore = pb->scale - scale; + // always prefer positive scores to prevent upscaling + if ((ascore < 0) != (bscore < 0)) + return bscore < 0 ? pa : pb; // Take the one closest to 0 return (qAbs(ascore) < qAbs(bscore)) ? pa : pb; } diff --git a/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp index 829c463c6b5..ca0af5d9836 100644 --- a/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp +++ b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp @@ -17,6 +17,7 @@ private slots: void addPixmap_data(); void addPixmap(); void ninePatch(); + void preferUpscale(); }; tst_QIconHighDpi::tst_QIconHighDpi() @@ -211,6 +212,23 @@ void tst_QIconHighDpi::ninePatch() } } +void tst_QIconHighDpi::preferUpscale() +{ + QIcon icon; + + // manual pixmap adder for full control of devicePixelRatio + auto addPixmapWithDpr = [&icon](const QString &path, qreal dpr) { + QImage image(path); + image.setDevicePixelRatio(dpr); + icon.addPixmap(QPixmap::fromImage(image)); + }; + + addPixmapWithDpr(":/icons/testtheme/22x22/actions/appointment-new.png", 1); + addPixmapWithDpr(":/icons/testtheme/22x22@2/actions/appointment-new.png", 2); + + QCOMPARE(icon.pixmap(QSize(22, 22), 1.25f).devicePixelRatio(), 1.25f); +} + int main(int argc, char *argv[]) { QGuiApplication app(argc, argv);