make private QBrush data actually private [ci reset]

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2021-11-28 23:02:04 +02:00
parent 40674e4110
commit bb3178f4de
4 changed files with 95 additions and 173 deletions

View file

@ -66,6 +66,18 @@ Q_GUI_EXPORT QImage qt_diagCrossBrush()
return QImage(qt_patternForBrush(Qt::DiagCrossPattern), 8, 8, 1, QImage::Format_MonoLSB); return QImage(qt_patternForBrush(Qt::DiagCrossPattern), 8, 8, 1, QImage::Format_MonoLSB);
} }
class QBrushData
{
public:
QBrushData() : ref(1), style(Qt::NoBrush), color(Qt::black) { }
QAtomicInt ref;
Qt::BrushStyle style;
QColor color;
QTransform transform;
};
struct QTexturedBrushData : public QBrushData struct QTexturedBrushData : public QBrushData
{ {
QTexturedBrushData() { QTexturedBrushData() {
@ -121,7 +133,7 @@ bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush)
{ {
if (brush.style() != Qt::TexturePattern) if (brush.style() != Qt::TexturePattern)
return false; return false;
QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d.data()); QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d);
return tx_data->m_has_pixmap_texture; return tx_data->m_has_pixmap_texture;
} }
@ -130,27 +142,6 @@ struct QGradientBrushData : public QBrushData
QGradient gradient; QGradient gradient;
}; };
struct QBrushDataPointerDeleter
{
static inline void cleanup(QBrushData *d)
{
if (d && !d->ref.deref()) {
switch (d->style) {
case Qt::TexturePattern:
delete static_cast<QTexturedBrushData*>(d);
break;
case Qt::LinearGradientPattern:
case Qt::RadialGradientPattern:
case Qt::ConicalGradientPattern:
delete static_cast<QGradientBrushData*>(d);
break;
default:
delete d;
}
}
}
};
/*! /*!
\class QBrush \class QBrush
\ingroup painting \ingroup painting
@ -231,33 +222,6 @@ struct QBrushDataPointerDeleter
\sa Qt::BrushStyle, QPainter, QColor \sa Qt::BrushStyle, QPainter, QColor
*/ */
// Special deleter that only deletes if the ref-count goes to zero
template <>
class QGlobalStaticDeleter<QBrushData>
{
public:
QGlobalStatic<QBrushData> &globalStatic;
QGlobalStaticDeleter(QGlobalStatic<QBrushData> &_globalStatic)
: globalStatic(_globalStatic)
{ }
inline ~QGlobalStaticDeleter()
{
if (!globalStatic.pointer->ref.deref()) {
delete globalStatic.pointer;
globalStatic.pointer = nullptr;
globalStatic.destroyed = true;
}
}
};
Q_GLOBAL_STATIC_WITH_INITIALIZER(QBrushData, nullBrushInstance,
{
x->ref = 1;
x->style = Qt::NoBrush;
x->color = Qt::black;
})
static bool qbrush_check_type(Qt::BrushStyle style) { static bool qbrush_check_type(Qt::BrushStyle style) {
switch (style) { switch (style) {
case Qt::TexturePattern: case Qt::TexturePattern:
@ -281,25 +245,26 @@ static bool qbrush_check_type(Qt::BrushStyle style) {
void QBrush::init(const QColor &color, Qt::BrushStyle style) void QBrush::init(const QColor &color, Qt::BrushStyle style)
{ {
// d may have randomized non-zero value (unitialized)
// Q_ASSERT(!d);
switch(style) { switch(style) {
case Qt::NoBrush: case Qt::NoBrush:
d.reset(nullBrushInstance()); d = new QBrushData();
d->ref.ref();
if (d->color != color) setColor(color); if (d->color != color) setColor(color);
return; return;
case Qt::TexturePattern: case Qt::TexturePattern:
d.reset(new QTexturedBrushData); d = new QTexturedBrushData();
break; break;
case Qt::LinearGradientPattern: case Qt::LinearGradientPattern:
case Qt::RadialGradientPattern: case Qt::RadialGradientPattern:
case Qt::ConicalGradientPattern: case Qt::ConicalGradientPattern:
d.reset(new QGradientBrushData); d = new QGradientBrushData();
break; break;
default: default:
d.reset(new QBrushData); d = new QBrushData();
break; break;
} }
d->ref = 1;
d->style = style; d->style = style;
d->color = color; d->color = color;
} }
@ -310,10 +275,8 @@ void QBrush::init(const QColor &color, Qt::BrushStyle style)
*/ */
QBrush::QBrush() QBrush::QBrush()
: d(nullBrushInstance()) : d(new QBrushData())
{ {
Q_ASSERT(d);
d->ref.ref();
} }
/*! /*!
@ -354,8 +317,7 @@ QBrush::QBrush(Qt::BrushStyle style)
if (qbrush_check_type(style)) if (qbrush_check_type(style))
init(Qt::black, style); init(Qt::black, style);
else { else {
d.reset(nullBrushInstance()); d = new QBrushData();
d->ref.ref();
} }
} }
@ -370,14 +332,11 @@ QBrush::QBrush(const QColor &color, Qt::BrushStyle style)
if (qbrush_check_type(style)) if (qbrush_check_type(style))
init(color, style); init(color, style);
else { else {
d.reset(nullBrushInstance()); d = new QBrushData();
d->ref.ref();
} }
} }
/*! /*!
\fn QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style)
Constructs a brush with the given \a color and \a style. Constructs a brush with the given \a color and \a style.
\sa setColor(), setStyle() \sa setColor(), setStyle()
@ -387,8 +346,7 @@ QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style)
if (qbrush_check_type(style)) if (qbrush_check_type(style))
init(color, style); init(color, style);
else { else {
d.reset(nullBrushInstance()); d = new QBrushData();
d->ref.ref();
} }
} }
@ -429,7 +387,7 @@ QBrush::QBrush(Qt::GlobalColor color, const QPixmap &pixmap)
*/ */
QBrush::QBrush(const QBrush &other) QBrush::QBrush(const QBrush &other)
: d(other.d.data()) : d(other.d)
{ {
d->ref.ref(); d->ref.ref();
} }
@ -454,7 +412,7 @@ QBrush::QBrush(const QGradient &gradient)
}; };
init(QColor(), enumTbl[gradient.type()]); init(QColor(), enumTbl[gradient.type()]);
QGradientBrushData *grad = static_cast<QGradientBrushData *>(d.data()); QGradientBrushData *grad = static_cast<QGradientBrushData *>(d);
grad->gradient = gradient; grad->gradient = gradient;
} }
@ -464,6 +422,20 @@ QBrush::QBrush(const QGradient &gradient)
QBrush::~QBrush() QBrush::~QBrush()
{ {
if (d && !d->ref.deref()) {
switch (d->style) {
case Qt::TexturePattern:
delete static_cast<QTexturedBrushData*>(d);
break;
case Qt::LinearGradientPattern:
case Qt::RadialGradientPattern:
case Qt::ConicalGradientPattern:
delete static_cast<QGradientBrushData*>(d);
break;
default:
delete d;
}
}
} }
void QBrush::detach(Qt::BrushStyle newStyle) void QBrush::detach(Qt::BrushStyle newStyle)
@ -476,7 +448,7 @@ void QBrush::detach(Qt::BrushStyle newStyle)
case Qt::TexturePattern: { case Qt::TexturePattern: {
QTexturedBrushData *tbd = new QTexturedBrushData; QTexturedBrushData *tbd = new QTexturedBrushData;
if (d->style == Qt::TexturePattern) { if (d->style == Qt::TexturePattern) {
QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data()); QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d);
if (data->m_has_pixmap_texture) if (data->m_has_pixmap_texture)
tbd->setPixmap(data->pixmap()); tbd->setPixmap(data->pixmap());
else else
@ -490,34 +462,30 @@ void QBrush::detach(Qt::BrushStyle newStyle)
case Qt::ConicalGradientPattern: case Qt::ConicalGradientPattern:
x.reset(new QGradientBrushData); x.reset(new QGradientBrushData);
static_cast<QGradientBrushData *>(x.data())->gradient = static_cast<QGradientBrushData *>(x.data())->gradient =
static_cast<QGradientBrushData *>(d.data())->gradient; static_cast<QGradientBrushData *>(d)->gradient;
break; break;
default: default:
x.reset(new QBrushData); x.reset(new QBrushData());
break; break;
} }
x->ref = 1;
x->style = newStyle; x->style = newStyle;
x->color = d->color; x->color = d->color;
x->transform = d->transform; x->transform = d->transform;
d.reset(x.take());
if (!d->ref.deref())
delete d;
d = x.take();
} }
/*! /*!
\fn QBrush &QBrush::operator=(const QBrush &brush) Assigns the given \a other to \e this brush and returns a
Assigns the given \a brush to \e this brush and returns a
reference to \e this brush. reference to \e this brush.
*/ */
QBrush &QBrush::operator=(const QBrush &b) QBrush &QBrush::operator=(const QBrush &other)
{ {
if (d == b.d) qAtomicAssign(d, other.d);
return *this;
b.d->ref.ref();
d.reset(b.d.data());
return *this; return *this;
} }
@ -539,12 +507,14 @@ QBrush::operator QVariant() const
} }
/*! /*!
\fn Qt::BrushStyle QBrush::style() const
Returns the brush style. Returns the brush style.
\sa setStyle() \sa setStyle()
*/ */
Qt::BrushStyle QBrush::style() const
{
return d->style;
}
/*! /*!
Sets the brush style to \a style. Sets the brush style to \a style.
@ -565,16 +535,16 @@ void QBrush::setStyle(Qt::BrushStyle style)
/*! /*!
\fn const QColor &QBrush::color() const
Returns the brush color. Returns the brush color.
\sa setColor() \sa setColor()
*/ */
const QColor &QBrush::color() const
{
return d->color;
}
/*! /*!
\fn void QBrush::setColor(const QColor &color)
Sets the brush color to the given \a color. Sets the brush color to the given \a color.
Note that calling setColor() will not make a difference if the Note that calling setColor() will not make a difference if the
@ -597,11 +567,7 @@ void QBrush::setColor(const QColor &c)
Sets the brush color to the given \a color. Sets the brush color to the given \a color.
*/ */
/*! /*!
\fn QPixmap QBrush::texture() const
Returns the custom brush pattern, or a null pixmap if no custom brush pattern Returns the custom brush pattern, or a null pixmap if no custom brush pattern
has been set. has been set.
@ -610,7 +576,7 @@ void QBrush::setColor(const QColor &c)
QPixmap QBrush::texture() const QPixmap QBrush::texture() const
{ {
return d->style == Qt::TexturePattern return d->style == Qt::TexturePattern
? (static_cast<QTexturedBrushData *>(d.data()))->pixmap() ? (static_cast<QTexturedBrushData *>(d))->pixmap()
: QPixmap(); : QPixmap();
} }
@ -628,7 +594,7 @@ void QBrush::setTexture(const QPixmap &pixmap)
{ {
if (!pixmap.isNull()) { if (!pixmap.isNull()) {
detach(Qt::TexturePattern); detach(Qt::TexturePattern);
QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data()); QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d);
data->setPixmap(pixmap); data->setPixmap(pixmap);
} else { } else {
detach(Qt::NoBrush); detach(Qt::NoBrush);
@ -651,7 +617,7 @@ void QBrush::setTexture(const QPixmap &pixmap)
QImage QBrush::textureImage() const QImage QBrush::textureImage() const
{ {
return d->style == Qt::TexturePattern return d->style == Qt::TexturePattern
? (static_cast<QTexturedBrushData *>(d.data()))->image() ? (static_cast<QTexturedBrushData *>(d))->image()
: QImage(); : QImage();
} }
@ -676,7 +642,7 @@ void QBrush::setTextureImage(const QImage &image)
{ {
if (!image.isNull()) { if (!image.isNull()) {
detach(Qt::TexturePattern); detach(Qt::TexturePattern);
QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data()); QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d);
data->setImage(image); data->setImage(image);
} else { } else {
detach(Qt::NoBrush); detach(Qt::NoBrush);
@ -692,7 +658,7 @@ const QGradient *QBrush::gradient() const
if (d->style == Qt::LinearGradientPattern if (d->style == Qt::LinearGradientPattern
|| d->style == Qt::RadialGradientPattern || d->style == Qt::RadialGradientPattern
|| d->style == Qt::ConicalGradientPattern) { || d->style == Qt::ConicalGradientPattern) {
return &static_cast<const QGradientBrushData *>(d.data())->gradient; return &static_cast<const QGradientBrushData *>(d)->gradient;
} }
return 0; return 0;
} }
@ -774,13 +740,16 @@ void QBrush::setTransform(const QTransform &matrix)
/*! /*!
\fn void QBrush::matrix() const
\since 4.2 \since 4.2
Returns the current transformation matrix for the brush. Returns the current transformation matrix for the brush.
\sa setMatrix() \sa setMatrix()
*/ */
const QMatrix &QBrush::matrix() const
{
return d->transform.toAffine();
}
/*! /*!
\fn bool QBrush::operator!=(const QBrush &brush) const \fn bool QBrush::operator!=(const QBrush &brush) const
@ -795,9 +764,7 @@ void QBrush::setTransform(const QTransform &matrix)
*/ */
/*! /*!
\fn bool QBrush::operator==(const QBrush &brush) const Returns true if the brush is equal to the given \a other;
Returns true if the brush is equal to the given \a brush;
otherwise returns false. otherwise returns false.
Two brushes are equal if they have equal styles, colors and Two brushes are equal if they have equal styles, colors and
@ -806,25 +773,25 @@ void QBrush::setTransform(const QTransform &matrix)
\sa operator!=() \sa operator!=()
*/ */
bool QBrush::operator==(const QBrush &b) const bool QBrush::operator==(const QBrush &other) const
{ {
if (b.d == d) if (other.d == d)
return true; return true;
if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform) if (other.d->style != d->style || other.d->color != d->color || other.d->transform != d->transform)
return false; return false;
switch (d->style) { switch (d->style) {
case Qt::TexturePattern: case Qt::TexturePattern:
{ {
const QPixmap &us = (static_cast<QTexturedBrushData *>(d.data()))->pixmap(); const QPixmap &us = (static_cast<QTexturedBrushData *>(d))->pixmap();
const QPixmap &them = (static_cast<QTexturedBrushData *>(b.d.data()))->pixmap(); const QPixmap &them = (static_cast<QTexturedBrushData *>(other.d))->pixmap();
return ((us.isNull() && them.isNull()) || us.cacheKey() == them.cacheKey()); return ((us.isNull() && them.isNull()) || us.cacheKey() == them.cacheKey());
} }
case Qt::LinearGradientPattern: case Qt::LinearGradientPattern:
case Qt::RadialGradientPattern: case Qt::RadialGradientPattern:
case Qt::ConicalGradientPattern: case Qt::ConicalGradientPattern:
{ {
const QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.data()); const QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d);
const QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.data()); const QGradientBrushData *d2 = static_cast<QGradientBrushData *>(other.d);
return d1->gradient == d2->gradient; return d1->gradient == d2->gradient;
} }
default: default:
@ -1210,8 +1177,6 @@ QGradient::QGradient()
*/ */
/*! /*!
\fn void QGradient::setColorAt(qreal position, const QColor &color)
Creates a stop point at the given \a position with the given \a Creates a stop point at the given \a position with the given \a
color. The given \a position must be in the range 0 to 1. color. The given \a position must be in the range 0 to 1.
@ -1236,8 +1201,6 @@ void QGradient::setColorAt(qreal pos, const QColor &color)
} }
/*! /*!
\fn void QGradient::setStops(const QGradientStops &stopPoints)
Replaces the current set of stop points with the given \a Replaces the current set of stop points with the given \a
stopPoints. The positions of the points must be in the range 0 to stopPoints. The positions of the points must be in the range 0 to
1, and must be sorted with the lowest point first. 1, and must be sorted with the lowest point first.
@ -1470,8 +1433,6 @@ QLinearGradient::QLinearGradient(const QPointF &start, const QPointF &finalStop)
} }
/*! /*!
\fn QLinearGradient::QLinearGradient(qreal x1, qreal y1, qreal x2, qreal y2)
Constructs a linear gradient with interpolation area between (\a Constructs a linear gradient with interpolation area between (\a
x1, \a y1) and (\a x2, \a y2). x1, \a y1) and (\a x2, \a y2).
@ -2099,29 +2060,16 @@ void QConicalGradient::setAngle(qreal angle)
*/ */
/*! /*!
\typedef QBrush::DataPtr
\internal
*/
/*!
\fn DataPtr &QBrush::data_ptr()
\internal
*/
/*!
\fn bool QBrush::isDetached() const
\internal
*/
/*!
\fn QTransform QBrush::transform() const
\since 4.3 \since 4.3
Returns the current transformation matrix for the brush. Returns the current transformation matrix for the brush.
\sa setTransform() \sa setTransform()
*/ */
QTransform QBrush::transform() const
{
return d->transform;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -25,7 +25,6 @@
#include <QtCore/qpair.h> #include <QtCore/qpair.h>
#include <QtCore/qpoint.h> #include <QtCore/qpoint.h>
#include <QtCore/qvector.h> #include <QtCore/qvector.h>
#include <QtCore/qscopedpointer.h>
#include <QtGui/qcolor.h> #include <QtGui/qcolor.h>
#include <QtGui/qmatrix.h> #include <QtGui/qmatrix.h>
#include <QtGui/qtransform.h> #include <QtGui/qtransform.h>
@ -38,15 +37,7 @@ QT_BEGIN_NAMESPACE
class QPixmap; class QPixmap;
class QGradient; class QGradient;
class QVariant; class QVariant;
struct QBrushDataPointerDeleter; class QBrushData;
struct QBrushData
{
QAtomicInt ref;
Qt::BrushStyle style;
QColor color;
QTransform transform;
};
class Q_GUI_EXPORT QBrush class Q_GUI_EXPORT QBrush
{ {
@ -66,7 +57,7 @@ public:
QBrush(const QGradient &gradient); QBrush(const QGradient &gradient);
~QBrush(); ~QBrush();
QBrush &operator=(const QBrush &brush); QBrush &operator=(const QBrush &other);
#ifdef Q_COMPILER_RVALUE_REFS #ifdef Q_COMPILER_RVALUE_REFS
inline QBrush &operator=(QBrush &&other) inline QBrush &operator=(QBrush &&other)
{ qSwap(d, other.d); return *this; } { qSwap(d, other.d); return *this; }
@ -75,13 +66,13 @@ public:
operator QVariant() const; operator QVariant() const;
inline Qt::BrushStyle style() const; Qt::BrushStyle style() const;
void setStyle(Qt::BrushStyle); void setStyle(Qt::BrushStyle);
inline const QMatrix &matrix() const; const QMatrix &matrix() const;
void setMatrix(const QMatrix &mat); void setMatrix(const QMatrix &mat);
inline QTransform transform() const; QTransform transform() const;
void setTransform(const QTransform &); void setTransform(const QTransform &);
QPixmap texture() const; QPixmap texture() const;
@ -90,7 +81,7 @@ public:
QImage textureImage() const; QImage textureImage() const;
void setTextureImage(const QImage &image); void setTextureImage(const QImage &image);
inline const QColor &color() const; const QColor &color() const;
void setColor(const QColor &color); void setColor(const QColor &color);
inline void setColor(Qt::GlobalColor color); inline void setColor(Qt::GlobalColor color);
@ -98,34 +89,23 @@ public:
bool isOpaque() const; bool isOpaque() const;
bool operator==(const QBrush &b) const; bool operator==(const QBrush &other) const;
inline bool operator!=(const QBrush &b) const { return !(operator==(b)); } inline bool operator!=(const QBrush &other) const { return !(operator==(other)); }
private: private:
#if defined(Q_WS_X11)
friend class QX11PaintEngine;
#endif
friend class QRasterPaintEngine;
friend class QRasterPaintEnginePrivate;
friend struct QSpanData;
friend class QPainter;
friend bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush); friend bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush);
void detach(Qt::BrushStyle newStyle); void detach(Qt::BrushStyle newStyle);
void init(const QColor &color, Qt::BrushStyle bs); void init(const QColor &color, Qt::BrushStyle bs);
QScopedPointer<QBrushData, QBrushDataPointerDeleter> d;
public: QBrushData *d;
inline bool isDetached() const;
typedef QScopedPointer<QBrushData, QBrushDataPointerDeleter> DataPtr;
inline DataPtr &data_ptr() { return d; }
}; };
inline void QBrush::setColor(Qt::GlobalColor acolor) inline void QBrush::setColor(Qt::GlobalColor acolor)
{ setColor(QColor(acolor)); } { setColor(QColor(acolor)); }
Q_DECLARE_TYPEINFO(QBrush, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QBrush, Q_MOVABLE_TYPE);
Q_DECLARE_SHARED(QBrush)
/***************************************************************************** /*****************************************************************************
QBrush stream functions QBrush stream functions
@ -140,14 +120,6 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QBrush &);
Q_GUI_EXPORT QDebug operator<<(QDebug, const QBrush &); Q_GUI_EXPORT QDebug operator<<(QDebug, const QBrush &);
#endif #endif
inline Qt::BrushStyle QBrush::style() const { return d->style; }
inline const QColor &QBrush::color() const { return d->color; }
inline const QMatrix &QBrush::matrix() const { return d->transform.toAffine(); }
inline QTransform QBrush::transform() const { return d->transform; }
inline bool QBrush::isDetached() const { return d->ref == 1; }
/******************************************************************************* /*******************************************************************************
* QGradients * QGradients
*/ */

View file

@ -707,14 +707,16 @@ void QRasterPaintEnginePrivate::systemStateChanged()
void QRasterPaintEnginePrivate::updateMatrixData(QSpanData *spanData, const QBrush &b, const QTransform &m) void QRasterPaintEnginePrivate::updateMatrixData(QSpanData *spanData, const QBrush &b, const QTransform &m)
{ {
if (b.d->style == Qt::NoBrush || b.d->style == Qt::SolidPattern) const Qt::BrushStyle bstyle(b.style());
if (bstyle == Qt::NoBrush || bstyle == Qt::SolidPattern)
return; return;
Q_Q(QRasterPaintEngine); Q_Q(QRasterPaintEngine);
bool bilinear = q->state()->flags.bilinear; bool bilinear = q->state()->flags.bilinear;
if (b.d->transform.type() > QTransform::TxNone) { // FALCON: optimize const QTransform btransform(b.transform());
spanData->setupMatrix(b.transform() * m, bilinear); if (btransform.type() > QTransform::TxNone) { // FALCON: optimize
spanData->setupMatrix(btransform * m, bilinear);
} else if (m.type() <= QTransform::TxTranslate) { } else if (m.type() <= QTransform::TxTranslate) {
// specialize setupMatrix for translation matrices // specialize setupMatrix for translation matrices
// to avoid needless matrix inversion // to avoid needless matrix inversion

View file

@ -3468,7 +3468,7 @@ void QPainter::setBrush(const QBrush &brush)
return; return;
} }
if (d->state->brush.d == brush.d) if (d->state->brush == brush)
return; return;
if (d->extended) { if (d->extended) {