summaryrefslogtreecommitdiffstats
path: root/src/gui/image/qiconloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image/qiconloader.cpp')
-rw-r--r--src/gui/image/qiconloader.cpp48
1 files changed, 34 insertions, 14 deletions
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 324f13a17b..d72c05a3c5 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -47,6 +47,7 @@
#include <qpa/qplatformtheme.h>
#include <QtGui/QIconEngine>
#include <QtGui/QPalette>
+#include <QtCore/qmath.h>
#include <QtCore/QList>
#include <QtCore/QDir>
#include <QtCore/QSettings>
@@ -347,6 +348,10 @@ QIconTheme::QIconTheme(const QString &themeName)
dirInfo.maxSize = indexReader.value(directoryKey +
QLatin1String("/MaxSize"),
size).toInt();
+
+ dirInfo.scale = indexReader.value(directoryKey +
+ QLatin1String("/Scale"),
+ 1).toInt();
m_keyList.append(dirInfo);
}
}
@@ -553,8 +558,11 @@ void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
* This algorithm is defined by the freedesktop spec:
* http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
*/
-static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
+static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize, int iconscale)
{
+ if (dir.scale != iconscale)
+ return false;
+
if (dir.type == QIconDirInfo::Fixed) {
return dir.size == iconsize;
@@ -575,24 +583,25 @@ static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
* This algorithm is defined by the freedesktop spec:
* http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
*/
-static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
+static int directorySizeDistance(const QIconDirInfo &dir, int iconsize, int iconscale)
{
+ const int scaledIconSize = iconsize * iconscale;
if (dir.type == QIconDirInfo::Fixed) {
- return qAbs(dir.size - iconsize);
+ return qAbs(dir.size * dir.scale - scaledIconSize);
} else if (dir.type == QIconDirInfo::Scalable) {
- if (iconsize < dir.minSize)
- return dir.minSize - iconsize;
- else if (iconsize > dir.maxSize)
- return iconsize - dir.maxSize;
+ if (scaledIconSize < dir.minSize * dir.scale)
+ return dir.minSize * dir.scale - scaledIconSize;
+ else if (scaledIconSize > dir.maxSize * dir.scale)
+ return scaledIconSize - dir.maxSize * dir.scale;
else
return 0;
} else if (dir.type == QIconDirInfo::Threshold) {
- if (iconsize < dir.size - dir.threshold)
- return dir.minSize - iconsize;
- else if (iconsize > dir.size + dir.threshold)
- return iconsize - dir.maxSize;
+ if (scaledIconSize < (dir.size - dir.threshold) * dir.scale)
+ return dir.minSize * dir.scale - scaledIconSize;
+ else if (scaledIconSize > (dir.size + dir.threshold) * dir.scale)
+ return scaledIconSize - dir.maxSize * dir.scale;
else return 0;
}
@@ -600,7 +609,7 @@ static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
return INT_MAX;
}
-QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
+QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size, int scale)
{
int iconsize = qMin(size.width(), size.height());
@@ -612,7 +621,7 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
// Search for exact matches first
for (int i = 0; i < numEntries; ++i) {
QIconLoaderEngineEntry *entry = m_info.entries.at(i);
- if (directoryMatchesSize(entry->dir, iconsize)) {
+ if (directoryMatchesSize(entry->dir, iconsize, scale)) {
return entry;
}
}
@@ -622,7 +631,7 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
QIconLoaderEngineEntry *closestMatch = 0;
for (int i = 0; i < numEntries; ++i) {
QIconLoaderEngineEntry *entry = m_info.entries.at(i);
- int distance = directorySizeDistance(entry->dir, iconsize);
+ int distance = directorySizeDistance(entry->dir, iconsize, scale);
if (distance < minimalSize) {
minimalSize = distance;
closestMatch = entry;
@@ -665,6 +674,8 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st
basePixmap.load(filename);
QSize actualSize = basePixmap.size();
+ // If the size of the best match we have (basePixmap) is larger than the
+ // requested size, we downscale it to match.
if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
actualSize.scale(size, Qt::KeepAspectRatio);
@@ -748,6 +759,15 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
*reinterpret_cast<bool*>(data) = m_info.entries.isEmpty();
}
break;
+ case QIconEngine::ScaledPixmapHook:
+ {
+ QIconEngine::ScaledPixmapArgument &arg = *reinterpret_cast<QIconEngine::ScaledPixmapArgument*>(data);
+ // QIcon::pixmap() multiplies size by the device pixel ratio.
+ const int integerScale = qCeil(arg.scale);
+ QIconLoaderEngineEntry *entry = entryForSize(arg.size / integerScale, integerScale);
+ arg.pixmap = entry ? entry->pixmap(arg.size, arg.mode, arg.state) : QPixmap();
+ }
+ break;
default:
QIconEngine::virtual_hook(id, data);
}