From 95712c5e5438e4eb5cd205ab4659febf3192137a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 10 Feb 2021 16:26:25 +0100 Subject: Fix QImage::fill with semi-transparent QColor A few formats were not treating the input QColor correctly. Fixed and added more exhaustive test. Pick-to: 6.1 6.0 5.15 Change-Id: I872aeeb45e518f9a34b4ac35642264821f9927f2 Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 21 ++++++++--------- tests/auto/gui/image/qimage/tst_qimage.cpp | 38 ++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index c3054bccfe..11eabcc9af 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1781,6 +1781,8 @@ void QImage::fill(const QColor &color) if (!d) return; + QRgba64 opaque = color.rgba64(); + opaque.setAlpha(65535); switch (d->format) { case QImage::Format_RGB32: case QImage::Format_ARGB32: @@ -1799,12 +1801,10 @@ void QImage::fill(const QColor &color) fill(ARGB2RGBA(qPremultiply(color.rgba()))); break; case QImage::Format_BGR30: - case QImage::Format_A2BGR30_Premultiplied: - fill(qConvertRgb64ToRgb30(color.rgba64())); + fill(qConvertRgb64ToRgb30(opaque)); break; case QImage::Format_RGB30: - case QImage::Format_A2RGB30_Premultiplied: - fill(qConvertRgb64ToRgb30(color.rgba64())); + fill(qConvertRgb64ToRgb30(opaque)); break; case QImage::Format_RGB16: fill((uint) qConvertRgb32To16(color.rgba())); @@ -1827,19 +1827,18 @@ void QImage::fill(const QColor &color) else fill((uint) 0); break; - case QImage::Format_RGBX64: { - QRgba64 c = color.rgba64(); - c.setAlpha(65535); - qt_rectfill(reinterpret_cast(d->data), c, + case QImage::Format_RGBX64: + qt_rectfill(reinterpret_cast(d->data), opaque, 0, 0, d->width, d->height, d->bytes_per_line); break; - - } case QImage::Format_RGBA64: - case QImage::Format_RGBA64_Premultiplied: qt_rectfill(reinterpret_cast(d->data), color.rgba64(), 0, 0, d->width, d->height, d->bytes_per_line); break; + case QImage::Format_RGBA64_Premultiplied: + qt_rectfill(reinterpret_cast(d->data), color.rgba64().premultiplied(), + 0, 0, d->width, d->height, d->bytes_per_line); + break; default: { QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Source); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 2c9f3a3746..6e7fce0b75 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -148,6 +148,7 @@ private slots: void fillColor_data(); void fillColor(); + void fillColorWithAlpha_data(); void fillColorWithAlpha(); void fillRGB888(); @@ -2348,15 +2349,38 @@ void tst_QImage::fillColor() } } -void tst_QImage::fillColorWithAlpha() +void tst_QImage::fillColorWithAlpha_data() { - QImage argb32(1, 1, QImage::Format_ARGB32); - argb32.fill(QColor(255, 0, 0, 127)); - QCOMPARE(argb32.pixel(0, 0), qRgba(255, 0, 0, 127)); + QTest::addColumn("format"); - QImage argb32pm(1, 1, QImage::Format_ARGB32_Premultiplied); - argb32pm.fill(QColor(255, 0, 0, 127)); - QCOMPARE(argb32pm.pixel(0, 0), 0x7f7f0000u); + for (int c = QImage::Format_RGB32; c < QImage::NImageFormats; ++c) { + if (c == QImage::Format_Grayscale8) + continue; + if (c == QImage::Format_Grayscale16) + continue; + if (c == QImage::Format_Alpha8) + continue; + QTest::newRow(qPrintable(formatToString(QImage::Format(c)))) << QImage::Format(c); + } +} + +void tst_QImage::fillColorWithAlpha() +{ + QFETCH(QImage::Format, format); + QImage image(1, 1, format); + image.fill(QColor(255, 170, 85, 170)); + QRgb referenceColor = qRgba(255, 170, 85, 170); + + if (!image.hasAlphaChannel()) + referenceColor = 0xff000000 | referenceColor; + else if (image.pixelFormat().premultiplied() == QPixelFormat::Premultiplied) + referenceColor = qPremultiply(referenceColor); + + QRgb color = image.pixel(0, 0); + QCOMPARE(qRed(color) & 0xf0, qRed(referenceColor) & 0xf0); + QCOMPARE(qGreen(color) & 0xf0, qGreen(referenceColor) & 0xf0); + QCOMPARE(qBlue(color) & 0xf0, qBlue(referenceColor) & 0xf0); + QCOMPARE(qAlpha(color) & 0xf0, qAlpha(referenceColor) & 0xf0); } void tst_QImage::fillRGB888() -- cgit v1.2.3