qskinny/src/nodes/QskShapeNode.cpp

120 lines
3.3 KiB
C++
Raw Normal View History

/******************************************************************************
2024-01-17 13:31:45 +00:00
* QSkinny - Copyright (C) The authors
2023-04-06 07:23:37 +00:00
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskShapeNode.h"
2022-10-31 13:42:08 +00:00
#include "QskGradient.h"
#include "QskGradientDirection.h"
2023-11-15 10:47:56 +00:00
#include "QskFillNodePrivate.h"
QSK_QT_PRIVATE_BEGIN
#include <private/qvectorpath_p.h>
#include <private/qtriangulator_p.h>
QSK_QT_PRIVATE_END
2024-09-25 05:51:02 +00:00
#if 0
// keeping the index list
2022-09-29 14:50:46 +00:00
static void qskUpdateGeometry( const QPainterPath& path,
const QTransform& transform, QSGGeometry& geometry )
{
2022-09-29 14:50:46 +00:00
const auto ts = qTriangulate( path, transform, 1, false );
geometry.allocate( ts.vertices.size(), ts.indices.size() );
2022-09-26 15:50:07 +00:00
auto vertexData = reinterpret_cast< float* >( geometry.vertexData() );
const auto points = ts.vertices.constData();
for ( int i = 0; i < ts.vertices.count(); i++ )
vertexData[i] = points[i];
memcpy( geometry.indexData(), ts.indices.data(),
ts.indices.size() * sizeof( quint16 ) );
2024-09-25 05:51:02 +00:00
}
#endif
static void qskUpdateGeometry( const QPainterPath& path,
const QTransform& transform, QSGGeometry& geometry )
{
const auto ts = qTriangulate( path, transform, 1, false );
/*
2024-09-25 05:51:02 +00:00
The triangulation of a random path does not lead to index lists
that are substantially reducing the number of vertices.
As we have to iterate over the vertex buffer to copy qreal to float
2024-09-25 05:51:02 +00:00
anyway we reorder according to the index buffer and drop
the index buffer.
QTriangleSet:
vertices: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
QVector<quint16> indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
*/
2024-09-25 05:51:02 +00:00
const auto points = ts.vertices.constData();
const auto indices = reinterpret_cast< const quint16* >( ts.indices.data() );
geometry.allocate( ts.indices.size() );
auto vertexData = geometry.vertexDataAsPoint2D();
for ( int i = 0; i < ts.indices.size(); i++ )
{
const int j = 2 * indices[i];
vertexData[i].set( points[j], points[j + 1] );
}
}
2023-11-15 10:47:56 +00:00
class QskShapeNodePrivate final : public QskFillNodePrivate
{
public:
/*
Is there a better way to find out if the path has changed
beside storing a copy ( even, when internally with Copy On Write ) ?
*/
QPainterPath path;
QTransform transform;
};
QskShapeNode::QskShapeNode()
2023-11-15 10:47:56 +00:00
: QskFillNode( *new QskShapeNodePrivate )
{
2023-11-15 10:47:56 +00:00
setColoring( Monochrome );
geometry()->setDrawingMode( QSGGeometry::DrawTriangles );
}
2023-04-12 10:17:38 +00:00
QskShapeNode::~QskShapeNode()
{
}
2022-09-29 14:50:46 +00:00
void QskShapeNode::updateNode( const QPainterPath& path,
2022-10-31 13:42:08 +00:00
const QTransform& transform, const QRectF& rect, const QskGradient& gradient )
{
Q_D( QskShapeNode );
2022-10-31 13:42:08 +00:00
if ( path.isEmpty() || !gradient.isVisible() )
2022-09-29 10:40:22 +00:00
{
d->path = QPainterPath();
2022-12-05 12:05:13 +00:00
d->transform = QTransform();
2023-11-15 10:47:56 +00:00
resetGeometry();
2022-09-29 10:40:22 +00:00
return;
}
2023-11-15 10:47:56 +00:00
setColoring( rect, gradient );
if ( ( transform != d->transform ) || ( path != d->path ) )
{
d->path = path;
d->transform = transform;
2023-11-15 10:47:56 +00:00
qskUpdateGeometry( path, transform, *geometry() );
2023-11-15 10:47:56 +00:00
geometry()->markVertexDataDirty();
markDirty( QSGNode::DirtyGeometry );
}
}