QPen: port to QESDP
Move from a manually managed d-pointer to QESDP. This is a long overdue change (QPen is one of the few classes still with manual management). At the same time: it's also one of the central classes, and in order to keep the impact minimal (and binary compatible), I'm not switching to something more sophisticated. As a drive-by: drop QPenData, a remnant only used by QPen itself, which nowadays is simply a typedef for QPenPrivate. Change-Id: I38834116d7d383f29bb69ff20b0a46dfe951bb53 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
cf6bccbcf5
commit
74b67c8f84
@ -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<QPenData *>(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<QPenData *>(d);
|
||||
dd->dashPattern.clear();
|
||||
dd->dashOffset = 0;
|
||||
d->dashPattern.clear();
|
||||
d->dashOffset = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -419,36 +399,35 @@ void QPen::setStyle(Qt::PenStyle s)
|
||||
*/
|
||||
QList<qreal> QPen::dashPattern() const
|
||||
{
|
||||
QPenData *dd = static_cast<QPenData *>(d);
|
||||
if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
|
||||
return QList<qreal>();
|
||||
} 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<qreal> &pattern)
|
||||
return;
|
||||
detach();
|
||||
|
||||
QPenData *dd = static_cast<QPenData *>(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<qreal> &pattern)
|
||||
*/
|
||||
qreal QPen::dashOffset() const
|
||||
{
|
||||
QPenData *dd = static_cast<QPenData *>(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<QPenData *>(d)->dashOffset))
|
||||
if (qFuzzyCompare(offset, d->dashOffset))
|
||||
return;
|
||||
detach();
|
||||
QPenData *dd = static_cast<QPenData *>(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<QPenData *>(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<QPenData *>(d);
|
||||
dd->miterLimit = limit;
|
||||
d->miterLimit = limit;
|
||||
}
|
||||
|
||||
|
||||
@ -782,8 +756,7 @@ bool QPen::isSolid() const
|
||||
|
||||
bool QPen::isCosmetic() const
|
||||
{
|
||||
QPenData *dd = static_cast<QPenData *>(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<QPenData *>(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<QPenData *>(d);
|
||||
QPenData *pdd = static_cast<QPenData *>(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<QPenData *>(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<QPenData *>(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;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifndef QPEN_H
|
||||
#define QPEN_H
|
||||
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtGui/qtguiglobal.h>
|
||||
#include <QtGui/qcolor.h>
|
||||
#include <QtGui/qbrush.h>
|
||||
@ -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<QPenPrivate>;
|
||||
|
||||
private:
|
||||
void detach();
|
||||
class QPenPrivate *d;
|
||||
DataPtr d;
|
||||
|
||||
public:
|
||||
typedef QPenPrivate * DataPtr;
|
||||
inline DataPtr &data_ptr() { return d; }
|
||||
};
|
||||
|
||||
|
@ -16,14 +16,15 @@
|
||||
//
|
||||
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user