diff --git a/src/nodes/QskBoxNode.cpp b/src/nodes/QskBoxNode.cpp index 5ed2a0cd..a4ea7f74 100644 --- a/src/nodes/QskBoxNode.cpp +++ b/src/nodes/QskBoxNode.cpp @@ -67,31 +67,34 @@ void QskBoxNode::updateNode( const QRectF& rect, QskBoxRectangleNode* rectNode = nullptr; QskBoxRectangleNode* fillNode = nullptr; - if ( !shadowMetrics.isNull() - && shadowColor.isValid() && shadowColor.alpha() != 0 ) + if ( !rect.isEmpty() ) { - shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole ); - shadowNode->setShadowData( shadowMetrics.shadowRect( rect ), - shape, shadowMetrics.blurRadius(), shadowColor ); - } - - if ( QskBoxRectangleNode::isCombinedGeometrySupported( gradient ) ) - { - rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole ); - rectNode->updateBox( rect, shape, borderMetrics, borderColors, gradient ); - } - else - { - if ( !borderMetrics.isNull() && borderColors.isVisible() ) + if ( !shadowMetrics.isNull() + && shadowColor.isValid() && shadowColor.alpha() != 0 ) { - rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole ); - rectNode->updateBorder( rect, shape, borderMetrics, borderColors ); + shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole ); + shadowNode->setShadowData( shadowMetrics.shadowRect( rect ), + shape, shadowMetrics.blurRadius(), shadowColor ); } - if ( gradient.isVisible() ) + if ( QskBoxRectangleNode::isCombinedGeometrySupported( gradient ) ) { - fillNode = qskNode< QskBoxRectangleNode >( this, FillRole ); - fillNode->updateFilling( rect, shape, borderMetrics, gradient ); + rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole ); + rectNode->updateBox( rect, shape, borderMetrics, borderColors, gradient ); + } + else + { + if ( !borderMetrics.isNull() && borderColors.isVisible() ) + { + rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole ); + rectNode->updateBorder( rect, shape, borderMetrics, borderColors ); + } + + if ( gradient.isVisible() ) + { + fillNode = qskNode< QskBoxRectangleNode >( this, FillRole ); + fillNode->updateFilling( rect, shape, borderMetrics, gradient ); + } } } diff --git a/src/nodes/QskBoxRectangleNode.cpp b/src/nodes/QskBoxRectangleNode.cpp index ec8b2a7e..b7e519f9 100644 --- a/src/nodes/QskBoxRectangleNode.cpp +++ b/src/nodes/QskBoxRectangleNode.cpp @@ -12,6 +12,12 @@ #include "QskGradientDirection.h" #include "QskFillNodePrivate.h" +static inline bool qskHasBorder( + const QskBoxBorderMetrics& metrics, const QskBoxBorderColors& colors ) +{ + return !metrics.isNull() && colors.isVisible(); +} + class QskBoxRectangleNodePrivate final : public QskFillNodePrivate { public: @@ -21,7 +27,7 @@ class QskBoxRectangleNodePrivate final : public QskFillNodePrivate node->resetGeometry(); } - bool updateMetrics( const QRectF& rect, + inline bool updateMetrics( const QRectF& rect, const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics ) { QskHashValue hash = 13000; @@ -30,10 +36,11 @@ class QskBoxRectangleNodePrivate final : public QskFillNodePrivate hash = shape.hash( hash ); hash = borderMetrics.hash( hash ); - return updateValue( m_metricsHash, hash ); + return updateHash( m_metricsHash, hash ); } - bool updateColors( const QskBoxBorderColors& borderColors, const QskGradient& gradient ) + inline bool updateColors( + const QskBoxBorderColors& borderColors, const QskGradient& gradient ) { QskHashValue hash = 13000; @@ -43,11 +50,11 @@ class QskBoxRectangleNodePrivate final : public QskFillNodePrivate if ( gradient.isVisible() ) hash = gradient.hash( hash ); - return updateValue( m_colorsHash, hash ); + return updateHash( m_colorsHash, hash ); } private: - inline bool updateValue( QskHashValue& value, const QskHashValue newValue ) const + inline bool updateHash( QskHashValue& value, const QskHashValue newValue ) const { if ( newValue != value ) { @@ -102,11 +109,13 @@ void QskBoxRectangleNode::updateFilling( const QRectF& rect, const bool coloredGeometry = hasHint( PreferColoredGeometry ) && QskBoxRenderer::isGradientSupported( fillGradient ); - const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics ); - const bool dirtyColors = d->updateColors( QskBoxBorderColors(), fillGradient ) - && ( coloredGeometry == isGeometryColored() ); + bool dirtyGeometry = d->updateMetrics( rect, shape, borderMetrics ); + bool dirtyMaterial = d->updateColors( QskBoxBorderColors(), fillGradient ); - if ( dirtyMetrics || dirtyColors ) + if ( coloredGeometry != isGeometryColored() ) + dirtyGeometry = dirtyMaterial = true; + + if ( dirtyGeometry || dirtyMaterial ) { if ( coloredGeometry ) { @@ -121,16 +130,15 @@ void QskBoxRectangleNode::updateFilling( const QRectF& rect, { if ( fillGradient.isMonochrome() ) { - if ( dirtyColors ) + if ( dirtyMaterial ) setColoring( fillGradient.rgbStart() ); } else { - // dirtyMetrics: the shader also depends on rect ! setColoring( rect, fillGradient ); } - if ( dirtyMetrics ) + if ( dirtyGeometry ) { QskBoxRenderer::setFillLines( rect, shape, borderMetrics, *geometry() ); @@ -147,28 +155,44 @@ void QskBoxRectangleNode::updateBorder( const QRectF& rect, { Q_D( QskBoxRectangleNode ); - if ( rect.isEmpty() || borderMetrics.isNull() || !borderColors.isVisible() ) + if ( rect.isEmpty() || !qskHasBorder( borderMetrics, borderColors ) ) { d->resetNode( this ); return; } - const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics ); - const bool dirtyColors = d->updateColors( borderColors, QskGradient() ); + const bool coloredGeometry = hasHint( PreferColoredGeometry ) + || !borderColors.isMonochrome(); - if ( dirtyMetrics || dirtyColors ) + bool dirtyGeometry = d->updateMetrics( rect, shape, borderMetrics ); + bool dirtyMaterial = d->updateColors( borderColors, QskGradient() ); + + if ( coloredGeometry != isGeometryColored() ) + dirtyGeometry = dirtyMaterial = true; + + if ( dirtyGeometry || dirtyMaterial ) { - const auto coloring = QskFillNode::Polychrome; + if ( coloredGeometry ) + { + setColoring( QskFillNode::Polychrome ); - if ( coloring == QskFillNode::Polychrome ) - setColoring( coloring ); + QskBoxRenderer::setColoredBorderLines( rect, shape, + borderMetrics, borderColors, *geometry() ); + + markDirty( QSGNode::DirtyGeometry ); + } else + { setColoring( borderColors.left().rgbStart() ); - QskBoxRenderer::setColoredBorderLines( rect, shape, borderMetrics, - borderColors, *this->geometry() ); + if ( dirtyGeometry ) + { + QskBoxRenderer::setBorderLines( rect, shape, + borderMetrics, *geometry() ); - markDirty( QSGNode::DirtyGeometry ); + markDirty( QSGNode::DirtyGeometry ); + } + } } } @@ -185,14 +209,14 @@ void QskBoxRectangleNode::updateBox( const QRectF& rect, } const bool hasFill = gradient.isVisible(); - const bool hasBorder = !borderMetrics.isNull() && borderColors.isVisible(); + const bool hasBorder = qskHasBorder( borderMetrics, borderColors ); if ( hasFill && hasBorder ) { - const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics ); - const bool dirtyColors = d->updateColors( borderColors, gradient ); + const bool isDirty = d->updateMetrics( rect, shape, borderMetrics ) + || d->updateColors( borderColors, gradient ) || !isGeometryColored(); - if ( dirtyMetrics || dirtyColors ) + if ( isDirty ) { /* For monochrome border/fiiling with the same color we might be