diff options
Diffstat (limited to 'tests/auto/gui/painting/qpainter/tst_qpainter.cpp')
-rw-r--r-- | tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 399 |
1 files changed, 287 insertions, 112 deletions
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 960dfdd04f..92b28f65bd 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -1,33 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include <QtTest/QtTest> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QTest> #include <qpainter.h> #ifndef QT_NO_WIDGETS #include <qdrawutil.h> @@ -69,6 +43,9 @@ Q_OBJECT public: tst_QPainter(); + enum ClipType { ClipRect, ClipRectF, ClipRegionSingle, ClipRegionMulti, ClipPathR, ClipPath }; + Q_ENUM(ClipType); + private slots: void cleanupTestCase(); void getSetCheck(); @@ -84,6 +61,7 @@ private slots: #endif void drawPixmapFragments(); void drawPixmapNegativeScale(); + void drawPixmapRounding(); void drawLine_data(); void drawLine(); @@ -155,6 +133,8 @@ private slots: void clipBoundingRect(); void transformedClip(); + void scaledClipConsistency_data(); + void scaledClipConsistency(); void setOpacity_data(); void setOpacity(); @@ -190,6 +170,7 @@ private slots: void radialGradientRgb30(); #endif + void radialGradient_QTBUG120332_ubsan(); void fpe_pixmapTransform(); void fpe_zeroLengthLines(); void fpe_divByZero(); @@ -300,6 +281,10 @@ private slots: void fillPolygon(); void drawImageAtPointF(); + void scaledDashes(); +#if QT_CONFIG(raster_fp) + void hdrColors(); +#endif private: void fillData(); @@ -599,7 +584,7 @@ QImage tst_QPainter::getResImage( const QString &dir, const QString &addition, c QImage res; QString resFilename = dir + QLatin1String("/res_") + addition + QLatin1Char('.') + extension; if ( !res.load( resFilename ) ) { - QWARN(QString("Could not load result data %s %1").arg(resFilename).toLatin1()); + qWarning() << "Could not load result data" << resFilename; return QImage(); } return res; @@ -610,14 +595,14 @@ QBitmap tst_QPainter::getBitmap( const QString &dir, const QString &filename, bo QBitmap bm; QString bmFilename = dir + QLatin1Char('/') + filename + QLatin1String(".xbm"); if ( !bm.load( bmFilename ) ) { - QWARN(QString("Could not load bitmap '%1'").arg(bmFilename).toLatin1()); + qWarning() << "Could not load bitmap" << bmFilename; return QBitmap(); } if ( mask ) { QBitmap mask; QString maskFilename = dir + QLatin1Char('/') + filename + QLatin1String("-mask.xbm"); if (!mask.load(maskFilename)) { - QWARN(QString("Could not load mask '%1'").arg(maskFilename).toLatin1()); + qWarning() << "Could not load mask" << maskFilename; return QBitmap(); } bm.setMask( mask ); @@ -763,6 +748,16 @@ void tst_QPainter::drawPixmapNegativeScale() QVERIFY(resultImage.pixel(12, 8) == qRgba(0, 0, 0, 255)); // and right strip is now black } +void tst_QPainter::drawPixmapRounding() +{ + // Just test that we don't assert + QBitmap bm(8, 8); + QImage out(64, 64, QImage::Format_RGB32); + QPainter p(&out); + qreal y = 26.499999999999996; + p.drawPixmap(QPointF(0, y), bm); +} + void tst_QPainter::drawLine_data() { QTest::addColumn<QLine>("line"); @@ -792,7 +787,6 @@ void tst_QPainter::drawLine() { // unclipped pixmapUnclipped.fill(Qt::white); QPainter p(&pixmapUnclipped); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.translate(offset, offset); p.setPen(QPen(Qt::black)); p.drawLine(line); @@ -815,11 +809,10 @@ void tst_QPainter::drawLine() qMin(line.y1(), line.y2()) + 2*offset + qAbs(line.dy())); { // clipped - const QRect clip = QRect(line.p1(), line.p2()).normalized(); + const QRect clip = QRect::span(line.p1(), line.p2()); pixmapClipped.fill(Qt::white); QPainter p(&pixmapClipped); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.translate(offset, offset); p.setClipRect(clip); p.setPen(QPen(Qt::black)); @@ -856,7 +849,6 @@ void tst_QPainter::drawLine_task121143() image.fill(0xffffffff); QPainter p(&image); p.setPen(pen); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.drawLine(QLine(0, 0+4, 0+4, 0)); p.end(); @@ -1037,7 +1029,6 @@ void tst_QPainter::drawRect2() QTransform transform(0.368567, 0, 0, 0, 0.368567, 0, 0.0289, 0.0289, 1); QPainter p(&image); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.setTransform(transform); p.setBrush(Qt::red); p.setPen(Qt::NoPen); @@ -1048,13 +1039,12 @@ void tst_QPainter::drawRect2() image.fill(0xffffffff); p.begin(&image); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.setTransform(transform); p.drawRect(QRect(14, 14, 39, 39)); p.end(); QRect stroke = getPaintedSize(image, Qt::white); - QCOMPARE(stroke.adjusted(1, 1, 0, 0), fill.adjusted(0, 0, 1, 1)); + QCOMPARE(stroke.adjusted(1, 1, 0, 0), fill.adjusted(1, 1, 0, 0)); } } @@ -1065,6 +1055,7 @@ void tst_QPainter::fillRect_data() QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied; QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied; QTest::newRow("rgba64pm") << QImage::Format_RGBA64_Premultiplied; + QTest::newRow("rgbaFP16pm") << QImage::Format_RGBA16FPx4_Premultiplied; } void tst_QPainter::fillRect() @@ -1264,13 +1255,13 @@ void tst_QPainter::drawPath_data() { QPainterPath p; p.addRect(2.25, 2.25, 10, 10); - QTest::newRow("non-aligned rect") << p << QRect(3, 3, 10, 10) << 10 * 10; + QTest::newRow("non-aligned rect") << p << QRect(2, 2, 10, 10) << 10 * 10; } { QPainterPath p; p.addRect(2.25, 2.25, 10.5, 10.5); - QTest::newRow("non-aligned rect 2") << p << QRect(3, 3, 10, 10) << 10 * 10; + QTest::newRow("non-aligned rect 2") << p << QRect(2, 2, 11, 11) << 11 * 11; } { @@ -1308,7 +1299,6 @@ void tst_QPainter::drawPath() image.fill(QColor(Qt::white).rgb()); QPainter p(&image); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.setPen(Qt::NoPen); p.setBrush(Qt::black); p.translate(offset - expectedBounds.left(), offset - expectedBounds.top()); @@ -1536,7 +1526,6 @@ void tst_QPainter::drawRoundedRect() { pixmap.fill(Qt::white); QPainter p(&pixmap); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen)); p.setBrush(Qt::black); p.drawRoundedRect(rect, 25, 25, Qt::RelativeSize); @@ -1565,6 +1554,8 @@ void tst_QPainter::qimageFormats_data() QTest::newRow("Qimage::Format_BGR888") << QImage::Format_BGR888; QTest::newRow("Qimage::Format_A2RGB30_Premultiplied") << QImage::Format_A2RGB30_Premultiplied; QTest::newRow("Qimage::Format_RGB30") << QImage::Format_RGB30; + QTest::newRow("QImage::Format_RGBX16FPx4") << QImage::Format_RGBX16FPx4; + QTest::newRow("QImage::Format_RGBA32FPx4_Premultiplied") << QImage::Format_RGBA32FPx4_Premultiplied; } /* @@ -1613,9 +1604,8 @@ void tst_QPainter::setWindow() pixmap.fill(QColor(Qt::white)); QPainter painter(&pixmap); - painter.setRenderHint(QPainter::Qt4CompatiblePainting); - painter.setWindow(0, 0, 3, 3); - painter.drawLine(1, 1, 2, 2); + painter.setWindow(0, 0, 28, 28); + painter.drawLine(10, 10, 18, 18); const QRect painted = getPaintedSize(pixmap, Qt::white); QVERIFY(195 < painted.y() && painted.y() < 205); // correct value is around 200 @@ -1753,10 +1743,11 @@ void tst_QPainter::setClipRect() /* Verify that the clipping works correctly. - The red outline should be covered by the blue rect on top and left, - while it should be clipped on the right and bottom and thus the red outline be visible + Just like fillRect, cliprect should snap rightwards and downwards in case of .5 coordinates. + The red outline should be covered by the blue rect on top, + while it should be clipped on the other edges and thus the red outline be visible - See: QTBUG-83229 + See: QTBUG-83229, modified by QTBUG-100329 */ void tst_QPainter::clipRect() { @@ -1782,7 +1773,7 @@ void tst_QPainter::clipRect() p.end(); QCOMPARE(image.pixelColor(clipRect.left() + 1, clipRect.top()), QColor(Qt::blue)); - QCOMPARE(image.pixelColor(clipRect.left(), clipRect.top() + 1), QColor(Qt::blue)); + QCOMPARE(image.pixelColor(clipRect.left(), clipRect.top() + 1), QColor(Qt::red)); QCOMPARE(image.pixelColor(clipRect.left() + 1, clipRect.bottom()), QColor(Qt::red)); QCOMPARE(image.pixelColor(clipRect.right(), clipRect.top() + 1), QColor(Qt::red)); } @@ -2102,21 +2093,22 @@ void tst_QPainter::clippedLines_data() QPen pen2(QColor(223, 223, 0, 223)); pen2.setWidth(2); - QList<QLineF> lines; - lines << QLineF(15, 15, 65, 65) - << QLineF(14, 14, 66, 66) - << QLineF(16, 16, 64, 64) - << QLineF(65, 65, 15, 15) - << QLineF(66, 66, 14, 14) - << QLineF(64, 64, 14, 14) - << QLineF(15, 50, 15, 64) - << QLineF(15, 50, 15, 65) - << QLineF(15, 50, 15, 66) - << QLineF(15, 50, 64, 50) - << QLineF(15, 50, 65, 50) - << QLineF(15, 50, 66, 50); - - foreach (QLineF line, lines) { + const auto lines = { + QLineF(15, 15, 65, 65), + QLineF(14, 14, 66, 66), + QLineF(16, 16, 64, 64), + QLineF(65, 65, 15, 15), + QLineF(66, 66, 14, 14), + QLineF(64, 64, 14, 14), + QLineF(15, 50, 15, 64), + QLineF(15, 50, 15, 65), + QLineF(15, 50, 15, 66), + QLineF(15, 50, 64, 50), + QLineF(15, 50, 65, 50), + QLineF(15, 50, 66, 50), + }; + + for (QLineF line : lines) { const QByteArray desc = "line (" + QByteArray::number(line.x1()) + ", " + QByteArray::number(line.y1()) + ", " + QByteArray::number(line.x2()) + ", " + QByteArray::number(line.y2()) @@ -2517,6 +2509,12 @@ void tst_QPainter::drawhelper_blend_untransformed_data() setOpacity_data(); } +static const auto &defaultOpacities() +{ + static const std::array opacities = {qreal(0.0), 0.1 , 0.01, 0.4, 0.5, 0.6, 0.9, 1.0}; + return opacities; +} + void tst_QPainter::drawhelper_blend_untransformed() { QFETCH(QImage::Format, destFormat); @@ -2537,9 +2535,7 @@ void tst_QPainter::drawhelper_blend_untransformed() p.fillRect(paintRect, srcColor); p.end(); - QList<qreal> opacities = (QList<qreal>() << 0.0 << 0.1 << 0.01 << 0.4 - << 0.5 << 0.6 << 0.9 << 1.0); - foreach (qreal opacity, opacities) { + for (qreal opacity : defaultOpacities()) { p.begin(&dest); p.fillRect(paintRect, destColor); @@ -2594,9 +2590,7 @@ void tst_QPainter::drawhelper_blend_tiled_untransformed() const QBrush brush(src); - QList<qreal> opacities = (QList<qreal>() << 0.0 << 0.1 << 0.01 << 0.4 - << 0.5 << 0.6 << 0.9 << 1.0); - foreach (qreal opacity, opacities) { + for (qreal opacity : defaultOpacities()) { p.begin(&dest); p.fillRect(paintRect, destColor); @@ -2634,17 +2628,17 @@ class DummyPaintEngine : public QPaintEngine, public QPaintDevice { public: DummyPaintEngine() : QPaintEngine(no_porter_duff()) {} - virtual bool begin(QPaintDevice *) { return true; } - virtual bool end() { return true; } + virtual bool begin(QPaintDevice *) override { return true; } + virtual bool end() override { return true; } - virtual void updateState(const QPaintEngineState &) {} - virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {} + virtual void updateState(const QPaintEngineState &) override {} + virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) override {} - virtual Type type() const { return User; } + virtual Type type() const override { return User; } - virtual QPaintEngine *paintEngine() const { return (QPaintEngine *)this; } + virtual QPaintEngine *paintEngine() const override { return (QPaintEngine *)this; } - virtual int metric(PaintDeviceMetric metric) const { Q_UNUSED(metric); return 0; }; + virtual int metric(PaintDeviceMetric metric) const override { Q_UNUSED(metric); return 0; }; }; static bool success; @@ -2697,8 +2691,9 @@ void tst_QPainter::drawhelper_blend_color() class ViewportTestWidget : public QWidget { public: - ViewportTestWidget(QWidget *parent = 0) : QWidget(parent), hasPainted(false) {} - QSize sizeHint() const { + ViewportTestWidget(QWidget *parent = nullptr) : QWidget(parent), hasPainted(false) {} + QSize sizeHint() const override + { return QSize(100, 100); } @@ -2706,7 +2701,8 @@ public: bool hasPainted; protected: - void paintEvent(QPaintEvent *) { + void paintEvent(QPaintEvent *) override + { hasPainted = true; QPainter p(this); viewport = p.viewport(); @@ -2788,7 +2784,7 @@ void tst_QPainter::monoImages() for (int i = 1; i < QImage::NImageFormats; ++i) { for (int j = 0; j < numColorPairs; ++j) { const QImage::Format format = QImage::Format(i); - if (format == QImage::Format_Indexed8) + if (format == QImage::Format_Indexed8 || format == QImage::Format_CMYK8888) continue; QImage img(2, 2, format); @@ -2848,7 +2844,14 @@ void tst_QPainter::monoImages() } } -#if !defined(Q_OS_AIX) && !defined(Q_CC_MSVC) && !defined(Q_OS_SOLARIS) && !defined(__UCLIBC__) +#if defined(Q_OS_DARWIN) || defined(Q_OS_FREEBSD) || defined(Q_OS_ANDROID) +# define TEST_FPE_EXCEPTIONS +#elif defined(Q_OS_LINUX) && defined(__GLIBC__) +# define TEST_FPE_EXCEPTIONS +#elif defined(Q_OS_WIN) && defined(Q_CC_GNU) +# define TEST_FPE_EXCEPTIONS +#endif +#ifdef TEST_FPE_EXCEPTIONS #include <fenv.h> static const QString fpeExceptionString(int exception) @@ -3254,11 +3257,6 @@ void tst_QPainter::imageScaling_task206785() #define FOR_EACH_NEIGHBOR_8 for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) if (dx != 0 || dy != 0) #define FOR_EACH_NEIGHBOR_4 for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) if ((dx == 0) != (dy == 0)) -size_t qHash(const QPoint &point) -{ - return qHash(qMakePair(point.x(), point.y())); -} - bool verifyOutlineFillConsistency(const QImage &img, QRgb outside, QRgb inside, QRgb outline) { if (img.pixel(img.width() / 2, img.height() / 2) != inside) @@ -3556,9 +3554,13 @@ void tst_QPainter::drawImage_data() for (int srcFormat = QImage::Format_Mono; srcFormat < QImage::NImageFormats; ++srcFormat) { for (int dstFormat = QImage::Format_Mono; dstFormat < QImage::NImageFormats; ++dstFormat) { - // Indexed8 can't be painted to, and Alpha8 can't hold a color. - if (dstFormat == QImage::Format_Indexed8 || dstFormat == QImage::Format_Alpha8) + // Indexed8 and CMYK8888 can't be painted to, and Alpha8 can't hold a color. + if (dstFormat == QImage::Format_Indexed8 || + dstFormat == QImage::Format_CMYK8888 || + dstFormat == QImage::Format_Alpha8) { continue; + } + for (int odd_x = 0; odd_x <= 1; ++odd_x) { for (int odd_width = 0; odd_width <= 1; ++odd_width) { QTest::addRow("srcFormat %d, dstFormat %d, odd x: %d, odd width: %d", @@ -3801,10 +3803,10 @@ static QLinearGradient inverseGradient(QLinearGradient g) { QLinearGradient g2 = g; - QGradientStops stops = g.stops(); + const QGradientStops stops = g.stops(); QGradientStops inverse; - foreach (QGradientStop stop, stops) + for (const QGradientStop &stop : stops) inverse << QGradientStop(1 - stop.first, stop.second); g2.setStops(inverse); @@ -3910,6 +3912,21 @@ void tst_QPainter::gradientPixelFormat() QCOMPARE(a, b.convertToFormat(QImage::Format_ARGB32_Premultiplied)); } +void tst_QPainter::radialGradient_QTBUG120332_ubsan() +{ + // Check if Radial Gradient will cause division by zero or not when + // the center point coincide with the focal point. + QImage image(8, 8, QImage::Format_ARGB32_Premultiplied); + QPainter painter(&image); + + QPointF center(0.5, 0.5); + QPointF focal(0.5, 0.5); + QRadialGradient gradient(center, 0.5, focal, 0.5); + gradient.setColorAt(0, Qt::blue); + gradient.setColorAt(1, Qt::red); + painter.fillRect(image.rect(), QBrush(gradient)); +} + void tst_QPainter::gradientInterpolation() { QImage image(256, 8, QImage::Format_ARGB32_Premultiplied); @@ -4451,7 +4468,7 @@ class TestProxy : public QGraphicsProxyWidget { public: TestProxy() : QGraphicsProxyWidget() {} - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { QGraphicsProxyWidget::paint(painter, option, widget); deviceTransform = painter->deviceTransform(); @@ -4464,7 +4481,7 @@ class TestWidget : public QWidget Q_OBJECT public: TestWidget() : QWidget(), painted(false) {} - void paintEvent(QPaintEvent *) + void paintEvent(QPaintEvent *) override { QPainter p(this); deviceTransform = p.deviceTransform(); @@ -4587,6 +4604,96 @@ void tst_QPainter::transformedClip() } } +void tst_QPainter::scaledClipConsistency_data() +{ + QTest::addColumn<ClipType>("clipType"); + + QTest::newRow("clipRect") << ClipRect; + QTest::newRow("clipRectF") << ClipRectF; + QTest::newRow("clipRegionSingle") << ClipRegionSingle; + QTest::newRow("clipRegionMulti") << ClipRegionMulti; + QTest::newRow("clipPathR") << ClipPathR; + QTest::newRow("clipPath") << ClipPath; +} + +void tst_QPainter::scaledClipConsistency() +{ + QFETCH(ClipType, clipType); + + const QList<QRect> clipRects = { + // Varying odd and even coordinates and width/height + QRect(1, 1, 7, 8), + QRect(8, 0, 8, 9), + QRect(0, 9, 8, 7), + QRect(8, 9, 8, 7), + }; + // Assert that these are edge to edge: + QPointF center = QRectF(clipRects[0]).bottomRight(); + Q_ASSERT(QRectF(clipRects[1]).bottomLeft() == center); + Q_ASSERT(QRectF(clipRects[2]).topRight() == center); + Q_ASSERT(QRectF(clipRects[3]).topLeft() == center); + + QRegion multiRegion; + for (const QRect &clipRect : clipRects) + multiRegion += clipRect; + + QColor fillColor(Qt::black); + fillColor.setAlphaF(0.5); + + for (int i = 100; i <= 300; i++) { + qreal dpr = qreal(i) / 100.0; + QImage img(QSize(16, 16) * dpr, QImage::Format_RGB32); + img.fill(Qt::white); + img.setDevicePixelRatio(dpr); + + for (const QRect &clipRect : clipRects) { + QPainter p(&img); + switch (clipType) { + case ClipRect: + p.setClipRect(clipRect); + break; + case ClipRectF: + p.setClipRect(QRectF(clipRect)); + break; + case ClipRegionSingle: + p.setClipRegion(QRegion(clipRect)); + break; + case ClipRegionMulti: + p.setClipRegion(multiRegion); + break; + case ClipPath: + p.rotate(0.001); // Avoid the path being optimized to a rectf + Q_FALLTHROUGH(); + case ClipPathR: { + QPainterPath path; + path.addRect(clipRect); // Will be recognized and converted back to a rectf + p.setClipPath(path); + break; + } + default: + Q_ASSERT(false); + break; + } + p.fillRect(p.window(), fillColor); + if (clipType == ClipRegionMulti) + break; // once is enough, we're not using the clipRect anyway + } + + int qtWidth = img.width() / 4; + int qtHeight = img.height() / 4; + QPoint imgCenter = img.rect().center(); + const QRgb targetColor = img.pixel(qtWidth, qtHeight); + + // Test that there are no gaps or overlaps where the cliprects meet + for (int offset = -2; offset <= 2; offset++) { + QCOMPARE(img.pixel(imgCenter.x() + offset, qtHeight), targetColor); + QCOMPARE(img.pixel(imgCenter.x() + offset, img.height() - qtHeight), targetColor); + QCOMPARE(img.pixel(qtWidth, imgCenter.y() + offset), targetColor); + QCOMPARE(img.pixel(img.width() - qtWidth, imgCenter.y() + offset), targetColor); + } + } +} + #if defined(Q_OS_MAC) // Only Mac supports sub pixel positions in raster engine currently void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053() @@ -4597,7 +4704,6 @@ void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053() baseLine.fill(Qt::white); { QPainter p(&baseLine); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.drawText(0, fm.ascent(), QString::fromLatin1("e")); } @@ -4608,7 +4714,6 @@ void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053() { QPainter p(&comparison); - p.setRenderHint(QPainter::Qt4CompatiblePainting); p.drawText(QPointF(i / 12.0, fm.ascent()), QString::fromLatin1("e")); } @@ -4645,7 +4750,7 @@ void tst_QPainter::drawPointScaled() class GradientProducer : public QThread { protected: - void run(); + void run() override; }; void GradientProducer::run() @@ -4739,7 +4844,7 @@ void tst_QPainter::QTBUG38781_NoBrushAndQBitmap() class TextDrawerThread : public QThread { public: - void run(); + void run() override; QImage rendering; }; @@ -4825,10 +4930,7 @@ void tst_QPainter::QTBUG25153_drawLine() { QImage image(2, 2, QImage::Format_RGB32); - QList<Qt::PenCapStyle> styles; - styles << Qt::FlatCap << Qt::SquareCap << Qt::RoundCap; - - foreach (Qt::PenCapStyle style, styles) { + for (Qt::PenCapStyle style : {Qt::FlatCap, Qt::SquareCap, Qt::RoundCap}) { image.fill(0xffffffff); QPainter p(&image); p.setPen(QPen(Qt::black, 0, Qt::SolidLine, style)); @@ -4939,16 +5041,16 @@ void tst_QPainter::blendARGBonRGB_data() QTest::newRow("ARGB_PM over RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied << QPainter::CompositionMode_SourceOver << qRgba(85, 0, 0, 85) << 85; #if QT_CONFIG(raster_64bit) - QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 - << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 85) << 85; - QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 - << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 120) << 85; + QTest::newRow("ARGB@85 source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 + << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 85) << 85; + QTest::newRow("ARGB@120 source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 + << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 120) << 85; #endif - QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied - << QPainter::CompositionMode_Source << qRgba(85, 0, 0, 85) << 85; + QTest::newRow("ARGB_PM@85 source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied + << QPainter::CompositionMode_Source << qRgba(85, 0, 0, 85) << 85; #if QT_CONFIG(raster_64bit) - QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied - << QPainter::CompositionMode_Source << qRgba(180, 0, 0, 180) << 170; + QTest::newRow("ARGB_PM@180 source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied + << QPainter::CompositionMode_Source << qRgba(180, 0, 0, 180) << 170; #endif QTest::newRow("ARGB source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 85) << 85; @@ -5109,7 +5211,7 @@ void tst_QPainter::drawPolyline() p.setPen(pen); QVERIFY(p.pen().isCosmetic()); if (r) { - for (int i = 0; i < points.count()-1; i++) { + for (int i = 0; i < points.size()-1; i++) { p.drawLine(points.at(i), points.at(i+1)); } } else { @@ -5372,6 +5474,79 @@ void tst_QPainter::drawImageAtPointF() paint.end(); } +void tst_QPainter::scaledDashes() +{ + // Test that we do not hit the limit-huge-number-of-dashes path + QRgb fore = qRgb(0, 0, 0xff); + QRgb back = qRgb(0xff, 0xff, 0); + QImage image(5, 32, QImage::Format_RGB32); + image.fill(back); + QPainter p(&image); + QPen pen(QColor(fore), 3, Qt::DotLine); + p.setPen(pen); + p.scale(1, 2); + p.drawLine(2, 0, 2, 16); + p.end(); + + bool foreFound = false; + bool backFound = false; + int i = 0; + while (i < 32 && (!foreFound || !backFound)) { + QRgb pix = image.pixel(3, i); + if (pix == fore) + foreFound = true; + else if (pix == back) + backFound = true; + i++; + } + + QVERIFY(foreFound); + QVERIFY(backFound); +} + +#if QT_CONFIG(raster_fp) +void tst_QPainter::hdrColors() +{ + QImage img(10, 10, QImage::Format_RGBA32FPx4_Premultiplied); + img.fill(Qt::transparent); + + QColor color = QColor::fromRgbF(2.0f, -0.25f, 1.5f); + img.setPixelColor(2, 2, color); + QCOMPARE(img.pixelColor(2, 2), color); + + { + QPainterPath path; + path.addEllipse(4, 4, 2, 2); + QPainter p(&img); + p.fillPath(path, color); + p.end(); + } + QCOMPARE(img.pixelColor(4, 4), color); + + img.fill(color); + QCOMPARE(img.pixelColor(8, 8), color); + + QColor color2 = QColor::fromRgbF(0.0f, 1.25f, 2.5f); + { + QPainter p(&img); + p.fillRect(0, 0, 3, 3, color2); + p.end(); + } + QCOMPARE(img.pixelColor(1, 1), color2); + QCOMPARE(img.pixelColor(4, 4), color); + + QImage img2(10, 10, QImage::Format_RGBX32FPx4); + img2.fill(Qt::black); // fill to avoid random FP values like Inf which can break SourceOver composition + { + QPainter p(&img2); + p.drawImage(0, 0, img); + p.end(); + } + QCOMPARE(img2.pixelColor(2, 2), color2); + QCOMPARE(img2.pixelColor(5, 5), color); +} +#endif + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" |