diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2019-06-28 14:40:04 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2019-07-31 12:05:54 +0200 |
commit | 697910e5fbd382e78bc1bcbac3f5824aded059b4 (patch) | |
tree | 96a3036426dc2c9340eaee48abb01d57887d74c9 | |
parent | a4567c90581e260f036d3966e5965ffb8dc9a951 (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.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath_p.h | 2 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp | 10 |
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() |