From bb3178f4de60ec5b38f3ba556bd18b12813f743d Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sun, 28 Nov 2021 23:02:04 +0200 Subject: [PATCH] make private QBrush data actually private [ci reset] Signed-off-by: Ivailo Monev --- src/gui/painting/qbrush.cpp | 210 +++++++++-------------- src/gui/painting/qbrush.h | 48 ++---- src/gui/painting/qpaintengine_raster.cpp | 8 +- src/gui/painting/qpainter.cpp | 2 +- 4 files changed, 95 insertions(+), 173 deletions(-) diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 9d2ad4c08..10285a7ba 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -66,6 +66,18 @@ Q_GUI_EXPORT QImage qt_diagCrossBrush() 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 { QTexturedBrushData() { @@ -121,7 +133,7 @@ bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush) { if (brush.style() != Qt::TexturePattern) return false; - QTexturedBrushData *tx_data = static_cast(brush.d.data()); + QTexturedBrushData *tx_data = static_cast(brush.d); return tx_data->m_has_pixmap_texture; } @@ -130,27 +142,6 @@ struct QGradientBrushData : public QBrushData QGradient gradient; }; -struct QBrushDataPointerDeleter -{ - static inline void cleanup(QBrushData *d) - { - if (d && !d->ref.deref()) { - switch (d->style) { - case Qt::TexturePattern: - delete static_cast(d); - break; - case Qt::LinearGradientPattern: - case Qt::RadialGradientPattern: - case Qt::ConicalGradientPattern: - delete static_cast(d); - break; - default: - delete d; - } - } - } -}; - /*! \class QBrush \ingroup painting @@ -231,33 +222,6 @@ struct QBrushDataPointerDeleter \sa Qt::BrushStyle, QPainter, QColor */ -// Special deleter that only deletes if the ref-count goes to zero -template <> -class QGlobalStaticDeleter -{ -public: - QGlobalStatic &globalStatic; - QGlobalStaticDeleter(QGlobalStatic &_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) { switch (style) { case Qt::TexturePattern: @@ -281,25 +245,26 @@ static bool qbrush_check_type(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) { case Qt::NoBrush: - d.reset(nullBrushInstance()); - d->ref.ref(); + d = new QBrushData(); if (d->color != color) setColor(color); return; case Qt::TexturePattern: - d.reset(new QTexturedBrushData); + d = new QTexturedBrushData(); break; case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: - d.reset(new QGradientBrushData); + d = new QGradientBrushData(); break; default: - d.reset(new QBrushData); + d = new QBrushData(); break; } - d->ref = 1; d->style = style; d->color = color; } @@ -310,10 +275,8 @@ void QBrush::init(const QColor &color, Qt::BrushStyle style) */ 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)) init(Qt::black, style); else { - d.reset(nullBrushInstance()); - d->ref.ref(); + d = new QBrushData(); } } @@ -370,14 +332,11 @@ QBrush::QBrush(const QColor &color, Qt::BrushStyle style) if (qbrush_check_type(style)) init(color, style); else { - d.reset(nullBrushInstance()); - d->ref.ref(); + d = new QBrushData(); } } /*! - \fn QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style) - Constructs a brush with the given \a color and \a style. \sa setColor(), setStyle() @@ -387,8 +346,7 @@ QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style) if (qbrush_check_type(style)) init(color, style); else { - d.reset(nullBrushInstance()); - d->ref.ref(); + d = new QBrushData(); } } @@ -429,7 +387,7 @@ QBrush::QBrush(Qt::GlobalColor color, const QPixmap &pixmap) */ QBrush::QBrush(const QBrush &other) - : d(other.d.data()) + : d(other.d) { d->ref.ref(); } @@ -454,7 +412,7 @@ QBrush::QBrush(const QGradient &gradient) }; init(QColor(), enumTbl[gradient.type()]); - QGradientBrushData *grad = static_cast(d.data()); + QGradientBrushData *grad = static_cast(d); grad->gradient = gradient; } @@ -464,6 +422,20 @@ QBrush::QBrush(const QGradient &gradient) QBrush::~QBrush() { + if (d && !d->ref.deref()) { + switch (d->style) { + case Qt::TexturePattern: + delete static_cast(d); + break; + case Qt::LinearGradientPattern: + case Qt::RadialGradientPattern: + case Qt::ConicalGradientPattern: + delete static_cast(d); + break; + default: + delete d; + } + } } void QBrush::detach(Qt::BrushStyle newStyle) @@ -476,7 +448,7 @@ void QBrush::detach(Qt::BrushStyle newStyle) case Qt::TexturePattern: { QTexturedBrushData *tbd = new QTexturedBrushData; if (d->style == Qt::TexturePattern) { - QTexturedBrushData *data = static_cast(d.data()); + QTexturedBrushData *data = static_cast(d); if (data->m_has_pixmap_texture) tbd->setPixmap(data->pixmap()); else @@ -490,34 +462,30 @@ void QBrush::detach(Qt::BrushStyle newStyle) case Qt::ConicalGradientPattern: x.reset(new QGradientBrushData); static_cast(x.data())->gradient = - static_cast(d.data())->gradient; + static_cast(d)->gradient; break; default: - x.reset(new QBrushData); + x.reset(new QBrushData()); break; } - x->ref = 1; x->style = newStyle; x->color = d->color; 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 brush to \e this brush and returns a + Assigns the given \a other to \e this brush and returns a reference to \e this brush. */ -QBrush &QBrush::operator=(const QBrush &b) +QBrush &QBrush::operator=(const QBrush &other) { - if (d == b.d) - return *this; - - b.d->ref.ref(); - d.reset(b.d.data()); + qAtomicAssign(d, other.d); return *this; } @@ -539,12 +507,14 @@ QBrush::operator QVariant() const } /*! - \fn Qt::BrushStyle QBrush::style() const - Returns the brush style. \sa setStyle() */ +Qt::BrushStyle QBrush::style() const +{ + return d->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. \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. 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. */ - - /*! - \fn QPixmap QBrush::texture() const - Returns the custom brush pattern, or a null pixmap if no custom brush pattern has been set. @@ -610,7 +576,7 @@ void QBrush::setColor(const QColor &c) QPixmap QBrush::texture() const { return d->style == Qt::TexturePattern - ? (static_cast(d.data()))->pixmap() + ? (static_cast(d))->pixmap() : QPixmap(); } @@ -628,7 +594,7 @@ void QBrush::setTexture(const QPixmap &pixmap) { if (!pixmap.isNull()) { detach(Qt::TexturePattern); - QTexturedBrushData *data = static_cast(d.data()); + QTexturedBrushData *data = static_cast(d); data->setPixmap(pixmap); } else { detach(Qt::NoBrush); @@ -651,7 +617,7 @@ void QBrush::setTexture(const QPixmap &pixmap) QImage QBrush::textureImage() const { return d->style == Qt::TexturePattern - ? (static_cast(d.data()))->image() + ? (static_cast(d))->image() : QImage(); } @@ -676,7 +642,7 @@ void QBrush::setTextureImage(const QImage &image) { if (!image.isNull()) { detach(Qt::TexturePattern); - QTexturedBrushData *data = static_cast(d.data()); + QTexturedBrushData *data = static_cast(d); data->setImage(image); } else { detach(Qt::NoBrush); @@ -692,7 +658,7 @@ const QGradient *QBrush::gradient() const if (d->style == Qt::LinearGradientPattern || d->style == Qt::RadialGradientPattern || d->style == Qt::ConicalGradientPattern) { - return &static_cast(d.data())->gradient; + return &static_cast(d)->gradient; } return 0; } @@ -774,13 +740,16 @@ void QBrush::setTransform(const QTransform &matrix) /*! - \fn void QBrush::matrix() const \since 4.2 Returns the current transformation matrix for the brush. \sa setMatrix() */ +const QMatrix &QBrush::matrix() const +{ + return d->transform.toAffine(); +} /*! \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 brush; + Returns true if the brush is equal to the given \a other; otherwise returns false. Two brushes are equal if they have equal styles, colors and @@ -806,25 +773,25 @@ void QBrush::setTransform(const QTransform &matrix) \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; - 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; switch (d->style) { case Qt::TexturePattern: { - const QPixmap &us = (static_cast(d.data()))->pixmap(); - const QPixmap &them = (static_cast(b.d.data()))->pixmap(); + const QPixmap &us = (static_cast(d))->pixmap(); + const QPixmap &them = (static_cast(other.d))->pixmap(); return ((us.isNull() && them.isNull()) || us.cacheKey() == them.cacheKey()); } case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: { - const QGradientBrushData *d1 = static_cast(d.data()); - const QGradientBrushData *d2 = static_cast(b.d.data()); + const QGradientBrushData *d1 = static_cast(d); + const QGradientBrushData *d2 = static_cast(other.d); return d1->gradient == d2->gradient; } 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 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 stopPoints. The positions of the points must be in the range 0 to 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 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 Returns the current transformation matrix for the brush. \sa setTransform() */ +QTransform QBrush::transform() const +{ + return d->transform; +} QT_END_NAMESPACE diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h index e8b46a895..06db0d039 100644 --- a/src/gui/painting/qbrush.h +++ b/src/gui/painting/qbrush.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -38,15 +37,7 @@ QT_BEGIN_NAMESPACE class QPixmap; class QGradient; class QVariant; -struct QBrushDataPointerDeleter; - -struct QBrushData -{ - QAtomicInt ref; - Qt::BrushStyle style; - QColor color; - QTransform transform; -}; +class QBrushData; class Q_GUI_EXPORT QBrush { @@ -66,7 +57,7 @@ public: QBrush(const QGradient &gradient); ~QBrush(); - QBrush &operator=(const QBrush &brush); + QBrush &operator=(const QBrush &other); #ifdef Q_COMPILER_RVALUE_REFS inline QBrush &operator=(QBrush &&other) { qSwap(d, other.d); return *this; } @@ -75,13 +66,13 @@ public: operator QVariant() const; - inline Qt::BrushStyle style() const; + Qt::BrushStyle style() const; void setStyle(Qt::BrushStyle); - inline const QMatrix &matrix() const; + const QMatrix &matrix() const; void setMatrix(const QMatrix &mat); - inline QTransform transform() const; + QTransform transform() const; void setTransform(const QTransform &); QPixmap texture() const; @@ -90,7 +81,7 @@ public: QImage textureImage() const; void setTextureImage(const QImage &image); - inline const QColor &color() const; + const QColor &color() const; void setColor(const QColor &color); inline void setColor(Qt::GlobalColor color); @@ -98,34 +89,23 @@ public: bool isOpaque() const; - bool operator==(const QBrush &b) const; - inline bool operator!=(const QBrush &b) const { return !(operator==(b)); } + bool operator==(const QBrush &other) const; + inline bool operator!=(const QBrush &other) const { return !(operator==(other)); } 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); + void detach(Qt::BrushStyle newStyle); void init(const QColor &color, Qt::BrushStyle bs); - QScopedPointer d; -public: - inline bool isDetached() const; - typedef QScopedPointer DataPtr; - inline DataPtr &data_ptr() { return d; } + QBrushData *d; }; inline void QBrush::setColor(Qt::GlobalColor acolor) { setColor(QColor(acolor)); } Q_DECLARE_TYPEINFO(QBrush, Q_MOVABLE_TYPE); -Q_DECLARE_SHARED(QBrush) /***************************************************************************** QBrush stream functions @@ -140,14 +120,6 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QBrush &); Q_GUI_EXPORT QDebug operator<<(QDebug, const QBrush &); #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 */ diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 50da0bf29..bc0a7d583 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -707,14 +707,16 @@ void QRasterPaintEnginePrivate::systemStateChanged() 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; Q_Q(QRasterPaintEngine); bool bilinear = q->state()->flags.bilinear; - if (b.d->transform.type() > QTransform::TxNone) { // FALCON: optimize - spanData->setupMatrix(b.transform() * m, bilinear); + const QTransform btransform(b.transform()); + if (btransform.type() > QTransform::TxNone) { // FALCON: optimize + spanData->setupMatrix(btransform * m, bilinear); } else if (m.type() <= QTransform::TxTranslate) { // specialize setupMatrix for translation matrices // to avoid needless matrix inversion diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 5c9b9835e..6782b53f8 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -3468,7 +3468,7 @@ void QPainter::setBrush(const QBrush &brush) return; } - if (d->state->brush.d == brush.d) + if (d->state->brush == brush) return; if (d->extended) {