From 068a545339a3ec14187e6b9b5ea05c6ffbda05a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 2 Oct 2015 23:48:17 +0200 Subject: [PATCH] Add support for "@3x" image loading. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement as generic "@Nx" support in an exported qt_findAtNxFile function. 3x devices now get one extra file existence test in cases where @3x versions are not present. 1x devices are still on the fast path where there are no extra file system accesses. Add an @3x image to the highdpi manual test. Change-Id: I4ce3fc245ada01ea410abe1443ceb1e3abf7c17f Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- src/gui/image/qicon.cpp | 51 +++++++++++++++++++++------ src/gui/image/qicon.h | 2 ++ src/gui/text/qtextimagehandler.cpp | 16 ++------- tests/manual/highdpi/highdpi.qrc | 1 + tests/manual/highdpi/qticon16@3x.png | Bin 0 -> 5307 bytes 5 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 tests/manual/highdpi/qticon16@3x.png diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 7a59adffb8..af3af516db 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" @@ -1026,19 +1027,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State } else { detach(); } + 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); } /*! @@ -1375,5 +1370,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 ccddf69101..8c72f54629 100644 --- a/src/gui/image/qicon.h +++ b/src/gui/image/qicon.h @@ -139,6 +139,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/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index 1ba2cb31ca..747ed90281 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE +extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio); static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio) { // We might use the fileName for loading if url loading fails @@ -62,19 +63,8 @@ static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePi if (targetDevicePixelRatio <= 1.0) return fileName; - // try to find a 2x version - - const int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString at2xfileName = fileName; - at2xfileName.insert(dotIndex, QStringLiteral("@2x")); - if (QFile::exists(at2xfileName)) { - fileName = at2xfileName; - *url = QUrl(fileName); - } - } - - return fileName; + // try to find a Nx version + return qt_findAtNxFile(fileName, targetDevicePixelRatio); } diff --git a/tests/manual/highdpi/highdpi.qrc b/tests/manual/highdpi/highdpi.qrc index 10efac44fa..0e33ed33d7 100644 --- a/tests/manual/highdpi/highdpi.qrc +++ b/tests/manual/highdpi/highdpi.qrc @@ -2,6 +2,7 @@ qticon16.png qticon16@2x.png + qticon16@3x.png qticon32.png qticon32@2x.png qticon64.png diff --git a/tests/manual/highdpi/qticon16@3x.png b/tests/manual/highdpi/qticon16@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..de9265824133542c6657e072d648835eb495b919 GIT binary patch literal 5307 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 IP_T~p7o_U>VE_OC literal 0 HcmV?d00001