summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gui/painting/qpainter/tst_qpainter.cpp')
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp399
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"