diff options
author | Janek Bevendorff <janek@jbev.net> | 2021-01-31 16:25:42 +0300 |
---|---|---|
committer | Janek Bevendorff <janek@jbev.net> | 2021-01-31 16:54:55 +0300 |
commit | 874e9e10751d5d6cdf6d957f4d4eb60b70c86f2a (patch) | |
tree | 422ec8bc1ec242db23e241b99161dfc3a6f2e934 | |
parent | 48f2efbc921f0b9fce461dca4c2abf4643be5511 (diff) |
Fix icon alpha blending in QTableView (backport)
Some widgets such as QTableView do not call QIconEngine::pixmap(), but do
the drawing immediately through QIconEngine::paint(). This breaks alpha
blending for recolouring, since the underlying image canvas is not
necessarily transparent and also not anchored at (0, 0). This results in
a black box of the size of the icon bounding box.
Icon recolouring is now always done on a temporary QImage with
transparent background and only the finished end result is composed onto
the original canvas.
Fixes #6006
-rw-r--r-- | src/core/Resources.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/src/core/Resources.cpp b/src/core/Resources.cpp index 66aa07f8e..d602698d7 100644 --- a/src/core/Resources.cpp +++ b/src/core/Resources.cpp @@ -179,24 +179,29 @@ AdaptiveIconEngine::AdaptiveIconEngine(QIcon baseIcon) void AdaptiveIconEngine::paint(QPainter* painter, const QRect& rect, QIcon::Mode mode, QIcon::State state) { - painter->save(); - m_baseIcon.paint(painter, rect, Qt::AlignCenter, mode, state); + // Temporary image canvas to ensure that the background is transparent and alpha blending works. + QImage img(rect.size(), QImage::Format_ARGB32_Premultiplied); + img.fill(0); + QPainter p(&img); + + m_baseIcon.paint(&p, img.rect(), Qt::AlignCenter, mode, state); if (getMainWindow()) { QPalette palette = getMainWindow()->palette(); - painter->setCompositionMode(QPainter::CompositionMode_SourceAtop); + p.setCompositionMode(QPainter::CompositionMode_SourceIn); if (mode == QIcon::Active) { - painter->fillRect(rect, palette.color(QPalette::Active, QPalette::ButtonText)); + p.fillRect(img.rect(), palette.color(QPalette::Active, QPalette::ButtonText)); } else if (mode == QIcon::Selected) { - painter->fillRect(rect, palette.color(QPalette::Active, QPalette::HighlightedText)); + p.fillRect(img.rect(), palette.color(QPalette::Active, QPalette::HighlightedText)); } else if (mode == QIcon::Disabled) { - painter->fillRect(rect, palette.color(QPalette::Disabled, QPalette::WindowText)); + p.fillRect(img.rect(), palette.color(QPalette::Disabled, QPalette::WindowText)); } else { - painter->fillRect(rect, palette.color(QPalette::Normal, QPalette::WindowText)); + p.fillRect(img.rect(), palette.color(QPalette::Normal, QPalette::WindowText)); } } - painter->restore(); + + painter->drawImage(rect, img); } QPixmap AdaptiveIconEngine::pixmap(const QSize& size, QIcon::Mode mode, QIcon::State state) @@ -205,7 +210,7 @@ QPixmap AdaptiveIconEngine::pixmap(const QSize& size, QIcon::Mode mode, QIcon::S img.fill(0); QPainter painter(&img); paint(&painter, QRect(0, 0, size.width(), size.height()), mode, state); - return QPixmap::fromImage(img, Qt::NoFormatConversion); + return QPixmap::fromImage(img, Qt::ImageConversionFlag::NoFormatConversion); } QIconEngine* AdaptiveIconEngine::clone() const |