QPainterPath: Fix boundingRect and controlPointRect ignoring start point

The boundingRect and controlPointRect did not use the start point from
the `QPainterPath(const QPointF &startPoint)` constructor until the
`dirtyBounds` or `dirtyControlBounds` member variables were set to true.
Those two are false on construction. This bug was fixed by adding a new
constructor for QPainterPathPrivate that initializes the `elements`,
`bounds` and `controlBounds` member variables with the start point from
the constructor.

There is also an autotest to verify that the top left of the
boundingRect and controlPointRect are at the same position as
elementAt(0) when the start point constructor is used.

[ChangeLog][QtGui][QPainterPath] boundingRect() and controlPointRect()
now use the start point from QPainterPath(const QPointF &startPoint).

Pick-to: 6.6 6.5
Change-Id: I7bf30364406c14ed60f75d24b78a9a5535f75d93
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit a4f44e06988e91c21c85e0e9f29d656d61f9c68e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Noah Davis 2024-01-27 10:10:10 -05:00 committed by Qt Cherry-pick Bot
parent 4f6cbed4db
commit 327dcc078d
3 changed files with 44 additions and 3 deletions

View File

@ -517,10 +517,8 @@ QPainterPath::QPainterPath(const QPainterPath &other) = default;
*/
QPainterPath::QPainterPath(const QPointF &startPoint)
: d_ptr(new QPainterPathPrivate)
: d_ptr(new QPainterPathPrivate(startPoint))
{
Element e = { startPoint.x(), startPoint.y(), MoveToElement };
d_func()->elements << e;
}
void QPainterPath::detach()

View File

@ -119,6 +119,21 @@ public:
{
}
QPainterPathPrivate(QPointF startPoint)
: QSharedData(),
elements{ { startPoint.x(), startPoint.y(), QPainterPath::MoveToElement } },
cStart(0),
fillRule(Qt::OddEvenFill),
bounds(startPoint, QSizeF(0, 0)),
controlBounds(startPoint, QSizeF(0, 0)),
require_moveTo(false),
dirtyBounds(false),
dirtyControlBounds(false),
convex(false),
pathConverter(nullptr)
{
}
QPainterPathPrivate(const QPainterPathPrivate &other) noexcept
: QSharedData(other),
elements(other.elements),

View File

@ -81,6 +81,8 @@ private slots:
void intersectionEquality();
void intersectionPointOnEdge();
void boundsAtStartPoint();
};
void tst_QPainterPath::cleanupTestCase()
@ -1442,6 +1444,32 @@ void tst_QPainterPath::intersectionPointOnEdge()
QVERIFY(p.intersects(r));
}
void tst_QPainterPath::boundsAtStartPoint()
{
const QPointF startPoint(10, 10);
const QPainterPath constructedPath(startPoint);
{
const auto boundingRect = constructedPath.boundingRect();
const auto topLeft = boundingRect.topLeft();
QCOMPARE(topLeft, startPoint);
QCOMPARE(topLeft, constructedPath.elementAt(0));
QCOMPARE(boundingRect, constructedPath.controlPointRect());
}
QPainterPath defaultPath;
defaultPath.moveTo(startPoint);
{
const auto boundingRect = defaultPath.boundingRect();
const auto topLeft = boundingRect.topLeft();
QCOMPARE(topLeft, startPoint);
QCOMPARE(topLeft, defaultPath.elementAt(0));
QCOMPARE(boundingRect, defaultPath.controlPointRect());
}
QCOMPARE(constructedPath.boundingRect(), defaultPath.boundingRect());
QCOMPARE(constructedPath.controlPointRect(), defaultPath.controlPointRect());
}
QTEST_APPLESS_MAIN(tst_QPainterPath)
#include "tst_qpainterpath.moc"