diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index d79c85c8f5d..21a0d39855c 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1302,7 +1302,7 @@ void QPainterPath::addRegion(const QRegion ®ion) */ Qt::FillRule QPainterPath::fillRule() const { - return !d_func() ? Qt::OddEvenFill : d_func()->fillRule; + return d_func() && d_func()->hasWindingFill ? Qt::WindingFill : Qt::OddEvenFill; } /*! @@ -1325,11 +1325,12 @@ Qt::FillRule QPainterPath::fillRule() const void QPainterPath::setFillRule(Qt::FillRule fillRule) { ensureData(); - if (d_func()->fillRule == fillRule) + const bool isWindingRequested = (fillRule == Qt::WindingFill); + if (d_func()->hasWindingFill == isWindingRequested) return; detach(); - d_func()->fillRule = fillRule; + d_func()->hasWindingFill = isWindingRequested; } #define QT_BEZIER_A(bezier, coord) 3 * (-bezier.coord##1 \ @@ -1835,7 +1836,7 @@ bool QPainterPath::contains(const QPointF &pt) const if (last_pt != last_start) qt_painterpath_isect_line(last_pt, last_start, pt, &winding_number); - return (d->fillRule == Qt::WindingFill + return (d->hasWindingFill ? (winding_number != 0) : ((winding_number % 2) != 0)); } @@ -2257,13 +2258,13 @@ bool QPainterPath::operator==(const QPainterPath &path) const if (other_d == d) { return true; } else if (!d || !other_d) { - if (!other_d && isEmpty() && elementAt(0) == QPointF() && d->fillRule == Qt::OddEvenFill) + if (!other_d && isEmpty() && elementAt(0) == QPointF() && !d->hasWindingFill) return true; - if (!d && path.isEmpty() && path.elementAt(0) == QPointF() && other_d->fillRule == Qt::OddEvenFill) + if (!d && path.isEmpty() && path.elementAt(0) == QPointF() && !other_d->hasWindingFill) return true; return false; } - else if (d->fillRule != other_d->fillRule) + else if (d->hasWindingFill != other_d->hasWindingFill) return false; else if (d->elements.size() != other_d->elements.size()) return false; @@ -2419,7 +2420,7 @@ QDataStream &operator<<(QDataStream &s, const QPainterPath &p) s << double(e.x) << double(e.y); } s << p.d_func()->cStart; - s << int(p.d_func()->fillRule); + s << int(p.fillRule()); return s; } @@ -2467,7 +2468,7 @@ QDataStream &operator>>(QDataStream &s, QPainterPath &p) int fillRule; s >> fillRule; Q_ASSERT(fillRule == Qt::OddEvenFill || fillRule == Qt::WindingFill); - p.d_func()->fillRule = Qt::FillRule(fillRule); + p.d_func()->hasWindingFill = (Qt::FillRule(fillRule) == Qt::WindingFill); if (errorDetected || p.d_func()->elements.isEmpty()) p = QPainterPath(); // Better than to return path with possibly corrupt datastructure, which would likely cause crash return s; diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index 5cc0dbd362d..eb6878ce712 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -35,8 +35,8 @@ class QVectorPathConverter; class QVectorPathConverter { public: - QVectorPathConverter(const QList &path, uint fillRule, bool convex) - : pathData(path, fillRule, convex), + QVectorPathConverter(const QList &path, bool hasWindingFill, bool convex) + : pathData(path, hasWindingFill, convex), path(pathData.points.data(), path.size(), pathData.elements.data(), pathData.flags) { } @@ -46,7 +46,7 @@ public: } struct QVectorPathData { - QVectorPathData(const QList &path, uint fillRule, bool convex) + QVectorPathData(const QList &path, bool hasWindingFill, bool convex) : elements(path.size()), points(path.size() * 2), flags(0) { int ptsPos = 0; @@ -65,7 +65,7 @@ public: isLines = isLines && e.type == (QPainterPath::ElementType) (i%2); } - if (fillRule == Qt::WindingFill) + if (hasWindingFill) flags |= QVectorPath::WindingFill; else flags |= QVectorPath::OddEvenFill; @@ -107,43 +107,38 @@ public: QPainterPathPrivate() noexcept : QSharedData(), - cStart(0), - fillRule(Qt::OddEvenFill), require_moveTo(false), dirtyBounds(false), dirtyControlBounds(false), convex(false), - pathConverter(nullptr) + hasWindingFill(false) { } 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) + hasWindingFill(false) { } QPainterPathPrivate(const QPainterPathPrivate &other) noexcept : QSharedData(other), elements(other.elements), - cStart(other.cStart), - fillRule(other.fillRule), bounds(other.bounds), controlBounds(other.controlBounds), + cStart(other.cStart), require_moveTo(false), dirtyBounds(other.dirtyBounds), dirtyControlBounds(other.dirtyControlBounds), convex(other.convex), - pathConverter(nullptr) + hasWindingFill(other.hasWindingFill) { } @@ -157,25 +152,23 @@ public: const QVectorPath &vectorPath() { if (!pathConverter) - pathConverter.reset(new QVectorPathConverter(elements, fillRule, convex)); + pathConverter.reset(new QVectorPathConverter(elements, hasWindingFill, convex)); return pathConverter->path; } private: QList elements; - - int cStart; - Qt::FillRule fillRule; - + std::unique_ptr pathConverter; QRectF bounds; QRectF controlBounds; - uint require_moveTo : 1; - uint dirtyBounds : 1; - uint dirtyControlBounds : 1; - uint convex : 1; + int cStart = 0; - std::unique_ptr pathConverter; + bool require_moveTo : 1; + bool dirtyBounds : 1; + bool dirtyControlBounds : 1; + bool convex : 1; + bool hasWindingFill : 1; }; class QPainterPathStrokerPrivate @@ -218,10 +211,7 @@ inline const QPainterPath QVectorPath::convertToPainterPath() const } } - if (m_hints & OddEvenFill) - data->fillRule = Qt::OddEvenFill; - else - data->fillRule = Qt::WindingFill; + data->hasWindingFill = !(m_hints & OddEvenFill); return path; }