functionality of QskBoxFillNode/QskRectangleNode moved into QskBoxRectangleNode

This commit is contained in:
Uwe Rathmann 2024-09-17 13:57:10 +02:00
parent 58344c0c4e
commit 6c391b831d
13 changed files with 213 additions and 432 deletions

View File

@ -150,7 +150,7 @@ void Frame::updateFrameNode( const QRectF& rect, QskBoxRectangleNode* node )
const QskBoxBorderColors borderColors( c1, c1, c2, c2 );
const qreal radius = effectiveRadius( rect, m_radius );
node->updateNode( rect, radius, m_frameWidth, borderColors, m_color );
node->updateBox( rect, radius, m_frameWidth, borderColors, m_color );
}
#include "moc_Frame.cpp"

View File

@ -173,7 +173,7 @@ QSGNode* DiagramSkinlet::updateChartNode( const Diagram* diagram, QSGNode* node
color = diagram->color( barSubcontrol );
const auto shape = diagram->boxShapeHint( barSubcontrol );
barNode->updateNode( barRect, shape, {}, {}, color );
barNode->updateFilling( barRect, shape, color );
}
}
else

View File

@ -10,7 +10,6 @@
#endif
#include <QskPaintedNode.h>
#include <QskBoxFillNode.h>
#include <QskBoxRectangleNode.h>
#include <QskGradient.h>
#include <QskGradientDirection.h>
@ -165,15 +164,17 @@ QSGNode* GradientView::updatePaintNode(
}
case BoxFill:
{
auto node = gradientNode< QskBoxFillNode >( oldNode );
node->updateNode( rect, m_gradient );
auto node = gradientNode< QskBoxRectangleNode >( oldNode );
node->setHint( QskFillNode::PreferColoredGeometry, false );
node->updateFilling( rect, shape, m_gradient );
return node;
}
case BoxRectangle:
{
auto node = gradientNode< QskBoxRectangleNode >( oldNode );
node->updateNode( rect, shape, m_gradient );
node->setHint( QskFillNode::PreferColoredGeometry, true );
node->updateFilling( rect, shape, m_gradient );
return node;
}

View File

@ -107,7 +107,6 @@ list(APPEND HEADERS
nodes/QskBasicLinesNode.h
nodes/QskBoxNode.h
nodes/QskBoxClipNode.h
nodes/QskBoxFillNode.h
nodes/QskBoxRectangleNode.h
nodes/QskBoxRenderer.h
nodes/QskBoxMetrics.h
@ -149,7 +148,6 @@ list(APPEND SOURCES
nodes/QskBasicLinesNode.cpp
nodes/QskBoxNode.cpp
nodes/QskBoxClipNode.cpp
nodes/QskBoxFillNode.cpp
nodes/QskBoxRectangleNode.cpp
nodes/QskBoxRenderer.cpp
nodes/QskBoxMetrics.cpp
@ -164,7 +162,6 @@ list(APPEND SOURCES
nodes/QskLinesNode.cpp
nodes/QskPaintedNode.cpp
nodes/QskPlainTextRenderer.cpp
nodes/QskRectangleNode.cpp
nodes/QskRichTextRenderer.cpp
nodes/QskSceneTexture.cpp
nodes/QskSGNode.cpp

View File

@ -22,7 +22,6 @@
#include "QskGraphicNode.h"
#include "QskGraphic.h"
#include "QskLinesNode.h"
#include "QskRectangleNode.h"
#include "QskSGNode.h"
#include "QskStippleMetrics.h"
#include "QskTextColors.h"
@ -373,8 +372,9 @@ QSGNode* QskSkinlet::updateBackgroundNode(
if ( !gradient.isValid() )
return nullptr;
auto rectNode = QskSGNode::ensureNode< QskRectangleNode >( node );
rectNode->updateNode( rect, gradient );
auto rectNode = QskSGNode::ensureNode< QskBoxRectangleNode >( node );
rectNode->updateFilling( rect, QskBoxShapeMetrics(),
QskBoxBorderMetrics(), gradient );
return rectNode;
}

View File

@ -1,95 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskBoxFillNode.h"
#include "QskGradientMaterial.h"
#include "QskGradient.h"
#include "QskGradientDirection.h"
#include "QskBoxShapeMetrics.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxRenderer.h"
#include "QskFillNodePrivate.h"
static inline QskHashValue qskMetricsHash(
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics )
{
QskHashValue hash = 13000;
hash = shape.hash( hash );
return borderMetrics.hash( hash );
}
class QskBoxFillNodePrivate final : public QskFillNodePrivate
{
public:
inline void resetValues()
{
rect = QRectF();
gradientHash = 0;
metricsHash = 0;
}
QRectF rect;
QskHashValue gradientHash = 0;
QskHashValue metricsHash = 0;
};
QskBoxFillNode::QskBoxFillNode()
: QskFillNode( *new QskBoxFillNodePrivate )
{
}
void QskBoxFillNode::updateNode( const QRectF& rect, const QskGradient& gradient )
{
updateNode( rect, QskBoxShapeMetrics(), QskBoxBorderMetrics(), gradient );
}
void QskBoxFillNode::updateNode(
const QRectF& rect, const QskBoxShapeMetrics& shapeMetrics,
const QskBoxBorderMetrics& borderMetrics, const QskGradient& gradient )
{
Q_D( QskBoxFillNode );
if ( rect.isEmpty() || !gradient.isVisible() )
{
d->resetValues();
resetGeometry();
return;
}
const auto metricsHash = qskMetricsHash( shapeMetrics, borderMetrics );
const auto gradientHash = gradient.hash( 22879 );
const bool dirtyColors = gradientHash != d->gradientHash;
const bool dirtyMetrics = ( metricsHash != d->metricsHash ) || ( rect != d->rect );
d->metricsHash = metricsHash;
d->gradientHash = gradientHash;
d->rect = rect;
if ( gradient.isMonochrome() )
{
if ( dirtyColors )
setColoring( gradient.startColor().toRgb() );
}
else
{
// dirtyMetrics: the shader also depends on the target rectangle !
if ( dirtyColors || dirtyMetrics )
setColoring( rect, gradient.effectiveGradient() );
}
if ( dirtyMetrics )
{
QskBoxRenderer::renderFillGeometry(
rect, shapeMetrics, borderMetrics, *geometry() );
markDirty( QSGNode::DirtyGeometry );
geometry()->markVertexDataDirty();
}
}

View File

@ -1,35 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_BOX_FILL_NODE_H
#define QSK_BOX_FILL_NODE_H
#include "QskGlobal.h"
#include "QskFillNode.h"
class QskGradient;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxFillNodePrivate;
class QSK_EXPORT QskBoxFillNode : public QskFillNode
{
using Inherited = QskFillNode;
public:
QskBoxFillNode();
void updateNode( const QRectF&,
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskGradient& );
void updateNode( const QRectF&, const QskGradient& );
private:
Q_DECLARE_PRIVATE( QskBoxFillNode )
};
#endif

View File

@ -4,10 +4,8 @@
*****************************************************************************/
#include "QskBoxNode.h"
#include "QskBoxFillNode.h"
#include "QskBoxShadowNode.h"
#include "QskBoxRectangleNode.h"
#include "QskBoxRenderer.h"
#include "QskSGNode.h"
#include "QskGradient.h"
@ -67,7 +65,7 @@ void QskBoxNode::updateNode( const QRectF& rect,
QskBoxShadowNode* shadowNode = nullptr;
QskBoxRectangleNode* rectNode = nullptr;
QskBoxFillNode* fillNode = nullptr;
QskBoxRectangleNode* fillNode = nullptr;
if ( !shadowMetrics.isNull()
&& shadowColor.isValid() && shadowColor.alpha() != 0 )
@ -77,29 +75,23 @@ void QskBoxNode::updateNode( const QRectF& rect,
shape, shadowMetrics.blurRadius(), shadowColor );
}
/*
QskBoxRectangleNode is more efficient and creates batchable geometries.
So we prefer using it where possible.
Note, that the border is always done with a QskBoxRectangleNode
*/
if ( QskBoxRenderer::isGradientSupported( gradient ) )
if ( QskBoxRectangleNode::isCombinedGeometrySupported( gradient ) )
{
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
rectNode->updateNode( rect, shape, borderMetrics, borderColors, gradient );
rectNode->updateBox( rect, shape, borderMetrics, borderColors, gradient );
}
else
{
if ( !borderMetrics.isNull() && borderColors.isVisible() )
{
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
rectNode->updateNode( rect, shape, borderMetrics, borderColors, QskGradient() );
rectNode->updateBorder( rect, shape, borderMetrics, borderColors );
}
if ( gradient.isVisible() )
{
fillNode = qskNode< QskBoxFillNode >( this, FillRole );
fillNode->updateNode( rect, shape, borderMetrics, gradient );
fillNode = qskNode< QskBoxRectangleNode >( this, FillRole );
fillNode->updateFilling( rect, shape, borderMetrics, gradient );
}
}

View File

@ -12,46 +12,55 @@
#include "QskGradientDirection.h"
#include "QskFillNodePrivate.h"
static inline QskHashValue qskMetricsHash(
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics )
{
QskHashValue hash = 13000;
hash = shape.hash( hash );
return borderMetrics.hash( hash );
}
static inline QskHashValue qskColorsHash(
const QskBoxBorderColors& borderColors, const QskGradient& fillGradient )
{
QskHashValue hash = 13000;
hash = borderColors.hash( hash );
return fillGradient.hash( hash );
}
#if 1
static inline QskGradient qskEffectiveGradient( const QskGradient& gradient )
{
auto g = gradient.effectiveGradient();
if ( g.type() != QskGradient::Linear )
{
qWarning() << "QskBoxRectangleNode does not support radial/conic gradients";
g.setDirection( QskGradient::Linear );
}
return g;
}
#endif
class QskBoxRectangleNodePrivate final : public QskFillNodePrivate
{
public:
QskHashValue metricsHash = 0;
QskHashValue colorsHash = 0;
QRectF rect;
inline void resetNode( QskBoxRectangleNode* node )
{
m_metricsHash = m_colorsHash = 0;
node->resetGeometry();
}
bool updateMetrics( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics )
{
QskHashValue hash = 13000;
hash = qHashBits( &rect, sizeof( rect ), hash );
hash = shape.hash( hash );
hash = borderMetrics.hash( hash );
return updateValue( m_metricsHash, hash );
}
bool updateColors( const QskBoxBorderColors& borderColors, const QskGradient& gradient )
{
QskHashValue hash = 13000;
if ( borderColors.isVisible() )
hash = borderColors.hash( hash );
if ( gradient.isVisible() )
hash = gradient.hash( hash );
return updateValue( m_colorsHash, hash );
}
private:
inline bool updateValue( QskHashValue& value, const QskHashValue newValue ) const
{
if ( newValue != value )
{
value = newValue;
return true;
}
return false;
}
public:
QskHashValue m_metricsHash = 0;
QskHashValue m_colorsHash = 0;
};
QskBoxRectangleNode::QskBoxRectangleNode()
@ -63,132 +72,163 @@ QskBoxRectangleNode::~QskBoxRectangleNode()
{
}
void QskBoxRectangleNode::updateNode(
const QRectF& rect, const QskGradient& fillGradient )
void QskBoxRectangleNode::updateFilling(
const QRectF& rect, const QskGradient& gradient )
{
updateNode( rect, QskBoxShapeMetrics(), QskBoxBorderMetrics(),
QskBoxBorderColors(), fillGradient );
updateFilling( rect, QskBoxShapeMetrics(), QskBoxBorderMetrics(), gradient );
}
void QskBoxRectangleNode::updateNode( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskGradient& fillGradient )
void QskBoxRectangleNode::updateFilling( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskGradient& gradient )
{
updateNode( rect, shape, QskBoxBorderMetrics(),
QskBoxBorderColors(), fillGradient );
updateFilling( rect, shape, QskBoxBorderMetrics(), gradient );
}
void QskBoxRectangleNode::updateNode( const QRectF& rect,
void QskBoxRectangleNode::updateFilling( const QRectF& rect,
const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics,
const QskGradient& gradient )
{
Q_D( QskBoxRectangleNode );
if ( rect.isEmpty() || !gradient.isVisible() )
{
d->resetNode( this );
return;
}
const auto fillGradient = gradient.effectiveGradient();
const auto shape = shapeMetrics.toAbsolute( rect.size() );
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() );
if ( dirtyMetrics || dirtyColors )
{
if ( coloredGeometry )
{
setColoring( QskFillNode::Polychrome );
QskBoxRenderer::renderBox( rect, shape,
borderMetrics, QskBoxBorderColors(), fillGradient, *geometry() );
markDirty( QSGNode::DirtyGeometry );
}
else
{
if ( fillGradient.isMonochrome() )
{
if ( dirtyColors )
setColoring( fillGradient.rgbStart() );
}
else
{
// dirtyMetrics: the shader also depends on rect !
setColoring( rect, fillGradient );
}
if ( dirtyMetrics )
{
QskBoxRenderer::renderFillGeometry(
rect, shape, borderMetrics, *geometry() );
markDirty( QSGNode::DirtyGeometry );
}
}
}
}
void QskBoxRectangleNode::updateBorder( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics,
const QskBoxBorderColors& borderColors )
{
Q_D( QskBoxRectangleNode );
if ( rect.isEmpty() || borderMetrics.isNull() || !borderColors.isVisible() )
{
d->resetNode( this );
return;
}
const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics );
const bool dirtyColors = d->updateColors( borderColors, QskGradient() );
if ( dirtyMetrics || dirtyColors )
{
const auto coloring = QskFillNode::Polychrome;
if ( coloring == QskFillNode::Polychrome )
setColoring( coloring );
else
setColoring( borderColors.left().rgbStart() );
QskBoxRenderer::renderBox( rect, shape, borderMetrics,
borderColors, QskGradient(), *this->geometry() );
markDirty( QSGNode::DirtyGeometry );
}
}
void QskBoxRectangleNode::updateBox( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics,
const QskBoxBorderColors& borderColors, const QskGradient& gradient )
{
Q_D( QskBoxRectangleNode );
/*
We supports certain linear gradients only.
Everything else has to be done using QskRectangleNode
*/
const auto fillGradient = qskEffectiveGradient( gradient );
const auto metricsHash = qskMetricsHash( shape, borderMetrics );
const auto colorsHash = qskColorsHash( borderColors, fillGradient );
if ( ( metricsHash == d->metricsHash ) &&
( colorsHash == d->colorsHash ) && ( rect == d->rect ) )
{
return;
}
d->metricsHash = metricsHash;
d->colorsHash = colorsHash;
d->rect = rect;
markDirty( QSGNode::DirtyMaterial );
markDirty( QSGNode::DirtyGeometry );
if ( rect.isEmpty() )
{
resetGeometry();
d->resetNode( this );
return;
}
bool hasFill = fillGradient.isVisible();
bool hasBorder = !borderMetrics.isNull();
if ( hasBorder )
{
/*
Wrong as the border width should have an
effect - even if not being visible. TODO ...
*/
hasBorder = borderColors.isVisible();
}
if ( !hasBorder && !hasFill )
{
resetGeometry();
return;
}
const bool isFillMonochrome = hasFill ? fillGradient.isMonochrome() : true;
const bool isBorderMonochrome = hasBorder ? borderColors.isMonochrome() : true;
const bool hasFill = gradient.isVisible();
const bool hasBorder = !borderMetrics.isNull() && borderColors.isVisible();
if ( hasFill && hasBorder )
{
if ( isFillMonochrome && isBorderMonochrome )
const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics );
const bool dirtyColors = d->updateColors( borderColors, gradient );
if ( dirtyMetrics || dirtyColors )
{
if ( borderColors.left().rgbStart() == fillGradient.rgbStart() )
/*
For monochrome border/fiiling with the same color we might be
able to do QskFillNode::Monochrome. However this is not implemeted in
QskBoxRenderer yet. TODO ...
*/
setColoring( QskFillNode::Polychrome );
auto fillGradient = gradient.effectiveGradient();
if ( !QskBoxRenderer::isGradientSupported( fillGradient ) )
{
// we can draw border and background in one
hasBorder = false;
qWarning() << "QskBoxRenderer does not support radial/conic gradients";
fillGradient.setDirection( QskGradient::Linear );
}
QskBoxRenderer::renderBox( rect, shape, borderMetrics,
borderColors, fillGradient, *geometry() );
markDirty( QSGNode::DirtyGeometry );
}
}
auto coloring = QskFillNode::Polychrome;
#if 0
/*
Always using the same material result in a better batching
but wastes some memory. when we have a solid color.
Maybe its worth to introduce a flag to control the behaviour,
but for the moment we go with performance.
*/
if ( !( hasFill && hasBorder ) )
else if ( hasFill )
{
if ( ( hasFill && isFillMonochrome )
|| ( hasBorder && !isBorderMonochrome )
{
coloring = QskFillNode::Monochrome;
}
updateFilling( rect, shape, borderMetrics, gradient );
}
#endif
auto& geometry = *this->geometry();
if ( coloring == QskFillNode::Polychrome )
else if ( hasBorder )
{
setColoring( coloring );
QskBoxRenderer::renderBox( d->rect, shape, borderMetrics,
borderColors, fillGradient, geometry );
updateBorder( rect, shape, borderMetrics, borderColors );
}
else
{
if ( hasFill )
{
setColoring( fillGradient.rgbStart() );
QskBoxRenderer::renderFillGeometry(
d->rect, shape, QskBoxBorderMetrics(), geometry );
}
else
{
setColoring( borderColors.left().rgbStart() );
QskBoxRenderer::renderBorderGeometry(
d->rect, shape, borderMetrics, geometry );
}
d->resetNode( this );
}
geometry.markVertexDataDirty();
}
bool QskBoxRectangleNode::isCombinedGeometrySupported( const QskGradient& gradient )
{
return QskBoxRenderer::isGradientSupported( gradient );
}

View File

@ -24,15 +24,29 @@ class QSK_EXPORT QskBoxRectangleNode : public QskFillNode
QskBoxRectangleNode();
~QskBoxRectangleNode() override;
void updateNode( const QRectF&,
void updateBox( const QRectF&,
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskBoxBorderColors&, const QskGradient& );
void updateNode( const QRectF& rect, const QskGradient& );
void updateBorder( const QRectF&,
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskBoxBorderColors& );
void updateNode( const QRectF& rect,
void updateFilling( const QRectF& rect, const QskGradient& );
void updateFilling( const QRectF& rect,
const QskBoxShapeMetrics&, const QskGradient& );
void updateFilling( const QRectF& rect, const QskBoxShapeMetrics&,
const QskBoxBorderMetrics&, const QskGradient& );
/*
If true border/filling can be rendered together into the same geometry.
This should not make much difference as the scene graph batches geometries
for the same material anyway.
*/
static bool isCombinedGeometrySupported( const QskGradient& );
private:
Q_DECLARE_PRIVATE( QskBoxRectangleNode )
};

View File

@ -34,6 +34,9 @@ static inline QskVertex::ColoredLine* qskAllocateColoredLines(
static inline QskGradient qskEffectiveGradient(
const QRectF& rect, const QskGradient& gradient )
{
if ( !gradient.isVisible() )
return gradient;
const auto dir = gradient.linearDirection();
auto g = gradient;
@ -111,6 +114,7 @@ void QskBoxRenderer::renderBorderGeometry(
const QskBoxBorderMetrics& border, QSGGeometry& geometry )
{
geometry.setDrawingMode( QSGGeometry::DrawTriangleStrip );
geometry.markVertexDataDirty();
const QskBoxMetrics metrics( rect, shape, border );
const QskBoxBasicStroker stroker( metrics );
@ -131,6 +135,7 @@ void QskBoxRenderer::renderFillGeometry(
const QskBoxBorderMetrics& border, QSGGeometry& geometry )
{
geometry.setDrawingMode( QSGGeometry::DrawTriangleStrip );
geometry.markVertexDataDirty();
const QskBoxMetrics metrics( rect, shape, border );
QskBoxBasicStroker stroker( metrics );
@ -153,6 +158,7 @@ void QskBoxRenderer::renderBox( const QRectF& rect,
QSGGeometry& geometry )
{
geometry.setDrawingMode( QSGGeometry::DrawTriangleStrip );
geometry.markVertexDataDirty();
const QskBoxMetrics metrics( rect, shape, border );
const auto effectiveGradient = qskEffectiveGradient( metrics.innerRect, gradient );

View File

@ -1,105 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskRectangleNode.h"
#include "QskGradient.h"
#include "QskBoxRenderer.h"
#include "QskBoxShapeMetrics.h"
#include "QskFillNodePrivate.h"
class QskRectangleNodePrivate final : public QskFillNodePrivate
{
public:
inline void resetValues()
{
rect = QRectF();
shape = QskBoxShapeMetrics();
gradientHash = 0;
metricsHash = 0;
}
QRectF rect;
QskBoxShapeMetrics shape;
QskHashValue gradientHash = 0;
QskHashValue metricsHash = 0;
};
QskRectangleNode::QskRectangleNode()
: QskFillNode( *new QskRectangleNodePrivate )
{
}
QskRectangleNode::~QskRectangleNode()
{
}
void QskRectangleNode::updateNode(
const QRectF& rect, const QskGradient& gradient )
{
updateNode( rect, QskBoxShapeMetrics(), gradient );
}
void QskRectangleNode::updateNode(
const QRectF& rect, const QskBoxShapeMetrics& shape, const QskGradient& gradient )
{
Q_D( QskRectangleNode );
if ( rect.isEmpty() || !gradient.isVisible() )
{
d->resetValues();
resetGeometry();
return;
}
const auto effectiveGradient = gradient.effectiveGradient();
const auto effectiveShape = shape.toAbsolute( rect.size() );
const auto gradientHash = effectiveGradient.hash( 54228 );
const auto metricsHash = effectiveShape.hash( 44564 );
const bool dirtyColors = gradientHash != d->gradientHash;
const bool dirtyMetrics = ( rect != d->rect ) || ( metricsHash != d->metricsHash );
if ( !( dirtyColors || dirtyMetrics ) )
return;
d->gradientHash = gradientHash;
d->metricsHash = metricsHash;
d->rect = rect;
d->shape = effectiveShape;
if ( QskBoxRenderer::isGradientSupported( effectiveGradient ) )
{
setColoring( Polychrome );
/*
Colors are added to the vertices, while the material does
not depend on the gradient at all
*/
if ( dirtyMetrics || dirtyColors )
{
QskBoxRenderer::renderBox( rect,
effectiveShape, effectiveGradient, *geometry() );
geometry()->markVertexDataDirty();
markDirty( QSGNode::DirtyGeometry );
}
}
else
{
if ( dirtyColors || dirtyMetrics )
setColoring( rect, effectiveGradient );
if ( dirtyMetrics )
{
QskBoxRenderer::renderFillGeometry( rect, effectiveShape, *geometry() );
geometry()->markVertexDataDirty();
markDirty( QSGNode::DirtyGeometry );
}
}
}

View File

@ -1,34 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_RECTANGLE_NODE_H
#define QSK_RECTANGLE_NODE_H
#include "QskGlobal.h"
#include "QskFillNode.h"
class QskGradient;
class QskBoxShapeMetrics;
class QskRectangleNodePrivate;
/*
QskRectangleNode is for rounded rectangles without a border.
*/
class QSK_EXPORT QskRectangleNode : public QskFillNode
{
using Inherited = QskFillNode;
public:
QskRectangleNode();
~QskRectangleNode() override;
void updateNode( const QRectF&, const QskGradient& );
void updateNode( const QRectF&, const QskBoxShapeMetrics&, const QskGradient& );
private:
Q_DECLARE_PRIVATE( QskRectangleNode )
};
#endif