From f4275c5098cfb448eb8ae579312465e3a01c163b Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sun, 4 Dec 2022 21:13:14 +0100 Subject: [PATCH] using the more efficient QVector< qreal > instead of QPainterPath --- src/nodes/QskBoxFillNode.cpp | 7 +++-- src/nodes/QskBoxRenderer.h | 11 +++---- src/nodes/QskBoxRendererEllipse.cpp | 49 +++++++++++------------------ src/nodes/QskBoxRendererRect.cpp | 13 +++++--- 4 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/nodes/QskBoxFillNode.cpp b/src/nodes/QskBoxFillNode.cpp index 058388aa..ec90f6d1 100644 --- a/src/nodes/QskBoxFillNode.cpp +++ b/src/nodes/QskBoxFillNode.cpp @@ -12,7 +12,6 @@ #include "QskBoxRenderer.h" #include -#include QSK_QT_PRIVATE_BEGIN #include @@ -44,9 +43,11 @@ static inline QskGradient qskEffectiveGradient( const QskGradient& gradient ) return gradient; } -static void qskUpdateGeometry( const QPainterPath& path, QSGGeometry& geometry ) +static void qskUpdateGeometry( const QVector< qreal > path, QSGGeometry& geometry ) { - const auto ts = qTriangulate( path, QTransform(), 1, false ); + const auto hints = QVectorPath::PolygonHint | QVectorPath::OddEvenFill; + const auto ts = qTriangulate( + path.constData(), path.size() / 2, hints, QTransform(), false ); /* As we have to iterate over the vertex buffer to copy qreal to float diff --git a/src/nodes/QskBoxRenderer.h b/src/nodes/QskBoxRenderer.h index 964f6876..ec40d964 100644 --- a/src/nodes/QskBoxRenderer.h +++ b/src/nodes/QskBoxRenderer.h @@ -9,14 +9,13 @@ #include "QskBoxShapeMetrics.h" #include -#include +#include class QskBoxBorderMetrics; class QskBoxBorderColors; class QskGradient; class QSGGeometry; -class QPainterPath; namespace QskVertex { @@ -36,7 +35,7 @@ class QSK_EXPORT QskBoxRenderer const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxBorderColors&, const QskGradient&, QSGGeometry& ); - QPainterPath fillPath( const QRectF&, + QVector< qreal > fillPath( const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics& ) const; class Quad @@ -136,9 +135,9 @@ class QSK_EXPORT QskBoxRenderer void renderRectFill( const Quad&, const QskGradient&, QskVertex::ColoredLine* ); - QPainterPath fillPathRect( const QRectF&, const QskBoxBorderMetrics& ) const; + QVector< qreal > fillPathRect( const QRectF&, const QskBoxBorderMetrics& ) const; - QPainterPath fillPathRectellipse( const QRectF&, + QVector< qreal > fillPathRectellipse( const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics& ) const; }; @@ -173,7 +172,7 @@ inline void QskBoxRenderer::renderBox( const QRectF& rect, renderRectellipse( rect, shape, border, borderColors, gradient, geometry ); } -inline QPainterPath QskBoxRenderer::fillPath( const QRectF& rect, +inline QVector< qreal > QskBoxRenderer::fillPath( const QRectF& rect, const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border ) const { if ( shape.isRectangle() ) diff --git a/src/nodes/QskBoxRendererEllipse.cpp b/src/nodes/QskBoxRendererEllipse.cpp index b19b86e1..71222c3a 100644 --- a/src/nodes/QskBoxRendererEllipse.cpp +++ b/src/nodes/QskBoxRendererEllipse.cpp @@ -1510,35 +1510,32 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect, } } -QPainterPath QskBoxRenderer::fillPathRectellipse( const QRectF& rect, +QVector< qreal > QskBoxRenderer::fillPathRectellipse( const QRectF& rect, const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border ) const { - QPainterPath path; - const Metrics metrics( rect, shape, border ); BorderValues v( metrics ); + const auto totalSteps = metrics.corner[0].stepCount + + metrics.corner[1].stepCount + + metrics.corner[2].stepCount + + metrics.corner[3].stepCount; + + QVector< qreal > path; + path.resize( 2 * ( totalSteps + 4 ) ); + + auto p = path.data(); + { constexpr auto id = TopLeft; const auto& c = metrics.corner[ id ]; - { - v.setAngle( 0.0, 1.0 ); - - const auto x = c.centerX - v.dx1( id ); - const auto y = c.centerY - v.dy1( id ); - - path.moveTo( x, y ); - } - for ( ArcIterator it( c.stepCount, false ); !it.isDone(); ++it ) { v.setAngle( it.cos(), it.sin() ); - const auto x = c.centerX - v.dx1( id ); - const auto y = c.centerY - v.dy1( id ); - - path.lineTo( x, y ); + *p++ = c.centerX - v.dx1( id ); + *p++ =c.centerY - v.dy1( id ); } } { @@ -1549,10 +1546,8 @@ QPainterPath QskBoxRenderer::fillPathRectellipse( const QRectF& rect, { v.setAngle( it.cos(), it.sin() ); - const auto x = c.centerX - v.dx1( id ); - const auto y = c.centerY + v.dy1( id ); - - path.lineTo( x, y ); + *p++ = c.centerX - v.dx1( id ); + *p++ = c.centerY + v.dy1( id ); } } { @@ -1563,10 +1558,8 @@ QPainterPath QskBoxRenderer::fillPathRectellipse( const QRectF& rect, { v.setAngle( it.cos(), it.sin() ); - const auto x = c.centerX + v.dx1( id ); - const auto y = c.centerY + v.dy1( id ); - - path.lineTo( x, y ); + *p++ = c.centerX + v.dx1( id ); + *p++ = c.centerY + v.dy1( id ); } } { @@ -1577,14 +1570,10 @@ QPainterPath QskBoxRenderer::fillPathRectellipse( const QRectF& rect, { v.setAngle( it.cos(), it.sin() ); - const auto x = c.centerX + v.dx1( id ); - const auto y = c.centerY - v.dy1( id ); - - path.lineTo( x, y ); + *p++ = c.centerX + v.dx1( id ); + *p++ = c.centerY - v.dy1( id ); } } - path.closeSubpath(); - return path; } diff --git a/src/nodes/QskBoxRendererRect.cpp b/src/nodes/QskBoxRendererRect.cpp index ba7b46e5..d7c02794 100644 --- a/src/nodes/QskBoxRendererRect.cpp +++ b/src/nodes/QskBoxRendererRect.cpp @@ -665,14 +665,17 @@ void QskBoxRenderer::renderRectFill( const QskBoxRenderer::Quad& rect, qskCreateFillOrdered( rect, gradient, line ); } -QPainterPath QskBoxRenderer::fillPathRect( const QRectF& rect, +QVector< qreal > QskBoxRenderer::fillPathRect( const QRectF& rect, const QskBoxBorderMetrics& border ) const { const auto r = border.adjustedRect( rect ); + if ( r.isEmpty() ) + return QVector< qreal >(); - QPainterPath path; - if ( !r.isEmpty() ) - path.addRect( r ); + const qreal x1 = r.left(); + const qreal x2 = r.right(); + const qreal y1 = r.top(); + const qreal y2 = r.bottom(); - return path; + return { x1, y1, x2, y1, x2, y2, x1, y2, x1, y1 }; }