QIcon: Add pixmap() overload which take devicePixelRatio

Add new QIcon::pixmap() overload:

  QPixmap pixmap(const QSize &size, qreal devicePixelRatio, ...)

This function replaces the existing pixmap() function which
take a QWindow pointer, and should be more convenient in use.

Task-number: QTBUG-85885
Change-Id: Ie4ca96a266d9278864678dc61bdfc2836cabdb93
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
bb10
Morten Johan Sørvig 2020-08-06 16:14:30 +02:00
parent 7a5f865186
commit ffde7e8995
3 changed files with 57 additions and 20 deletions

View File

@ -820,7 +820,8 @@ QPixmap QIcon::pixmap(const QSize &size, Mode mode, State state) const
{
if (!d)
return QPixmap();
return pixmap(nullptr, size, mode, state);
const qreal dpr = -1; // don't know target dpr
return pixmap(size, dpr, mode, state);
}
/*!
@ -849,18 +850,36 @@ QPixmap QIcon::pixmap(const QSize &size, Mode mode, State state) const
images will have a devicePixelRatio larger than 1.
*/
/*! Returns the actual size of the icon for the requested \a size, \a
mode, and \a state. The result might be smaller than requested, but
never larger. The returned size is in device-independent pixels (This
is relevant for high-dpi pixmaps.)
/*!
\overload
\since 6.0
\sa pixmap(), paint()
Returns a pixmap with the requested \a size, \a devicePixelRatio, \a mode, and \a
state, generating one if necessary.
\sa actualSize(), paint()
*/
QSize QIcon::actualSize(const QSize &size, Mode mode, State state) const
QPixmap QIcon::pixmap(const QSize &size, qreal devicePixelRatio, Mode mode, State state) const
{
if (!d)
return QSize();
return actualSize(nullptr, size, mode, state);
return QPixmap();
// Use the global devicePixelRatio if the caller does not know the target dpr
if (devicePixelRatio == -1)
devicePixelRatio = qApp->devicePixelRatio();
// Handle the simple normal-dpi case
if (!(devicePixelRatio > 1.0)) {
QPixmap pixmap = d->engine->pixmap(size, mode, state);
pixmap.setDevicePixelRatio(1.0);
return pixmap;
}
// Try get a pixmap that is big enough to be displayed at device pixel resolution.
QIconEngine::ScaledPixmapArgument scalePixmapArg = { size * devicePixelRatio, mode, state, devicePixelRatio, QPixmap() };
d->engine->virtual_hook(QIconEngine::ScaledPixmapHook, reinterpret_cast<void*>(&scalePixmapArg));
scalePixmapArg.pixmap.setDevicePixelRatio(d->pixmapDevicePixelRatio(devicePixelRatio, size, scalePixmapArg.pixmap.size()));
return scalePixmapArg.pixmap;
}
/*!
@ -881,19 +900,22 @@ QPixmap QIcon::pixmap(QWindow *window, const QSize &size, Mode mode, State state
return QPixmap();
qreal devicePixelRatio = qt_effective_device_pixel_ratio(window);
return pixmap(size, devicePixelRatio, mode, state);
}
// Handle the simple normal-dpi case:
if (!(devicePixelRatio > 1.0)) {
QPixmap pixmap = d->engine->pixmap(size, mode, state);
pixmap.setDevicePixelRatio(1.0);
return pixmap;
}
// Try get a pixmap that is big enough to be displayed at device pixel resolution.
QIconEngine::ScaledPixmapArgument scalePixmapArg = { size * devicePixelRatio, mode, state, devicePixelRatio, QPixmap() };
d->engine->virtual_hook(QIconEngine::ScaledPixmapHook, reinterpret_cast<void*>(&scalePixmapArg));
scalePixmapArg.pixmap.setDevicePixelRatio(d->pixmapDevicePixelRatio(devicePixelRatio, size, scalePixmapArg.pixmap.size()));
return scalePixmapArg.pixmap;
/*! Returns the actual size of the icon for the requested \a size, \a
mode, and \a state. The result might be smaller than requested, but
never larger. The returned size is in device-independent pixels (This
is relevant for high-dpi pixmaps.)
\sa pixmap(), paint()
*/
QSize QIcon::actualSize(const QSize &size, Mode mode, State state) const
{
if (!d)
return QSize();
return actualSize(nullptr, size, mode, state);
}
/*!

View File

@ -82,6 +82,7 @@ public:
{ return pixmap(QSize(w, h), mode, state); }
inline QPixmap pixmap(int extent, Mode mode = Normal, State state = Off) const
{ return pixmap(QSize(extent, extent), mode, state); }
QPixmap pixmap(const QSize &size, qreal devicePixelRatio, Mode mode = Normal, State state = Off) const;
QPixmap pixmap(QWindow *window, const QSize &size, Mode mode = Normal, State state = Off) const;
QSize actualSize(const QSize &size, Mode mode = Normal, State state = Off) const;

View File

@ -55,6 +55,7 @@ private slots:
void cacheKey();
void detach();
void addFile();
void pixmap();
void availableSizes();
void name();
void streamAvailableSizes_data();
@ -447,6 +448,19 @@ void tst_QIcon::addFile()
expectedHighDpiImage(128, ":/styles/commonstyle/images/standardbutton-save-%1.png"));
}
void tst_QIcon::pixmap()
{
QIcon icon;
icon.addFile(m_pngImageFileName, QSize(64, 64));
// Exercise all pixmap() API overloads
QVERIFY(icon.pixmap(16).size().width() >= 16);
QVERIFY(icon.pixmap(16, 16).size().width() >= 16);
QVERIFY(icon.pixmap(QSize(16, 16)).size().width() >= 16);
QVERIFY(icon.pixmap(QSize(16, 16), 1).size().width() == 16);
QVERIFY(icon.pixmap(nullptr, QSize(16, 16)).size().width() >= 16);
}
static bool sizeLess(const QSize &a, const QSize &b)
{
return a.width() < b.width();