diff options
Diffstat (limited to 'src/gui/image')
-rw-r--r-- | src/gui/image/qicon.cpp | 51 | ||||
-rw-r--r-- | src/gui/image/qicon.h | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap_win.cpp | 28 | ||||
-rw-r--r-- | src/gui/image/qpixmapcache.cpp | 3 |
4 files changed, 60 insertions, 24 deletions
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 7ae081adfb..cebe5ce5f9 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -45,6 +45,7 @@ #include "qcache.h" #include "qdebug.h" #include "qpalette.h" +#include "qmath.h" #include "private/qhexstring_p.h" #include "private/qguiapplication_p.h" @@ -1029,19 +1030,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State d->engine = new QPixmapIconEngine; } } + d->engine->addFile(fileName, size, mode, state); - // Check if a "@2x" file exists and add it. - static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING"); - if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) { - QString at2xfileName = fileName; - int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); - if (dotIndex == -1) /* no dot */ - dotIndex = fileName.size(); /* append */ - at2xfileName.insert(dotIndex, QStringLiteral("@2x")); - if (QFile::exists(at2xfileName)) - d->engine->addFile(at2xfileName, size, mode, state); - } + // Check if a "@Nx" file exists and add it. + QString atNxFileName = qt_findAtNxFile(fileName, qApp->devicePixelRatio()); + if (atNxFileName != fileName) + d->engine->addFile(atNxFileName, size, mode, state); } /*! @@ -1395,5 +1390,39 @@ QDebug operator<<(QDebug dbg, const QIcon &i) \internal */ +/*! + \internal + \since 5.6 + Attempts to find a suitable @Nx file for the given \a targetDevicePixelRatio + Returns the the \a baseFileName if no such file was found. + + Given base foo.png and a target dpr of 2.5, this function will look for + foo@3x.png, then foo@2x, then fall back to foo.png if not found. +*/ +QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio) +{ + if (targetDevicePixelRatio <= 1.0) + return baseFileName; + + static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING"); + if (disableNxImageLoading) + return baseFileName; + + QString atNx = QLatin1String("@%1x"); + int dotIndex = baseFileName.lastIndexOf(QLatin1Char('.')); + if (dotIndex == -1) /* no dot */ + dotIndex = baseFileName.size(); /* append */ + + // Check for @Nx, ..., @3x, @2x file versions, + for (int n = qCeil(targetDevicePixelRatio); n > 1; --n) { + QString atNxfileName = baseFileName; + atNxfileName.insert(dotIndex, atNx.arg(n)); + if (QFile::exists(atNxfileName)) + return atNxfileName; + } + + return baseFileName; +} + QT_END_NAMESPACE #endif //QT_NO_ICON diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h index 329ae3deb3..6808bc2828 100644 --- a/src/gui/image/qicon.h +++ b/src/gui/image/qicon.h @@ -140,6 +140,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &); Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QIcon &); #endif +Q_GUI_EXPORT QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio); + QT_END_NAMESPACE #endif // QICON_H diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 12e19440dc..a7a9b375ff 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -345,9 +345,22 @@ static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) return image; } +static inline bool hasAlpha(const QImage &image) +{ + const int w = image.width(); + const int h = image.height(); + for (int y = 0; y < h; ++y) { + const QRgb *scanLine = reinterpret_cast<const QRgb *>(image.scanLine(y)); + for (int x = 0; x < w; ++x) { + if (qAlpha(scanLine[x]) != 0) + return true; + } + } + return false; +} + Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) { - bool foundAlpha = false; HDC screenDevice = GetDC(0); HDC hdc = CreateCompatibleDC(screenDevice); ReleaseDC(0, screenDevice); @@ -356,6 +369,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center if (!result) { qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); + DeleteDC(hdc); return QPixmap(); } @@ -371,17 +385,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL); QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h); - for (int y = 0 ; y < h && !foundAlpha ; y++) { - const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y)); - for (int x = 0; x < w ; x++) { - if (qAlpha(scanLine[x]) != 0) { - foundAlpha = true; - break; - } - } - } - if (!foundAlpha) { - //If no alpha was found, we use the mask to set alpha values + if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK); const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h); diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 2df813367d..6265a0c16d 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -652,7 +652,8 @@ void QPixmapCache::remove(const Key &key) void QPixmapCache::clear() { QT_TRY { - pm_cache()->clear(); + if (pm_cache.exists()) + pm_cache->clear(); } QT_CATCH(const std::bad_alloc &) { // if we ran out of memory during pm_cache(), it's no leak, // so just ignore it. |