From 011794130c8e4bb64dbc3c8c9b50849b278cdda3 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 28 Mar 2019 13:59:35 +0300 Subject: Forward physical parameters for derived QImages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More specifically, for masks and rotated images. Add tests for it, also add tests that image metadata is forwarded for converted and copied images. Fixes: QTBUG-49259 Change-Id: I05d4a468b17f53a2625500b871c01b2c53b981a1 Reviewed-by: Morten Johan Sørvig --- src/gui/image/qimage.cpp | 36 ++++++++++++++++++++++-------- tests/auto/gui/image/qimage/tst_qimage.cpp | 35 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 3e18ca6528..ed6f23ee56 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1089,15 +1089,31 @@ void QImage::detach() } -static void copyMetadata(QImageData *dst, const QImageData *src) +static void copyPhysicalMetadata(QImageData *dst, const QImageData *src) { - // Doesn't copy colortable and alpha_clut, or offset. dst->dpmx = src->dpmx; dst->dpmy = src->dpmy; dst->devicePixelRatio = src->devicePixelRatio; +} + +static void copyMetadata(QImageData *dst, const QImageData *src) +{ + // Doesn't copy colortable and alpha_clut, or offset. + copyPhysicalMetadata(dst, src); dst->text = src->text; } +static void copyMetadata(QImage *dst, const QImage &src) +{ + dst->setDotsPerMeterX(src.dotsPerMeterX()); + dst->setDotsPerMeterY(src.dotsPerMeterY()); + dst->setDevicePixelRatio(src.devicePixelRatio()); + const auto textKeys = src.textKeys(); + for (const auto &key: textKeys) + dst->setText(key, src.text(key)); + +} + /*! \fn QImage QImage::copy(int x, int y, int width, int height) const \overload @@ -2924,8 +2940,10 @@ QImage QImage::createAlphaMask(Qt::ImageConversionFlags flags) const } QImage mask(d->width, d->height, Format_MonoLSB); - if (!mask.isNull()) + if (!mask.isNull()) { dither_to_Mono(mask.d, d, flags, true); + copyPhysicalMetadata(mask.d, d); + } return mask; } @@ -3043,6 +3061,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const #undef PIX + copyPhysicalMetadata(m.d, d); return m; } #endif //QT_NO_IMAGE_HEURISTIC_MASK @@ -3086,6 +3105,8 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const } if (mode == Qt::MaskOutColor) maskImage.invertPixels(); + + copyPhysicalMetadata(maskImage.d, d); return maskImage; } @@ -4655,8 +4676,7 @@ QImage QImage::smoothScaled(int w, int h) const { static QImage rotated90(const QImage &image) { QImage out(image.height(), image.width(), image.format()); - out.setDotsPerMeterX(image.dotsPerMeterY()); - out.setDotsPerMeterY(image.dotsPerMeterX()); + copyMetadata(&out, image); if (image.colorCount() > 0) out.setColorTable(image.colorTable()); int w = image.width(); @@ -4684,8 +4704,7 @@ static QImage rotated180(const QImage &image) return image.mirrored(true, true); QImage out(image.width(), image.height(), image.format()); - out.setDotsPerMeterX(image.dotsPerMeterY()); - out.setDotsPerMeterY(image.dotsPerMeterX()); + copyMetadata(&out, image); if (image.colorCount() > 0) out.setColorTable(image.colorTable()); int w = image.width(); @@ -4697,8 +4716,7 @@ static QImage rotated180(const QImage &image) static QImage rotated270(const QImage &image) { QImage out(image.height(), image.width(), image.format()); - out.setDotsPerMeterX(image.dotsPerMeterY()); - out.setDotsPerMeterY(image.dotsPerMeterX()); + copyMetadata(&out, image); if (image.colorCount() > 0) out.setColorTable(image.colorTable()); int w = image.width(); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 6bc27a6e16..bb81b9f61f 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -3260,11 +3260,46 @@ void tst_QImage::metadataPassthrough() QCOMPARE(mirrored.dotsPerMeterY(), a.dotsPerMeterY()); QCOMPARE(mirrored.devicePixelRatio(), a.devicePixelRatio()); + QTransform t; + t.rotate(90); + QImage rotated = a.transformed(t); + QCOMPARE(rotated.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); + QCOMPARE(rotated.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(rotated.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(rotated.devicePixelRatio(), a.devicePixelRatio()); + QImage swapped = a.rgbSwapped(); QCOMPARE(swapped.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); QCOMPARE(swapped.dotsPerMeterX(), a.dotsPerMeterX()); QCOMPARE(swapped.dotsPerMeterY(), a.dotsPerMeterY()); QCOMPARE(swapped.devicePixelRatio(), a.devicePixelRatio()); + + QImage converted = a.convertToFormat(QImage::Format_RGB32); + QCOMPARE(converted.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); + QCOMPARE(converted.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(converted.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(converted.devicePixelRatio(), a.devicePixelRatio()); + + QImage copied = a.copy(0, 0, a.width() / 2, a.height() / 2); + QCOMPARE(copied.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); + QCOMPARE(copied.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(copied.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(copied.devicePixelRatio(), a.devicePixelRatio()); + + QImage alphaMask = a.createAlphaMask(); + QCOMPARE(alphaMask.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(alphaMask.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(alphaMask.devicePixelRatio(), a.devicePixelRatio()); + + QImage heuristicMask = a.createHeuristicMask(); + QCOMPARE(heuristicMask.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(heuristicMask.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(heuristicMask.devicePixelRatio(), a.devicePixelRatio()); + + QImage maskFromColor = a.createMaskFromColor(qRgb(0, 0, 0)); + QCOMPARE(maskFromColor.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(maskFromColor.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(maskFromColor.devicePixelRatio(), a.devicePixelRatio()); } void tst_QImage::pixelColor() -- cgit v1.2.3