summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2019-06-28 14:40:04 +0200
committerEirik Aavitsland <eirik.aavitsland@qt.io>2019-07-31 12:05:54 +0200
commit697910e5fbd382e78bc1bcbac3f5824aded059b4 (patch)
tree96a3036426dc2c9340eaee48abb01d57887d74c9
parenta4567c90581e260f036d3966e5965ffb8dc9a951 (diff)
Fix assert in QPainterPath after clear()
The newly introduced clear() method left the path in an undefined state: d_ptr allocated, but no elements. The elements vector is otherwise never empty, since ensureData() inserts a dummy initial moveTo element. Fix by making sure that clear() leaves the path in the same state as ensureData() (i.e. "empty" but not "null"), except possibly more capacity allocated in the elements vector. Fixes: QTBUG-76534 Change-Id: I7ad8b312913f5eb6e22023f5d2fd873e54b1e23c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--src/gui/painting/qpainterpath.cpp9
-rw-r--r--src/gui/painting/qpainterpath_p.h2
-rw-r--r--tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp10
3 files changed, 15 insertions, 6 deletions
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index d20faf89a2..8516d73537 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -661,6 +661,7 @@ void QPainterPath::clear()
detach();
d_func()->clear();
+ d_func()->elements.append( {0, 0, MoveToElement} );
}
/*!
@@ -2337,12 +2338,12 @@ bool QPainterPath::operator==(const QPainterPath &path) const
{
QPainterPathData *d = reinterpret_cast<QPainterPathData *>(d_func());
QPainterPathData *other_d = path.d_func();
- if (other_d == d)
+ if (other_d == d) {
return true;
- else if (!d || !other_d) {
- if (!d && other_d->elements.empty() && other_d->fillRule == Qt::OddEvenFill)
+ } else if (!d || !other_d) {
+ if (!other_d && isEmpty() && elementAt(0) == QPointF() && d->fillRule == Qt::OddEvenFill)
return true;
- if (!other_d && d && d->elements.empty() && d->fillRule == Qt::OddEvenFill)
+ if (!d && path.isEmpty() && path.elementAt(0) == QPointF() && other_d->fillRule == Qt::OddEvenFill)
return true;
return false;
}
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index a36c8005bc..567f155210 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -298,7 +298,7 @@ inline void QPainterPathData::clear()
elements.clear();
cStart = 0;
-
+ fillRule = Qt::OddEvenFill;
bounds = {};
controlBounds = {};
diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
index c90348e91a..67cf9a321a 100644
--- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
+++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
@@ -161,10 +161,18 @@ void tst_QPainterPath::clear()
p1.clear();
QCOMPARE(p1, p2);
+ p1.lineTo(50, 50);
+ QPainterPath p3;
+ QCOMPARE(p1.elementCount(), 2);
+ p3.lineTo(50, 50);
+ QCOMPARE(p1, p3);
+
QCOMPARE(p1.fillRule(), Qt::OddEvenFill);
p1.setFillRule(Qt::WindingFill);
+ QVERIFY(p1 != p3);
p1.clear();
- QCOMPARE(p1.fillRule(), Qt::WindingFill);
+ QCOMPARE(p1.fillRule(), Qt::OddEvenFill);
+ QCOMPARE(p1, p2);
}
void tst_QPainterPath::reserveAndCapacity()