Apple icon engine: maintain aspect ratio of image
Don't return fixed square icon sizes from availableSizes(), respect the aspect ratio of the input image we get from the system, and return an actualSize() that fits into the requested size, but uses the image's aspect ratio as well. Reuse the calculation in the rendering code. Amends 5b993fa8ede67871a8b2434505bc3c3d8bb906c6. Fixes: QTBUG-121764 Change-Id: I672b90a1fbecb662fd6614dcfa5090e28b16f3c8 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io> (cherry picked from commit 8a19f3c089deafa8a3a5fa5a05baa7ca01d8ec14) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
5e7cd47721
commit
746e6d4b48
@ -84,27 +84,35 @@ bool QAppleIconEngine::isNull()
|
||||
return m_image == nullptr;
|
||||
}
|
||||
|
||||
QList<QSize> QAppleIconEngine::availableIconSizes()
|
||||
QList<QSize> QAppleIconEngine::availableIconSizes(double aspectRatio)
|
||||
{
|
||||
const qreal devicePixelRatio = qGuiApp->devicePixelRatio();
|
||||
const QList<QSize> sizes = {
|
||||
{qRound(16 * devicePixelRatio), qRound(16 * devicePixelRatio)},
|
||||
{qRound(32 * devicePixelRatio), qRound(32 * devicePixelRatio)},
|
||||
{qRound(64 * devicePixelRatio), qRound(64 * devicePixelRatio)},
|
||||
{qRound(128 * devicePixelRatio), qRound(128 * devicePixelRatio)},
|
||||
{qRound(256 * devicePixelRatio), qRound(256 * devicePixelRatio)},
|
||||
{qRound(16 * devicePixelRatio), qRound(16. * devicePixelRatio / aspectRatio)},
|
||||
{qRound(32 * devicePixelRatio), qRound(32. * devicePixelRatio / aspectRatio)},
|
||||
{qRound(64 * devicePixelRatio), qRound(64. * devicePixelRatio / aspectRatio)},
|
||||
{qRound(128 * devicePixelRatio), qRound(128. * devicePixelRatio / aspectRatio)},
|
||||
{qRound(256 * devicePixelRatio), qRound(256. * devicePixelRatio / aspectRatio)},
|
||||
};
|
||||
return sizes;
|
||||
}
|
||||
|
||||
QList<QSize> QAppleIconEngine::availableSizes(QIcon::Mode, QIcon::State)
|
||||
{
|
||||
return availableIconSizes();
|
||||
const double aspectRatio = isNull() ? 1.0 : m_image.size.width / m_image.size.height;
|
||||
return availableIconSizes(aspectRatio);
|
||||
}
|
||||
|
||||
QSize QAppleIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state)
|
||||
QSize QAppleIconEngine::actualSize(const QSize &size, QIcon::Mode /*mode*/, QIcon::State /*state*/)
|
||||
{
|
||||
return QIconEngine::actualSize(size, mode, state);
|
||||
const double inputAspectRatio = isNull() ? 1.0 : m_image.size.width / m_image.size.height;
|
||||
const double outputAspectRatio = size.width() / size.height();
|
||||
QSize result = size;
|
||||
if (outputAspectRatio > inputAspectRatio)
|
||||
result.rwidth() = result.height() * inputAspectRatio;
|
||||
else
|
||||
result.rheight() = result.width() / inputAspectRatio;
|
||||
return result;
|
||||
}
|
||||
|
||||
QPixmap QAppleIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
|
||||
@ -188,23 +196,13 @@ QPixmap QAppleIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIco
|
||||
// The size we want might have a different aspect ratio than the icon we have.
|
||||
// So ask for a pixmap with the same aspect ratio as the icon, constrained to the
|
||||
// size we want, and then center that within a pixmap of the requested size.
|
||||
QSizeF renderSize = size * scale;
|
||||
const double inputAspectRatio = image.size.width / image.size.height;
|
||||
const double outputAspectRatio = size.width() / size.height();
|
||||
const bool aspectRatioAdjusted = !qFuzzyCompare(inputAspectRatio, outputAspectRatio);
|
||||
if (aspectRatioAdjusted) {
|
||||
// don't grow
|
||||
if (outputAspectRatio > inputAspectRatio)
|
||||
renderSize.rwidth() = renderSize.height() * inputAspectRatio;
|
||||
else
|
||||
renderSize.rheight() = renderSize.width() / inputAspectRatio;
|
||||
}
|
||||
|
||||
const QSize requestedSize = size * scale;
|
||||
const QSizeF renderSize = actualSize(requestedSize, mode, state);
|
||||
QPixmap iconPixmap = imageToPixmap(image, renderSize);
|
||||
iconPixmap.setDevicePixelRatio(scale);
|
||||
|
||||
if (aspectRatioAdjusted) {
|
||||
m_pixmap = QPixmap(size * scale);
|
||||
if (renderSize != requestedSize) {
|
||||
m_pixmap = QPixmap(requestedSize);
|
||||
m_pixmap.fill(Qt::transparent);
|
||||
m_pixmap.setDevicePixelRatio(scale);
|
||||
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
QPixmap scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) override;
|
||||
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
|
||||
|
||||
static QList<QSize> availableIconSizes();
|
||||
static QList<QSize> availableIconSizes(double aspectRatio = 1.0);
|
||||
|
||||
private:
|
||||
static constexpr quint64 calculateCacheKey(QIcon::Mode mode, QIcon::State state)
|
||||
|
Loading…
x
Reference in New Issue
Block a user