QLabel: use QIcon instead QPixmap in internal data structure

... and let QIcon do all the scaling (and caching) stuff. This allows
us to pass a QIcon to QLabel.

Task-number: QTBUG-122403
Change-Id: I40f6338a38b75ddbdf909f98a8d18d6369d62acb
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Christian Ehrlicher 2024-06-16 21:02:29 +02:00
parent 02bf12072f
commit 81e74cfa26
2 changed files with 21 additions and 33 deletions

View File

@ -304,20 +304,18 @@ void QLabel::clear()
void QLabel::setPixmap(const QPixmap &pixmap) void QLabel::setPixmap(const QPixmap &pixmap)
{ {
Q_D(QLabel); Q_D(QLabel);
if (!d->pixmap || d->pixmap->cacheKey() != pixmap.cacheKey()) { if (d->icon && d->icon->availableSizes().contains(pixmap.size()) &&
d->clearContents(); d->icon->pixmap(pixmap.size()).cacheKey() == pixmap.cacheKey())
d->pixmap = pixmap; return;
} d->icon = QIcon(pixmap);
d->pixmapSize = pixmap.deviceIndependentSize().toSize();
d->updateLabel(); d->updateLabel();
} }
QPixmap QLabel::pixmap() const QPixmap QLabel::pixmap() const
{ {
Q_D(const QLabel); Q_D(const QLabel);
if (d->pixmap) return d->icon ? d->icon->pixmap(d->pixmapSize) : QPixmap();
return *(d->pixmap);
return QPixmap();
} }
/*! /*!
@ -525,9 +523,8 @@ QSize QLabelPrivate::sizeForWidth(int w) const
int vextra = hextra; int vextra = hextra;
QFontMetrics fm = q->fontMetrics(); QFontMetrics fm = q->fontMetrics();
if (pixmap && !pixmap->isNull()) { if (icon && !icon->isNull()) {
br = pixmap->rect(); br = QRect(QPoint(0, 0), pixmapSize);
br.setSize(pixmap->deviceIndependentSize().toSize());
#ifndef QT_NO_PICTURE #ifndef QT_NO_PICTURE
} else if (picture && !picture->isNull()) { } else if (picture && !picture->isNull()) {
br = picture->boundingRect(); br = picture->boundingRect();
@ -1050,25 +1047,18 @@ void QLabel::paintEvent(QPaintEvent *)
} }
} else } else
#endif #endif
if (d->pixmap && !d->pixmap->isNull()) { if (d->icon && !d->icon->isNull()) {
QPixmap pix;
const qreal dpr = devicePixelRatio(); const qreal dpr = devicePixelRatio();
if (d->scaledcontents || dpr != d->pixmap->devicePixelRatio()) { const QSize size = d->scaledcontents ? cr.size() : d->pixmapSize;
QSize scaledSize = d->scaledcontents ? (cr.size() * dpr) const auto mode = isEnabled() ? QIcon::Normal : QIcon::Disabled;
: (d->pixmap->size() * (dpr / d->pixmap->devicePixelRatio())); QPixmap pix = d->icon->pixmap(size, dpr, mode);
if (!d->scaledpixmap || d->scaledpixmap->size() != scaledSize) { if (d->scaledcontents && pix.size() != size * dpr) {
d->scaledpixmap = pix = pix.scaled(size * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
d->pixmap->scaled(scaledSize, pix.setDevicePixelRatio(dpr);
Qt::IgnoreAspectRatio, Qt::SmoothTransformation); d->icon->addPixmap(pix, mode);
d->scaledpixmap->setDevicePixelRatio(dpr); }
}
pix = *d->scaledpixmap;
} else
pix = *d->pixmap;
QStyleOption opt; QStyleOption opt;
opt.initFrom(this); opt.initFrom(this);
if (!isEnabled())
pix = style->generatedIconPixmap(QIcon::Disabled, pix, &opt);
style->drawItemPixmap(&painter, cr, align, pix); style->drawItemPixmap(&painter, cr, align, pix);
} }
} }
@ -1266,8 +1256,8 @@ void QLabelPrivate::clearContents()
#ifndef QT_NO_PICTURE #ifndef QT_NO_PICTURE
picture.reset(); picture.reset();
#endif #endif
scaledpixmap.reset(); icon.reset();
pixmap.reset(); pixmapSize = QSize();
text.clear(); text.clear();
Q_Q(QLabel); Q_Q(QLabel);
@ -1410,8 +1400,6 @@ void QLabel::setScaledContents(bool enable)
if ((bool)d->scaledcontents == enable) if ((bool)d->scaledcontents == enable)
return; return;
d->scaledcontents = enable; d->scaledcontents = enable;
if (!enable)
d->scaledpixmap.reset();
update(contentsRect()); update(contentsRect());
} }

View File

@ -85,8 +85,8 @@ public:
mutable QSize sh; mutable QSize sh;
mutable QSize msh; mutable QSize msh;
QString text; QString text;
std::optional<QPixmap> pixmap; std::optional<QIcon> icon;
std::optional<QPixmap> scaledpixmap; QSize pixmapSize;
#ifndef QT_NO_PICTURE #ifndef QT_NO_PICTURE
std::optional<QPicture> picture; std::optional<QPicture> picture;
#endif #endif