diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index 958539feda..d37beda6b6 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -10,8 +10,6 @@ QT_BEGIN_NAMESPACE -typedef QPenPrivate QPenData; - /*! \class QPen \inmodule QtGui @@ -193,7 +191,7 @@ typedef QPenPrivate QPenData; */ QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle, Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle) - : ref(1), dashOffset(0), miterLimit(2), + : dashOffset(0), miterLimit(2), cosmetic(false) { width = _width; @@ -209,17 +207,13 @@ static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin; class QPenDataHolder { public: - QPenData *pen; + QPen::DataPtr pen; QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle, Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle) - : pen(new QPenData(brush, width, penStyle, penCapStyle, _joinStyle)) + : pen(new QPenPrivate(brush, width, penStyle, penCapStyle, _joinStyle)) { } - ~QPenDataHolder() - { - if (!pen->ref.deref()) - delete pen; - pen = nullptr; - } + ~QPenDataHolder() = default; + Q_DISABLE_COPY_MOVE(QPenDataHolder) }; Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance, @@ -234,7 +228,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance, QPen::QPen() { d = defaultPenInstance()->pen; - d->ref.ref(); } /*! @@ -247,9 +240,8 @@ QPen::QPen(Qt::PenStyle style) { if (style == Qt::NoPen) { d = nullPenInstance()->pen; - d->ref.ref(); } else { - d = new QPenData(Qt::black, 1, style, qpen_default_cap, qpen_default_join); + d = new QPenPrivate(Qt::black, 1, style, qpen_default_cap, qpen_default_join); } } @@ -262,7 +254,7 @@ QPen::QPen(Qt::PenStyle style) QPen::QPen(const QColor &color) { - d = new QPenData(color, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join); + d = new QPenPrivate(color, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join); } @@ -277,7 +269,7 @@ QPen::QPen(const QColor &color) QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j) { - d = new QPenData(brush, width, s, c, j); + d = new QPenPrivate(brush, width, s, c, j); } /*! @@ -287,10 +279,8 @@ QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, */ QPen::QPen(const QPen &p) noexcept + : d(p.d) { - d = p.d; - if (d) - d->ref.ref(); } @@ -309,11 +299,9 @@ QPen::QPen(const QPen &p) noexcept Destroys the pen. */ -QPen::~QPen() -{ - if (d && !d->ref.deref()) - delete d; -} +QPen::~QPen() = default; + +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QPenPrivate) /*! \fn void QPen::detach() @@ -327,14 +315,7 @@ QPen::~QPen() void QPen::detach() { - if (d->ref.loadRelaxed() == 1) - return; - - QPenData *x = new QPenData(*static_cast(d)); - if (!d->ref.deref()) - delete d; - x->ref.storeRelaxed(1); - d = x; + d.detach(); } @@ -407,9 +388,8 @@ void QPen::setStyle(Qt::PenStyle s) return; detach(); d->style = s; - QPenData *dd = static_cast(d); - dd->dashPattern.clear(); - dd->dashOffset = 0; + d->dashPattern.clear(); + d->dashOffset = 0; } /*! @@ -419,36 +399,35 @@ void QPen::setStyle(Qt::PenStyle s) */ QList QPen::dashPattern() const { - QPenData *dd = static_cast(d); if (d->style == Qt::SolidLine || d->style == Qt::NoPen) { return QList(); - } else if (dd->dashPattern.isEmpty()) { + } else if (d->dashPattern.isEmpty()) { const qreal space = 2; const qreal dot = 1; const qreal dash = 4; switch (d->style) { case Qt::DashLine: - dd->dashPattern.reserve(2); - dd->dashPattern << dash << space; + d->dashPattern.reserve(2); + d->dashPattern << dash << space; break; case Qt::DotLine: - dd->dashPattern.reserve(2); - dd->dashPattern << dot << space; + d->dashPattern.reserve(2); + d->dashPattern << dot << space; break; case Qt::DashDotLine: - dd->dashPattern.reserve(4); - dd->dashPattern << dash << space << dot << space; + d->dashPattern.reserve(4); + d->dashPattern << dash << space << dot << space; break; case Qt::DashDotDotLine: - dd->dashPattern.reserve(6); - dd->dashPattern << dash << space << dot << space << dot << space; + d->dashPattern.reserve(6); + d->dashPattern << dash << space << dot << space << dot << space; break; default: break; } } - return dd->dashPattern; + return d->dashPattern; } /*! @@ -487,13 +466,12 @@ void QPen::setDashPattern(const QList &pattern) return; detach(); - QPenData *dd = static_cast(d); - dd->dashPattern = pattern; + d->dashPattern = pattern; d->style = Qt::CustomDashLine; - if ((dd->dashPattern.size() % 2) == 1) { + if ((d->dashPattern.size() % 2) == 1) { qWarning("QPen::setDashPattern: Pattern not of even length"); - dd->dashPattern << 1; + d->dashPattern << 1; } } @@ -505,8 +483,7 @@ void QPen::setDashPattern(const QList &pattern) */ qreal QPen::dashOffset() const { - QPenData *dd = static_cast(d); - return dd->dashOffset; + return d->dashOffset; } /*! Sets the dash offset (the starting point on the dash pattern) for this pen @@ -528,13 +505,12 @@ qreal QPen::dashOffset() const */ void QPen::setDashOffset(qreal offset) { - if (qFuzzyCompare(offset, static_cast(d)->dashOffset)) + if (qFuzzyCompare(offset, d->dashOffset)) return; detach(); - QPenData *dd = static_cast(d); - dd->dashOffset = offset; + d->dashOffset = offset; if (d->style != Qt::CustomDashLine) { - dd->dashPattern = dashPattern(); + d->dashPattern = dashPattern(); d->style = Qt::CustomDashLine; } } @@ -547,8 +523,7 @@ void QPen::setDashOffset(qreal offset) */ qreal QPen::miterLimit() const { - const QPenData *dd = static_cast(d); - return dd->miterLimit; + return d->miterLimit; } /*! @@ -570,8 +545,7 @@ qreal QPen::miterLimit() const void QPen::setMiterLimit(qreal limit) { detach(); - QPenData *dd = static_cast(d); - dd->miterLimit = limit; + d->miterLimit = limit; } @@ -782,8 +756,7 @@ bool QPen::isSolid() const bool QPen::isCosmetic() const { - QPenData *dd = static_cast(d); - return (dd->cosmetic == true) || d->width == 0; + return (d->cosmetic == true) || d->width == 0; } @@ -797,8 +770,7 @@ bool QPen::isCosmetic() const void QPen::setCosmetic(bool cosmetic) { detach(); - QPenData *dd = static_cast(d); - dd->cosmetic = cosmetic; + d->cosmetic = cosmetic; } @@ -825,19 +797,17 @@ void QPen::setCosmetic(bool cosmetic) bool QPen::operator==(const QPen &p) const { - QPenData *dd = static_cast(d); - QPenData *pdd = static_cast(p.d); return (p.d == d) || (p.d->style == d->style && p.d->capStyle == d->capStyle && p.d->joinStyle == d->joinStyle && p.d->width == d->width - && pdd->miterLimit == dd->miterLimit + && p.d->miterLimit == d->miterLimit && (d->style != Qt::CustomDashLine - || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) && - pdd->dashPattern == dd->dashPattern)) + || (qFuzzyCompare(p.d->dashOffset, d->dashOffset) && + p.d->dashPattern == d->dashPattern)) && p.d->brush == d->brush - && pdd->cosmetic == dd->cosmetic); + && p.d->cosmetic == d->cosmetic); } @@ -869,14 +839,13 @@ bool QPen::isDetached() QDataStream &operator<<(QDataStream &s, const QPen &p) { - QPenData *dd = static_cast(p.d); if (s.version() < 3) { s << (quint8)p.style(); } else if (s.version() < QDataStream::Qt_4_3) { s << (quint8)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle())); } else { s << (quint16)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle())); - s << (bool)(dd->cosmetic); + s << (bool)(p.d->cosmetic); } if (s.version() < 7) { @@ -965,16 +934,15 @@ QDataStream &operator>>(QDataStream &s, QPen &p) } p.detach(); - QPenData *dd = static_cast(p.d); - dd->width = width; - dd->brush = brush; - dd->style = Qt::PenStyle(style & Qt::MPenStyle); - dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle); - dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle); - dd->dashPattern = dashPattern; - dd->miterLimit = miterLimit; - dd->dashOffset = dashOffset; - dd->cosmetic = cosmetic; + p.d->width = width; + p.d->brush = brush; + p.d->style = Qt::PenStyle(style & Qt::MPenStyle); + p.d->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle); + p.d->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle); + p.d->dashPattern = dashPattern; + p.d->miterLimit = miterLimit; + p.d->dashOffset = dashOffset; + p.d->cosmetic = cosmetic; return s; } diff --git a/src/gui/painting/qpen.h b/src/gui/painting/qpen.h index 2f38098496..3367b96c35 100644 --- a/src/gui/painting/qpen.h +++ b/src/gui/painting/qpen.h @@ -4,6 +4,7 @@ #ifndef QPEN_H #define QPEN_H +#include #include #include #include @@ -21,6 +22,8 @@ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPen &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPen &); #endif +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QPenPrivate, Q_GUI_EXPORT) + class Q_GUI_EXPORT QPen { public: @@ -34,10 +37,9 @@ public: ~QPen(); QPen &operator=(const QPen &pen) noexcept; - QPen(QPen &&other) noexcept - : d(std::exchange(other.d, nullptr)) {} + QPen(QPen &&other) noexcept = default; QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QPen) - void swap(QPen &other) noexcept { qt_ptr_swap(d, other.d); } + void swap(QPen &other) noexcept { d.swap(other.d); } Qt::PenStyle style() const; void setStyle(Qt::PenStyle); @@ -79,15 +81,19 @@ public: operator QVariant() const; bool isDetached(); + private: friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPen &); friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPen &); +public: + using DataPtr = QExplicitlySharedDataPointer; + +private: void detach(); - class QPenPrivate *d; + DataPtr d; public: - typedef QPenPrivate * DataPtr; inline DataPtr &data_ptr() { return d; } }; diff --git a/src/gui/painting/qpen_p.h b/src/gui/painting/qpen_p.h index 39ed024d85..a939c5e4f6 100644 --- a/src/gui/painting/qpen_p.h +++ b/src/gui/painting/qpen_p.h @@ -16,14 +16,15 @@ // #include +#include QT_BEGIN_NAMESPACE -class QPenPrivate { +class QPenPrivate : public QSharedData +{ public: QPenPrivate(const QBrush &brush, qreal width, Qt::PenStyle, Qt::PenCapStyle, Qt::PenJoinStyle _joinStyle); - QAtomicInt ref; qreal width; QBrush brush; Qt::PenStyle style;