2022-09-26 12:44:23 +00:00
|
|
|
/******************************************************************************
|
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
|
2022-09-26 12:44:23 +00:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskShapeNode.h"
|
2022-10-31 13:42:08 +00:00
|
|
|
#include "QskGradient.h"
|
2022-11-13 16:22:09 +00:00
|
|
|
#include "QskGradientDirection.h"
|
2023-11-15 10:47:56 +00:00
|
|
|
#include "QskFillNodePrivate.h"
|
2022-09-26 12:44:23 +00:00
|
|
|
|
|
|
|
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-26 12:44:23 +00:00
|
|
|
{
|
2022-09-29 14:50:46 +00:00
|
|
|
const auto ts = qTriangulate( path, transform, 1, false );
|
2022-09-26 12:44:23 +00:00
|
|
|
|
|
|
|
geometry.allocate( ts.vertices.size(), ts.indices.size() );
|
|
|
|
|
2022-09-26 15:50:07 +00:00
|
|
|
auto vertexData = reinterpret_cast< float* >( geometry.vertexData() );
|
2022-09-26 12:44:23 +00:00
|
|
|
const auto points = ts.vertices.constData();
|
|
|
|
|
2022-09-28 18:14:10 +00:00
|
|
|
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 );
|
|
|
|
|
2022-09-26 12:44:23 +00:00
|
|
|
/*
|
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.
|
|
|
|
|
2022-09-26 12:44:23 +00:00
|
|
|
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.
|
2022-09-28 18:14:10 +00:00
|
|
|
|
|
|
|
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], ...]
|
2022-09-26 12:44:23 +00:00
|
|
|
*/
|
2024-09-25 05:51:02 +00:00
|
|
|
|
2022-09-28 18:14:10 +00:00
|
|
|
const auto points = ts.vertices.constData();
|
|
|
|
const auto indices = reinterpret_cast< const quint16* >( ts.indices.data() );
|
2022-09-26 12:44:23 +00:00
|
|
|
|
2022-09-28 18:14:10 +00:00
|
|
|
geometry.allocate( ts.indices.size() );
|
2022-09-26 12:44:23 +00:00
|
|
|
|
2022-09-28 18:14:10 +00:00
|
|
|
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] );
|
|
|
|
}
|
2022-09-26 12:44:23 +00:00
|
|
|
}
|
|
|
|
|
2023-11-15 10:47:56 +00:00
|
|
|
class QskShapeNodePrivate final : public QskFillNodePrivate
|
2022-09-26 12:44:23 +00:00
|
|
|
{
|
|
|
|
public:
|
2022-09-30 13:23:55 +00:00
|
|
|
/*
|
|
|
|
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;
|
2022-09-26 12:44:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
QskShapeNode::QskShapeNode()
|
2023-11-15 10:47:56 +00:00
|
|
|
: QskFillNode( *new QskShapeNodePrivate )
|
2022-09-26 12:44:23 +00:00
|
|
|
{
|
2023-11-15 10:47:56 +00:00
|
|
|
setColoring( Monochrome );
|
|
|
|
geometry()->setDrawingMode( QSGGeometry::DrawTriangles );
|
2022-09-26 12:44:23 +00:00
|
|
|
}
|
|
|
|
|
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 )
|
2022-09-28 18:14:10 +00:00
|
|
|
{
|
2022-09-30 13:23:55 +00:00
|
|
|
Q_D( QskShapeNode );
|
|
|
|
|
2022-10-31 13:42:08 +00:00
|
|
|
if ( path.isEmpty() || !gradient.isVisible() )
|
2022-09-29 10:40:22 +00:00
|
|
|
{
|
2022-09-30 13:23:55 +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-30 13:23:55 +00:00
|
|
|
|
2022-09-29 10:40:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-15 10:47:56 +00:00
|
|
|
setColoring( rect, gradient );
|
|
|
|
|
2022-09-30 13:23:55 +00:00
|
|
|
if ( ( transform != d->transform ) || ( path != d->path ) )
|
2022-09-28 18:14:10 +00:00
|
|
|
{
|
2022-09-30 13:23:55 +00:00
|
|
|
d->path = path;
|
|
|
|
d->transform = transform;
|
|
|
|
|
2023-11-15 10:47:56 +00:00
|
|
|
qskUpdateGeometry( path, transform, *geometry() );
|
2022-09-28 18:14:10 +00:00
|
|
|
|
2023-11-15 10:47:56 +00:00
|
|
|
geometry()->markVertexDataDirty();
|
|
|
|
markDirty( QSGNode::DirtyGeometry );
|
2022-09-28 18:14:10 +00:00
|
|
|
}
|
|
|
|
}
|