QskBoxRectangleNode supports rounded rectangles now.

This commit is contained in:
Uwe Rathmann 2022-12-06 12:12:54 +01:00
parent 9ae7dc2f63
commit 778ed1de9e
5 changed files with 59 additions and 34 deletions

View File

@ -40,7 +40,6 @@ static inline QskHashValue qskColorsHash(
#if 1
static inline QskGradient qskEffectiveGradient( const QskGradient& gradient )
{
QskGradient g;
@ -139,16 +138,10 @@ void QskBoxRectangleNode::updateNode( const QRectF& rect,
Q_D( QskBoxRectangleNode );
/*
QskBoxRenderer supports certain linear gradients only.
For everything else we would have to use a QskGradientMaterial instead.
As a temporary solution we simply "convert" gradient into a
simple QskLinearGradient so that at least something is happening.
TODO ...
We supports certain linear gradients only.
Everything else has to be done using QskRectangleNode
*/
#if 1
const auto fillGradient = qskEffectiveGradient( gradient );
#endif
const auto metricsHash = qskMetricsHash( shape, borderMetrics );
const auto colorsHash = qskColorsHash( borderColors, fillGradient );

View File

@ -33,9 +33,6 @@ class QSK_EXPORT QskBoxRenderer
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskBoxBorderColors&, const QskGradient&, QSGGeometry& );
static void renderRect( const QRectF&, const QskGradient&, QSGGeometry& );
static void renderRect( const QRectF&, QSGGeometry& );
static bool isGradientSupported( const QskGradient& );
class Quad

View File

@ -552,18 +552,6 @@ void QskBoxRenderer::renderRectFill( const QRectF& rect,
p[3].set( quad.right, quad.bottom );
}
void QskBoxRenderer::renderRect( const QRectF& rect,
const QskGradient& gradient, QSGGeometry& geometry )
{
renderRect( rect, QskBoxBorderMetrics(),
QskBoxBorderColors(), gradient, geometry );
}
void QskBoxRenderer::renderRect( const QRectF& rect, QSGGeometry& geometry )
{
renderRectFill( rect, QskBoxBorderMetrics(), geometry );
}
void QskBoxRenderer::renderRect( const QRectF& rect,
const QskBoxBorderMetrics& border, const QskBoxBorderColors& borderColors,
const QskGradient& gradient, QSGGeometry& geometry )

View File

@ -9,6 +9,10 @@
#include "QskBoxRenderer.h"
#include "QskGradientMaterial.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h"
#include "QskBoxShapeMetrics.h"
#include <qglobalstatic.h>
#include <qsgvertexcolormaterial.h>
@ -33,6 +37,21 @@ static inline QskGradient qskEffectiveGradient( const QskGradient& gradient )
return gradient;
}
static inline void qskUpdateColoredPoint2D( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskGradient& gradient,
QSGGeometry& geometry )
{
QskBoxRenderer::renderBox( rect, shape,
QskBoxBorderMetrics(), QskBoxBorderColors(), gradient, geometry );
}
static inline void qskUpdatePoint2D( const QRectF& rect,
const QskBoxShapeMetrics& shape, QSGGeometry& geometry )
{
QskBoxRenderer::renderFill( rect, shape,
QskBoxBorderMetrics(), geometry );
}
class QskRectangleNodePrivate final : public QSGGeometryNodePrivate
{
public:
@ -41,10 +60,21 @@ class QskRectangleNodePrivate final : public QSGGeometryNodePrivate
{
}
inline void resetValues()
{
rect = QRectF();
shape = QskBoxShapeMetrics();
gradientHash = 0;
metricsHash = 0;
}
QSGGeometry geometry;
QRectF rect;
QskBoxShapeMetrics shape;
QskHashValue gradientHash = 0;
QskHashValue metricsHash = 0;
int gradientType = -1;
};
@ -64,30 +94,39 @@ 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->rect = QRectF();
d->gradientHash = 0;
d->resetValues();
QskSGNode::resetGeometry( this );
return;
}
const auto effectiveGradient = qskEffectiveGradient( gradient );
const auto effectiveShape = shape.toAbsolute( rect.size() );
const auto gradientHash = effectiveGradient.hash( 54228 );
const auto metricsHash = effectiveShape.hash( 44564 );
const bool dirtyGradient = gradientHash != d->gradientHash;
const bool dirtyRect = rect != d->rect;
const bool dirtyColors = gradientHash != d->gradientHash;
const bool dirtyMetrics = ( rect != d->rect ) || ( metricsHash != d->metricsHash );
if ( !( dirtyGradient || dirtyRect ) )
if ( !( dirtyColors || dirtyMetrics ) )
return;
d->gradientHash = gradientHash;
d->metricsHash = metricsHash;
d->rect = rect;
d->shape = effectiveShape;
if ( QskBoxRenderer::isGradientSupported( effectiveGradient ) )
{
@ -128,9 +167,10 @@ void QskRectangleNode::updateNode(
Colors are added to the vertices, while the material does
not depend on the gradient at all
*/
if ( dirtyRect || dirtyGradient )
if ( dirtyMetrics || dirtyColors )
{
QskBoxRenderer::renderRect( rect, effectiveGradient, d->geometry );
qskUpdateColoredPoint2D( rect, effectiveShape,
effectiveGradient, d->geometry );
markDirty( QSGNode::DirtyGeometry );
}
}
@ -142,13 +182,13 @@ void QskRectangleNode::updateNode(
Monochrome gradients or QskGradient::Stops are supported by the
QskBoxRenderer. So we don't need to handle them here.
*/
if ( dirtyRect )
if ( dirtyMetrics )
{
QskBoxRenderer::renderRect( rect, d->geometry );
qskUpdatePoint2D( rect, effectiveShape, d->geometry );
markDirty( QSGNode::DirtyGeometry );
}
if ( dirtyGradient )
if ( dirtyColors )
{
const auto gradientType = effectiveGradient.type();

View File

@ -10,8 +10,14 @@
#include <qsgnode.h>
class QskGradient;
class QskBoxShapeMetrics;
class QskRectangleNodePrivate;
/*
QskRectangleNode is for rounded rectangles without a border.
Depending on the type of gradient it uses a different
material/geometry combination.
*/
class QSK_EXPORT QskRectangleNode : public QSGGeometryNode
{
public:
@ -19,6 +25,7 @@ class QSK_EXPORT QskRectangleNode : public QSGGeometryNode
~QskRectangleNode() override;
void updateNode( const QRectF&, const QskGradient& );
void updateNode( const QRectF&, const QskBoxShapeMetrics&, const QskGradient& );
private:
Q_DECLARE_PRIVATE( QskRectangleNode )