From 7eecc6357173d92451c027366b85fc472aeb1d41 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sun, 4 Dec 2022 19:52:07 +0100 Subject: [PATCH] QPainterPath support added --- src/nodes/QskBoxRenderer.h | 19 +++++++ src/nodes/QskBoxRendererEllipse.cpp | 79 +++++++++++++++++++++++++++++ src/nodes/QskBoxRendererRect.cpp | 12 +++++ 3 files changed, 110 insertions(+) diff --git a/src/nodes/QskBoxRenderer.h b/src/nodes/QskBoxRenderer.h index b597fbde..964f6876 100644 --- a/src/nodes/QskBoxRenderer.h +++ b/src/nodes/QskBoxRenderer.h @@ -9,12 +9,14 @@ #include "QskBoxShapeMetrics.h" #include +#include class QskBoxBorderMetrics; class QskBoxBorderColors; class QskGradient; class QSGGeometry; +class QPainterPath; namespace QskVertex { @@ -34,6 +36,9 @@ class QSK_EXPORT QskBoxRenderer const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxBorderColors&, const QskGradient&, QSGGeometry& ); + QPainterPath fillPath( const QRectF&, + const QskBoxShapeMetrics&, const QskBoxBorderMetrics& ) const; + class Quad { public: @@ -130,6 +135,11 @@ class QSK_EXPORT QskBoxRenderer int lineCount, QskVertex::ColoredLine* ); void renderRectFill( const Quad&, const QskGradient&, QskVertex::ColoredLine* ); + + QPainterPath fillPathRect( const QRectF&, const QskBoxBorderMetrics& ) const; + + QPainterPath fillPathRectellipse( const QRectF&, + const QskBoxShapeMetrics&, const QskBoxBorderMetrics& ) const; }; inline void QskBoxRenderer::renderBorder( @@ -163,4 +173,13 @@ inline void QskBoxRenderer::renderBox( const QRectF& rect, renderRectellipse( rect, shape, border, borderColors, gradient, geometry ); } +inline QPainterPath QskBoxRenderer::fillPath( const QRectF& rect, + const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border ) const +{ + if ( shape.isRectangle() ) + return fillPathRect( rect, border ); + else + return fillPathRectellipse( rect, shape, border ); +} + #endif diff --git a/src/nodes/QskBoxRendererEllipse.cpp b/src/nodes/QskBoxRendererEllipse.cpp index aadef4a4..b19b86e1 100644 --- a/src/nodes/QskBoxRendererEllipse.cpp +++ b/src/nodes/QskBoxRendererEllipse.cpp @@ -1509,3 +1509,82 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect, qskRenderBorder( metrics, Qt::Vertical, borderColors, line ); } } + +QPainterPath QskBoxRenderer::fillPathRectellipse( const QRectF& rect, + const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border ) const +{ + QPainterPath path; + + const Metrics metrics( rect, shape, border ); + BorderValues v( metrics ); + + { + 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 ); + } + } + { + constexpr auto id = BottomLeft; + const auto& c = metrics.corner[ id ]; + + for ( ArcIterator it( c.stepCount, true ); !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 ); + } + } + { + constexpr auto id = BottomRight; + const auto& c = metrics.corner[ id ]; + + 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 ); + } + } + { + constexpr auto id = TopRight; + const auto& c = metrics.corner[ id ]; + + for ( ArcIterator it( c.stepCount, true ); !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 ); + } + } + + path.closeSubpath(); + + return path; +} diff --git a/src/nodes/QskBoxRendererRect.cpp b/src/nodes/QskBoxRendererRect.cpp index d43238c7..ba7b46e5 100644 --- a/src/nodes/QskBoxRendererRect.cpp +++ b/src/nodes/QskBoxRendererRect.cpp @@ -664,3 +664,15 @@ void QskBoxRenderer::renderRectFill( const QskBoxRenderer::Quad& rect, { qskCreateFillOrdered( rect, gradient, line ); } + +QPainterPath QskBoxRenderer::fillPathRect( const QRectF& rect, + const QskBoxBorderMetrics& border ) const +{ + const auto r = border.adjustedRect( rect ); + + QPainterPath path; + if ( !r.isEmpty() ) + path.addRect( r ); + + return path; +}