diff options
-rw-r--r-- | src/gui/image/qabstractfileiconengine.cpp | 15 | ||||
-rw-r--r-- | src/gui/image/qicon.cpp | 14 | ||||
-rw-r--r-- | src/gui/image/qiconengine.cpp | 9 | ||||
-rw-r--r-- | src/gui/image/qiconloader.cpp | 28 | ||||
-rw-r--r-- | src/gui/image/qiconloader_p.h | 7 |
5 files changed, 37 insertions, 36 deletions
diff --git a/src/gui/image/qabstractfileiconengine.cpp b/src/gui/image/qabstractfileiconengine.cpp index ffbe088d206..b9b9abc1f55 100644 --- a/src/gui/image/qabstractfileiconengine.cpp +++ b/src/gui/image/qabstractfileiconengine.cpp @@ -29,6 +29,11 @@ using namespace Qt::StringLiterals; QPixmap QAbstractFileIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { + return scaledPixmap(size, mode, state, 1.0); +} + +QPixmap QAbstractFileIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) +{ Q_UNUSED(mode); Q_UNUSED(state); @@ -37,13 +42,13 @@ QPixmap QAbstractFileIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QString key = cacheKey(); if (key.isEmpty()) - return filePixmap(size, mode, state); + return filePixmap(size * scale, mode, state); key += u'_' + QString::number(size.width()); QPixmap result; if (!QPixmapCache::find(key, &result)) { - result = filePixmap(size, mode, state); + result = filePixmap(size * scale, mode, state); if (!result.isNull()) QPixmapCache::insert(key, result); } @@ -51,12 +56,6 @@ QPixmap QAbstractFileIconEngine::pixmap(const QSize &size, QIcon::Mode mode, return result; } -QPixmap QAbstractFileIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) -{ - Q_UNUSED(scale); // (size is pre-multiplied by scale) - return pixmap(size, mode, state); -} - QSize QAbstractFileIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) { diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 3e16c7e0377..43a0c8a93d0 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -208,7 +208,7 @@ static QPixmapIconEngineEntry *bestSizeScaleMatch(const QSize &size, qreal scale return (qAbs(ascore) < qAbs(bscore)) ? pa : pb; } - qint64 s = area(size); + qint64 s = area(size * scale); if (pa->size == QSize() && pa->pixmap.isNull()) { pa->pixmap = QPixmap(pa->fileName); pa->size = pa->pixmap.size(); @@ -317,13 +317,15 @@ QPixmap QPixmapIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIc return scaledPixmap(size, mode, state, scale); } - const auto actualSize = adjustSize(size, pm.size()); + const auto actualSize = adjustSize(size * scale, pm.size()); + const auto calculatedDpr = QIconPrivate::pixmapDevicePixelRatio(scale, size, actualSize); QString key = "qt_"_L1 % HexString<quint64>(pm.cacheKey()) % HexString<quint8>(pe->mode) % HexString<quint64>(QGuiApplication::palette().cacheKey()) % HexString<uint>(actualSize.width()) - % HexString<uint>(actualSize.height()); + % HexString<uint>(actualSize.height()) + % HexString<quint16>(qRound(calculatedDpr * 1000)); if (mode == QIcon::Active) { if (QPixmapCache::find(key % HexString<quint8>(mode), &pm)) @@ -347,6 +349,7 @@ QPixmap QPixmapIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIc if (!generated.isNull()) pm = generated; } + pm.setDevicePixelRatio(calculatedDpr); QPixmapCache::insert(key % HexString<quint8>(mode), pm); } return pm; @@ -386,7 +389,8 @@ QList<QSize> QPixmapIconEngine::availableSizes(QIcon::Mode mode, QIcon::State st void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state) { if (!pixmap.isNull()) { - QPixmapIconEngineEntry *pe = tryMatch(pixmap.size(), pixmap.devicePixelRatio(), mode, state); + QPixmapIconEngineEntry *pe = tryMatch(pixmap.size() / pixmap.devicePixelRatio(), + pixmap.devicePixelRatio(), mode, state); if (pe && pe->size == pixmap.size() && pe->pixmap.devicePixelRatio() == pixmap.devicePixelRatio()) { pe->pixmap = pixmap; pe->fileName.clear(); @@ -879,7 +883,7 @@ QPixmap QIcon::pixmap(const QSize &size, qreal devicePixelRatio, Mode mode, Stat } // Try get a pixmap that is big enough to be displayed at device pixel resolution. - QPixmap pixmap = d->engine->scaledPixmap(size * devicePixelRatio, mode, state, devicePixelRatio); + QPixmap pixmap = d->engine->scaledPixmap(size, mode, state, devicePixelRatio); pixmap.setDevicePixelRatio(d->pixmapDevicePixelRatio(devicePixelRatio, size, pixmap.size())); return pixmap; } diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp index efcc3824ba7..999da649e44 100644 --- a/src/gui/image/qiconengine.cpp +++ b/src/gui/image/qiconengine.cpp @@ -42,6 +42,9 @@ QT_BEGIN_NAMESPACE /*! Returns the actual size of the icon the engine provides for the requested \a size, \a mode and \a state. The default implementation returns the given \a size. + + The returned size is in device-independent pixels (This + is relevant for high-dpi pixmaps). */ QSize QIconEngine::actualSize(const QSize &size, QIcon::Mode /*mode*/, QIcon::State /*state*/) { @@ -234,10 +237,10 @@ void QIconEngine::virtual_hook(int id, void *data) { switch (id) { case QIconEngine::ScaledPixmapHook: { - // We don't have any notion of scale besides "@nx", so just call pixmap() here. QIconEngine::ScaledPixmapArgument &arg = *reinterpret_cast<QIconEngine::ScaledPixmapArgument*>(data); - arg.pixmap = pixmap(arg.size, arg.mode, arg.state); + // try to get a pixmap with the correct size, the dpr is adjusted later on + arg.pixmap = pixmap(arg.size * arg.scale, arg.mode, arg.state); break; } default: @@ -282,7 +285,7 @@ bool QIconEngine::isNull() Returns a pixmap for the given \a size, \a mode, \a state and \a scale. The \a scale argument is typically equal to the \l {High DPI} - {device pixel ratio} of the display. + {device pixel ratio} of the display. The size is given in device-independent pixels. \include qiconengine-virtualhookhelper.qdocinc diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index 97735e4af63..bc7cafc53c0 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -900,7 +900,7 @@ QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, return QSize(0, 0); } -QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) { Q_UNUSED(state); @@ -911,13 +911,15 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st // If the size of the best match we have (basePixmap) is larger than the // requested size, we downscale it to match. - const auto actualSize = QPixmapIconEngine::adjustSize(size, basePixmap.size()); + const auto actualSize = QPixmapIconEngine::adjustSize(size * scale, basePixmap.size()); + const auto calculatedDpr = QIconPrivate::pixmapDevicePixelRatio(scale, size, actualSize); QString key = "$qt_theme_"_L1 % HexString<quint64>(basePixmap.cacheKey()) % HexString<quint8>(mode) % HexString<quint64>(QGuiApplication::palette().cacheKey()) % HexString<uint>(actualSize.width()) - % HexString<uint>(actualSize.height()); + % HexString<uint>(actualSize.height()) + % HexString<quint16>(qRound(calculatedDpr * 1000)); QPixmap cachedPixmap; if (QPixmapCache::find(key, &cachedPixmap)) { @@ -929,32 +931,24 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st cachedPixmap = basePixmap; if (QGuiApplication *guiApp = qobject_cast<QGuiApplication *>(qApp)) cachedPixmap = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(guiApp))->applyQIconStyleHelper(mode, cachedPixmap); + cachedPixmap.setDevicePixelRatio(calculatedDpr); QPixmapCache::insert(key, cachedPixmap); } return cachedPixmap; } -QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) { if (svgIcon.isNull()) svgIcon = QIcon(filename); - // Bypass QIcon API, as that will scale by device pixel ratio of the - // highest DPR screen since we're not passing on any QWindow. - if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine : nullptr) - return engine->pixmap(size, mode, state); - - return QPixmap(); + return svgIcon.pixmap(size, scale, mode, state); } QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { - QIconLoaderEngineEntry *entry = entryForSize(m_info, size); - if (entry) - return entry->pixmap(size, mode, state); - - return QPixmap(); + return scaledPixmap(size, mode, state, 1.0); } QString QIconLoaderEngine::key() const @@ -975,8 +969,8 @@ bool QIconLoaderEngine::isNull() QPixmap QIconLoaderEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) { const int integerScale = qCeil(scale); - QIconLoaderEngineEntry *entry = entryForSize(m_info, size / integerScale, integerScale); - return entry ? entry->pixmap(size, mode, state) : QPixmap(); + QIconLoaderEngineEntry *entry = entryForSize(m_info, size, integerScale); + return entry ? entry->pixmap(size, mode, state, scale) : QPixmap(); } QList<QSize> QIconLoaderEngine::availableSizes(QIcon::Mode mode, QIcon::State state) diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h index 4a8079a3e98..5d0a65e09d5 100644 --- a/src/gui/image/qiconloader_p.h +++ b/src/gui/image/qiconloader_p.h @@ -66,20 +66,21 @@ public: virtual ~QIconLoaderEngineEntry() {} virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, - QIcon::State state) = 0; + QIcon::State state, + qreal scale) = 0; QString filename; QIconDirInfo dir; }; struct ScalableEntry : public QIconLoaderEngineEntry { - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override; + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) override; QIcon svgIcon; }; struct PixmapEntry : public QIconLoaderEngineEntry { - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override; + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) override; QPixmap basePixmap; }; |