diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-02-10 16:26:25 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-02-12 20:46:10 +0000 |
commit | 17b9fdb40083692d7f2bab04e24aa73647610da9 (patch) | |
tree | 48aeb14f081d7d81a213c5ab5136b317071a7445 | |
parent | 7db44587ebdf573a741baab7871e753c1477f655 (diff) |
Fix QImage::fill with semi-transparent QColor
A few formats were not treating the input QColor correctly. Fixed and
added more exhaustive test.
Change-Id: I872aeeb45e518f9a34b4ac35642264821f9927f2
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit 95712c5e5438e4eb5cd205ab4659febf3192137a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/gui/image/qimage.cpp | 21 | ||||
-rw-r--r-- | 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 7ca5b13373..c6175ac84f 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<PixelOrderBGR>(color.rgba64())); + fill(qConvertRgb64ToRgb30<PixelOrderBGR>(opaque)); break; case QImage::Format_RGB30: - case QImage::Format_A2RGB30_Premultiplied: - fill(qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64())); + fill(qConvertRgb64ToRgb30<PixelOrderRGB>(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<quint64>(reinterpret_cast<quint64*>(d->data), c, + case QImage::Format_RGBX64: + qt_rectfill<quint64>(reinterpret_cast<quint64*>(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<quint64>(reinterpret_cast<quint64*>(d->data), color.rgba64(), 0, 0, d->width, d->height, d->bytes_per_line); break; + case QImage::Format_RGBA64_Premultiplied: + qt_rectfill<quint64>(reinterpret_cast<quint64 *>(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 0e0cb5d5a5..34a5bbdb3e 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -147,6 +147,7 @@ private slots: void fillColor_data(); void fillColor(); + void fillColorWithAlpha_data(); void fillColorWithAlpha(); void fillRGB888(); @@ -2347,15 +2348,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<QImage::Format>("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() |