diff --git a/examples/frames/Frame.cpp b/examples/frames/Frame.cpp index 4c89f3d33..88c11bb71 100644 --- a/examples/frames/Frame.cpp +++ b/examples/frames/Frame.cpp @@ -150,7 +150,7 @@ void Frame::updateFrameNode( const QRectF& rect, QskBoxRectangleNode* node ) const QskBoxBorderColors borderColors( c1, c1, c2, c2 ); const qreal radius = effectiveRadius( rect, m_radius ); - node->updateBox( rect, radius, m_frameWidth, borderColors, m_color ); + node->updateBox( window(), rect, radius, m_frameWidth, borderColors, m_color ); } #include "moc_Frame.cpp" diff --git a/examples/iotdashboard/DiagramSkinlet.cpp b/examples/iotdashboard/DiagramSkinlet.cpp index 5e2ab79fb..4287bcf11 100644 --- a/examples/iotdashboard/DiagramSkinlet.cpp +++ b/examples/iotdashboard/DiagramSkinlet.cpp @@ -173,7 +173,7 @@ QSGNode* DiagramSkinlet::updateChartNode( const Diagram* diagram, QSGNode* node color = diagram->color( barSubcontrol ); const auto shape = diagram->boxShapeHint( barSubcontrol ); - barNode->updateFilling( barRect, shape, color ); + barNode->updateFilling( diagram->window(), barRect, shape, color ); } } else diff --git a/playground/gradients/GradientView.cpp b/playground/gradients/GradientView.cpp index 78d90fedb..2804cbbee 100644 --- a/playground/gradients/GradientView.cpp +++ b/playground/gradients/GradientView.cpp @@ -166,7 +166,7 @@ QSGNode* GradientView::updatePaintNode( { auto node = gradientNode< QskBoxRectangleNode >( oldNode ); node->setHint( QskFillNode::PreferColoredGeometry, false ); - node->updateFilling( rect, shape, m_gradient ); + node->updateFilling( window(), rect, shape, m_gradient ); return node; } @@ -174,7 +174,7 @@ QSGNode* GradientView::updatePaintNode( { auto node = gradientNode< QskBoxRectangleNode >( oldNode ); node->setHint( QskFillNode::PreferColoredGeometry, true ); - node->updateFilling( rect, shape, m_gradient ); + node->updateFilling( window(), rect, shape, m_gradient ); return node; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 151ed18fd..0c8fa8250 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -111,7 +111,6 @@ list(APPEND HEADERS nodes/QskBoxMetrics.h nodes/QskBoxBasicStroker.h nodes/QskBoxGradientStroker.h - nodes/QskBoxColorMap.h nodes/QskBoxShadowNode.h nodes/QskColorRamp.h nodes/QskFillNode.h @@ -133,6 +132,7 @@ list(APPEND HEADERS nodes/QskTextRenderer.h nodes/QskTextureRenderer.h nodes/QskVertex.h + nodes/QskVertexHelper.h ) list(APPEND PRIVATE_HEADERS diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index 7befc8377..33a9661f8 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -196,26 +196,37 @@ static inline QskTextColors qskTextColors( return c; } +static inline QQuickWindow* qskWindowOfSkinnable( const QskSkinnable* skinnable ) +{ + if ( auto item = skinnable->owningItem() ) + return item->window(); + + return nullptr; +} + static inline QSGNode* qskUpdateBoxNode( - const QskSkinnable*, QSGNode* node, const QRectF& rect, + const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect, const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors, const QskGradient& gradient, const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) { - if ( rect.isEmpty() ) - return nullptr; - - if ( !qskIsBoxVisible( borderMetrics, borderColors, gradient ) - && !qskIsShadowVisible( shadowMetrics, shadowColor ) ) + if ( !rect.isEmpty() ) { - return nullptr; - } + if ( qskIsBoxVisible( borderMetrics, borderColors, gradient ) + || qskIsShadowVisible( shadowMetrics, shadowColor ) ) + { + if ( auto window = qskWindowOfSkinnable( skinnable ) ) + { + auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node ); + boxNode->updateNode( window, rect, shape, borderMetrics, + borderColors, gradient, shadowMetrics, shadowColor ); - auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node ); - boxNode->updateNode( rect, shape, borderMetrics, - borderColors, gradient, shadowMetrics, shadowColor ); + return boxNode; + } + } + } - return boxNode; + return nullptr; } static inline QSGNode* qskUpdateArcNode( @@ -373,7 +384,7 @@ QSGNode* QskSkinlet::updateBackgroundNode( return nullptr; auto rectNode = QskSGNode::ensureNode< QskBoxRectangleNode >( node ); - rectNode->updateFilling( rect, gradient ); + rectNode->updateFilling( control->window(), rect, gradient ); return rectNode; } @@ -648,7 +659,8 @@ QSGNode* QskSkinlet::updateBoxClipNode( const QskSkinnable* skinnable, auto shape = skinnable->boxShapeHint( subControl ); shape = shape.toAbsolute( clipRect.size() ); - clipNode->setBox( clipRect, shape, borderMetrics ); + const auto window = qskWindowOfSkinnable( skinnable ); + clipNode->setBox( window, clipRect, shape, borderMetrics ); } return clipNode; diff --git a/src/nodes/QskArcRenderer.cpp b/src/nodes/QskArcRenderer.cpp index 02e843f9c..72f644401 100644 --- a/src/nodes/QskArcRenderer.cpp +++ b/src/nodes/QskArcRenderer.cpp @@ -7,7 +7,7 @@ #include "QskArcMetrics.h" #include "QskGradient.h" #include "QskVertex.h" -#include "QskBoxColorMap.h" +#include "QskVertexHelper.h" #include "QskRgbValue.h" #include @@ -359,7 +359,7 @@ namespace void Renderer::renderLines( const LineStroker& lineStroker, Line* fillLines, Line* borderLines ) const { - QskBoxRenderer::GradientIterator it; + QskVertex::GradientIterator it; if ( fillLines ) { diff --git a/src/nodes/QskBoxBasicStroker.cpp b/src/nodes/QskBoxBasicStroker.cpp index b893428ae..0221e3b9f 100644 --- a/src/nodes/QskBoxBasicStroker.cpp +++ b/src/nodes/QskBoxBasicStroker.cpp @@ -4,7 +4,6 @@ *****************************************************************************/ #include "QskBoxBasicStroker.h" -#include "QskBoxColorMap.h" namespace { @@ -144,7 +143,7 @@ namespace { public: inline FillMap( const QskBoxMetrics& metrics, - const QskBoxRenderer::ColorMap& colorMap ) + const QskVertex::ColorMap& colorMap ) : m_colorMap( colorMap ) , m_corners( metrics.corners ) { @@ -184,7 +183,7 @@ namespace m_colorMap.setLine( x1, y1, x2, y2, line ); } - const QskBoxRenderer::ColorMap& m_colorMap; + const QskVertex::ColorMap& m_colorMap; const QskBoxMetrics::Corner* m_corners; }; } @@ -379,12 +378,12 @@ QskBoxBasicStroker::QskBoxBasicStroker( const QskBoxMetrics& metrics ) QskBoxBasicStroker::QskBoxBasicStroker( const QskBoxMetrics& metrics, const QskBoxBorderColors& borderColors ) - : QskBoxBasicStroker( metrics, borderColors, QskBoxRenderer::ColorMap() ) + : QskBoxBasicStroker( metrics, borderColors, QskVertex::ColorMap() ) { } QskBoxBasicStroker::QskBoxBasicStroker( const QskBoxMetrics& metrics, - const QskBoxBorderColors& borderColors, const QskBoxRenderer::ColorMap& colorMap ) + const QskBoxBorderColors& borderColors, const QskVertex::ColorMap& colorMap ) : m_metrics( metrics ) , m_borderColors( borderColors ) , m_colorMap( colorMap ) diff --git a/src/nodes/QskBoxBasicStroker.h b/src/nodes/QskBoxBasicStroker.h index b43e9fbcd..f65713dd6 100644 --- a/src/nodes/QskBoxBasicStroker.h +++ b/src/nodes/QskBoxBasicStroker.h @@ -8,7 +8,7 @@ #include "QskBoxMetrics.h" #include "QskBoxBorderColors.h" -#include "QskBoxColorMap.h" +#include "QskVertexHelper.h" class QskBoxShapeMetrics; class QskBoxBorderMetrics; @@ -25,7 +25,7 @@ class QskBoxBasicStroker QskBoxBasicStroker( const QskBoxMetrics& ); QskBoxBasicStroker( const QskBoxMetrics&, const QskBoxBorderColors& ); QskBoxBasicStroker( const QskBoxMetrics&, - const QskBoxBorderColors&, const QskBoxRenderer::ColorMap& ); + const QskBoxBorderColors&, const QskVertex::ColorMap& ); int fillCount() const; int borderCount() const; @@ -78,7 +78,7 @@ class QskBoxBasicStroker const QskBoxMetrics& m_metrics; const QskBoxBorderColors m_borderColors; - const QskBoxRenderer::ColorMap m_colorMap; + const QskVertex::ColorMap m_colorMap; const GeometryLayout m_geometryLayout; const bool m_isColored; diff --git a/src/nodes/QskBoxClipNode.cpp b/src/nodes/QskBoxClipNode.cpp index c04d79e27..1006cb813 100644 --- a/src/nodes/QskBoxClipNode.cpp +++ b/src/nodes/QskBoxClipNode.cpp @@ -9,6 +9,8 @@ #include "QskBoxShapeMetrics.h" #include "QskFunctions.h" +#include + static inline QskHashValue qskMetricsHash( const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border ) { @@ -29,7 +31,7 @@ QskBoxClipNode::~QskBoxClipNode() { } -void QskBoxClipNode::setBox( const QRectF& rect, +void QskBoxClipNode::setBox( const QQuickWindow* window, const QRectF& rect, const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border ) { const auto hash = qskMetricsHash( shape, border ); @@ -67,7 +69,9 @@ void QskBoxClipNode::setBox( const QRectF& rect, else { setIsRectangular( false ); - QskBoxRenderer::setFillLines( rect, shape, border, m_geometry ); + + QskBoxRenderer renderer( window ); + renderer.setFillLines( rect, shape, border, m_geometry ); } /* diff --git a/src/nodes/QskBoxClipNode.h b/src/nodes/QskBoxClipNode.h index 9312334dd..1a6377922 100644 --- a/src/nodes/QskBoxClipNode.h +++ b/src/nodes/QskBoxClipNode.h @@ -12,13 +12,15 @@ class QskBoxShapeMetrics; class QskBoxBorderMetrics; +class QQuickWindow; + class QSK_EXPORT QskBoxClipNode : public QSGClipNode { public: QskBoxClipNode(); ~QskBoxClipNode() override; - void setBox( const QRectF&, + void setBox( const QQuickWindow*, const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics& ); private: diff --git a/src/nodes/QskBoxGradientStroker.cpp b/src/nodes/QskBoxGradientStroker.cpp index ad2537ca3..97c444d91 100644 --- a/src/nodes/QskBoxGradientStroker.cpp +++ b/src/nodes/QskBoxGradientStroker.cpp @@ -5,8 +5,7 @@ #include "QskBoxGradientStroker.h" #include "QskBoxBasicStroker.h" -#include "QskVertex.h" -#include "QskBoxColorMap.h" +#include "QskVertexHelper.h" #include "QskBoxMetrics.h" static inline bool qskCanUseHVFiller( @@ -172,7 +171,7 @@ namespace qreal m_t0, m_dt; const QskBoxMetrics::Corner* m_c1, * m_c2, * m_c3; - QskBoxRenderer::GradientIterator m_gradientIterator; + QskVertex::GradientIterator m_gradientIterator; }; } @@ -528,7 +527,7 @@ namespace int setLines( const QskGradient& gradient, ColoredLine* lines ) { ContourIterator it( m_metrics, gradient.linearDirection() ); - QskBoxRenderer::GradientIterator gradientIt( gradient.stops() ); + QskVertex::GradientIterator gradientIt( gradient.stops() ); ColoredLine* l = lines; @@ -584,7 +583,7 @@ namespace const qreal y1 = m_metrics.innerRect.top(); const qreal y2 = m_metrics.innerRect.bottom(); - QskBoxRenderer::GradientIterator it( gradient.stops() ); + QskVertex::GradientIterator it( gradient.stops() ); ColoredLine* l = lines; const auto dir = gradient.linearDirection(); diff --git a/src/nodes/QskBoxMetrics.cpp b/src/nodes/QskBoxMetrics.cpp index a0cf0cff0..4972ad3d6 100644 --- a/src/nodes/QskBoxMetrics.cpp +++ b/src/nodes/QskBoxMetrics.cpp @@ -6,7 +6,7 @@ #include "QskBoxMetrics.h" #include "QskBoxShapeMetrics.h" #include "QskBoxBorderMetrics.h" -#include "QskVertex.h" +#include "QskVertexHelper.h" #include "QskFunctions.h" QskBoxMetrics::QskBoxMetrics( const QRectF& rect, diff --git a/src/nodes/QskBoxNode.cpp b/src/nodes/QskBoxNode.cpp index 22cc78c59..89af944d0 100644 --- a/src/nodes/QskBoxNode.cpp +++ b/src/nodes/QskBoxNode.cpp @@ -60,7 +60,7 @@ QskBoxNode::~QskBoxNode() { } -void QskBoxNode::updateNode( const QRectF& rect, +void QskBoxNode::updateNode( const QQuickWindow* window, const QRectF& rect, const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors, const QskGradient& gradient, const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) @@ -100,7 +100,8 @@ void QskBoxNode::updateNode( const QRectF& rect, { // QskBoxRectangleNode allows scene graph batching shadowFillNode = qskNode< QskBoxRectangleNode >( this, ShadowFillRole ); - shadowFillNode->updateFilling( shadowRect, shadowShape, shadowColor ); + shadowFillNode->updateFilling( window, + shadowRect, shadowShape, shadowColor ); } else { @@ -125,13 +126,16 @@ void QskBoxNode::updateNode( const QRectF& rect, if ( fillNode ) { - rectNode->updateBorder( rect, shapeMetrics, borderMetrics, borderColors ); - fillNode->updateFilling( rect, shapeMetrics, borderMetrics, gradient ); + rectNode->updateBorder( window, rect, + shapeMetrics, borderMetrics, borderColors ); + + fillNode->updateFilling( window, rect, + shapeMetrics, borderMetrics, gradient ); } else { - rectNode->updateBox( rect, shapeMetrics, - borderMetrics, borderColors, gradient ); + rectNode->updateBox( window, rect, + shapeMetrics, borderMetrics, borderColors, gradient ); } } } diff --git a/src/nodes/QskBoxNode.h b/src/nodes/QskBoxNode.h index 999fa58c5..8e14d668a 100644 --- a/src/nodes/QskBoxNode.h +++ b/src/nodes/QskBoxNode.h @@ -15,6 +15,7 @@ class QskBoxBorderMetrics; class QskBoxBorderColors; class QskGradient; class QskShadowMetrics; +class QQuickWindow; class QColor; class QSK_EXPORT QskBoxNode : public QSGNode @@ -23,7 +24,7 @@ class QSK_EXPORT QskBoxNode : public QSGNode QskBoxNode(); ~QskBoxNode() override; - void updateNode( const QRectF&, + void updateNode( const QQuickWindow*, const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxBorderColors&, const QskGradient&, const QskShadowMetrics&, const QColor& shadowColor ); diff --git a/src/nodes/QskBoxRectangleNode.cpp b/src/nodes/QskBoxRectangleNode.cpp index 62fcb8c58..ce715e1d4 100644 --- a/src/nodes/QskBoxRectangleNode.cpp +++ b/src/nodes/QskBoxRectangleNode.cpp @@ -79,21 +79,22 @@ QskBoxRectangleNode::~QskBoxRectangleNode() { } -void QskBoxRectangleNode::updateFilling( +void QskBoxRectangleNode::updateFilling( const QQuickWindow* window, const QRectF& rect, const QskGradient& gradient ) { - updateFilling( rect, QskBoxShapeMetrics(), QskBoxBorderMetrics(), gradient ); + updateFilling( window, rect, + QskBoxShapeMetrics(), QskBoxBorderMetrics(), gradient ); } -void QskBoxRectangleNode::updateFilling( const QRectF& rect, - const QskBoxShapeMetrics& shape, const QskGradient& gradient ) +void QskBoxRectangleNode::updateFilling( const QQuickWindow* window, + const QRectF& rect, const QskBoxShapeMetrics& shape, const QskGradient& gradient ) { - updateFilling( rect, shape, QskBoxBorderMetrics(), gradient ); + updateFilling( window, rect, shape, QskBoxBorderMetrics(), gradient ); } -void QskBoxRectangleNode::updateFilling( const QRectF& rect, - const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, - const QskGradient& gradient ) +void QskBoxRectangleNode::updateFilling( const QQuickWindow* window, + const QRectF& rect, const QskBoxShapeMetrics& shapeMetrics, + const QskBoxBorderMetrics& borderMetrics, const QskGradient& gradient ) { Q_D( QskBoxRectangleNode ); @@ -117,11 +118,13 @@ void QskBoxRectangleNode::updateFilling( const QRectF& rect, if ( dirtyGeometry || dirtyMaterial ) { + QskBoxRenderer renderer( window ); + if ( coloredGeometry ) { setColoring( QskFillNode::Polychrome ); - QskBoxRenderer::setColoredFillLines( rect, shape, + renderer.setColoredFillLines( rect, shape, borderMetrics, fillGradient, *geometry() ); markDirty( QSGNode::DirtyGeometry ); @@ -132,18 +135,16 @@ void QskBoxRectangleNode::updateFilling( const QRectF& rect, if ( dirtyGeometry ) { - QskBoxRenderer::setFillLines( - rect, shape, borderMetrics, *geometry() ); - + renderer.setFillLines( rect, shape, borderMetrics, *geometry() ); markDirty( QSGNode::DirtyGeometry ); } } } } -void QskBoxRectangleNode::updateBorder( const QRectF& rect, - const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, - const QskBoxBorderColors& borderColors ) +void QskBoxRectangleNode::updateBorder( const QQuickWindow* window, + const QRectF& rect, const QskBoxShapeMetrics& shapeMetrics, + const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors ) { Q_D( QskBoxRectangleNode ); @@ -166,11 +167,13 @@ void QskBoxRectangleNode::updateBorder( const QRectF& rect, if ( dirtyGeometry || dirtyMaterial ) { + QskBoxRenderer renderer( window ); + if ( coloredGeometry ) { setColoring( QskFillNode::Polychrome ); - QskBoxRenderer::setColoredBorderLines( rect, shape, + renderer.setColoredBorderLines( rect, shape, borderMetrics, borderColors, *geometry() ); markDirty( QSGNode::DirtyGeometry ); @@ -181,7 +184,7 @@ void QskBoxRectangleNode::updateBorder( const QRectF& rect, if ( dirtyGeometry ) { - QskBoxRenderer::setBorderLines( rect, shape, + renderer.setBorderLines( rect, shape, borderMetrics, *geometry() ); markDirty( QSGNode::DirtyGeometry ); @@ -190,7 +193,7 @@ void QskBoxRectangleNode::updateBorder( const QRectF& rect, } } -void QskBoxRectangleNode::updateBox( const QRectF& rect, +void QskBoxRectangleNode::updateBox( const QQuickWindow* window, const QRectF& rect, const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors, const QskGradient& gradient ) { @@ -228,7 +231,8 @@ void QskBoxRectangleNode::updateBox( const QRectF& rect, fillGradient.setDirection( QskGradient::Linear ); } - QskBoxRenderer::setColoredBorderAndFillLines( rect, shape, borderMetrics, + QskBoxRenderer renderer( window ); + renderer.setColoredBorderAndFillLines( rect, shape, borderMetrics, borderColors, fillGradient, *geometry() ); markDirty( QSGNode::DirtyGeometry ); @@ -236,11 +240,11 @@ void QskBoxRectangleNode::updateBox( const QRectF& rect, } else if ( hasFill ) { - updateFilling( rect, shapeMetrics, borderMetrics, gradient ); + updateFilling( window, rect, shapeMetrics, borderMetrics, gradient ); } else if ( hasBorder ) { - updateBorder( rect, shapeMetrics, borderMetrics, borderColors ); + updateBorder( window, rect, shapeMetrics, borderMetrics, borderColors ); } else { diff --git a/src/nodes/QskBoxRectangleNode.h b/src/nodes/QskBoxRectangleNode.h index 362f1afe8..1446bc3e6 100644 --- a/src/nodes/QskBoxRectangleNode.h +++ b/src/nodes/QskBoxRectangleNode.h @@ -13,9 +13,10 @@ class QskBoxShapeMetrics; class QskBoxBorderMetrics; class QskBoxBorderColors; class QskGradient; - class QskBoxRectangleNodePrivate; +class QQuickWindow; + class QSK_EXPORT QskBoxRectangleNode : public QskFillNode { using Inherited = QskFillNode; @@ -24,21 +25,21 @@ class QSK_EXPORT QskBoxRectangleNode : public QskFillNode QskBoxRectangleNode(); ~QskBoxRectangleNode() override; - void updateBox( const QRectF&, + void updateBox( const QQuickWindow*, const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxBorderColors&, const QskGradient& ); - void updateBorder( const QRectF&, + void updateBorder( const QQuickWindow*, const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxBorderColors& ); - void updateFilling( const QRectF& rect, const QskGradient& ); + void updateFilling( const QQuickWindow*, const QRectF&, const QskGradient& ); - void updateFilling( const QRectF& rect, + void updateFilling( const QQuickWindow*, const QRectF&, const QskBoxShapeMetrics&, const QskGradient& ); - void updateFilling( const QRectF& rect, const QskBoxShapeMetrics&, - const QskBoxBorderMetrics&, const QskGradient& ); + void updateFilling( const QQuickWindow*, const QRectF&, + const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskGradient& ); /* If true border/filling can be rendered together into the same geometry. diff --git a/src/nodes/QskBoxRenderer.cpp b/src/nodes/QskBoxRenderer.cpp index dd4afcdd1..f5f039fbd 100644 --- a/src/nodes/QskBoxRenderer.cpp +++ b/src/nodes/QskBoxRenderer.cpp @@ -70,6 +70,15 @@ static inline bool qskMaybeSpreading( const QskGradient& gradient ) return true; } +QskBoxRenderer::QskBoxRenderer( const QQuickWindow* window ) + : m_window( window ) +{ +} + +QskBoxRenderer::~QskBoxRenderer() +{ +} + bool QskBoxRenderer::isGradientSupported( const QskGradient& gradient ) { if ( !gradient.isVisible() || gradient.isMonochrome() ) @@ -177,7 +186,7 @@ void QskBoxRenderer::setColoredBorderAndFillLines( const QRectF& rect, const auto effectiveGradient = qskEffectiveGradient( metrics.innerRect, gradient ); if ( metrics.innerRect.isEmpty() || - QskBoxRenderer::ColorMap::isGradientSupported( effectiveGradient, metrics.innerRect ) ) + QskVertex::ColorMap::isGradientSupported( effectiveGradient, metrics.innerRect ) ) { /* The gradient can be translated to a QskBoxRenderer::ColorMap and we can do all @@ -236,14 +245,14 @@ void QskBoxRenderer::setColoredBorderAndFillLines( const QRectF& rect, QskGradient QskBoxRenderer::effectiveGradient( const QskGradient& gradient ) { if ( ( gradient.type() == QskGradient::Stops ) || gradient.isMonochrome() ) - { + { // the shader for linear gradients is the fastest - + auto g = gradient; g.setDirection( QskGradient::Linear ); - + return g; } - + return gradient; } diff --git a/src/nodes/QskBoxRenderer.h b/src/nodes/QskBoxRenderer.h index 9b30eb884..1352ff7c8 100644 --- a/src/nodes/QskBoxRenderer.h +++ b/src/nodes/QskBoxRenderer.h @@ -13,11 +13,16 @@ class QskBoxBorderColors; class QskBoxShapeMetrics; class QskGradient; +class QQuickWindow; class QSGGeometry; class QRectF; -namespace QskBoxRenderer +class QSK_EXPORT QskBoxRenderer { + public: + QskBoxRenderer( const QQuickWindow* ); + ~QskBoxRenderer(); + /* Filling the geometry without any color information: see QSGGeometry::defaultAttributes_Point2D() @@ -26,13 +31,13 @@ namespace QskBoxRenderer - using shaders setting the color information */ - QSK_EXPORT void setBorderLines( const QRectF&, + void setBorderLines( const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, QSGGeometry& ); - QSK_EXPORT void setFillLines( const QRectF&, + void setFillLines( const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, QSGGeometry& ); - QSK_EXPORT void setFillLines( const QRectF&, + void setFillLines( const QRectF&, const QskBoxShapeMetrics&, QSGGeometry& ); /* @@ -41,21 +46,25 @@ namespace QskBoxRenderer Usually used in combination with QSGVertexColorMaterial */ - QSK_EXPORT bool isGradientSupported( const QskGradient& ); - QSK_EXPORT void setColoredBorderLines( const QRectF&, + void setColoredBorderLines( const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxBorderColors&, QSGGeometry& ); - QSK_EXPORT void setColoredFillLines( const QRectF&, + void setColoredFillLines( const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskGradient&, QSGGeometry& ); - QSK_EXPORT void setColoredBorderAndFillLines( const QRectF&, + void setColoredBorderAndFillLines( const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxBorderColors&, const QskGradient&, QSGGeometry& ); - QSK_EXPORT QskGradient effectiveGradient( const QskGradient& ); -} + static bool isGradientSupported( const QskGradient& ); + static QskGradient effectiveGradient( const QskGradient& ); + + private: + // for adjustments to the target ( f.e devicePixelRatio ) + const QQuickWindow* m_window; +}; #endif diff --git a/src/nodes/QskVertex.h b/src/nodes/QskVertex.h index 967d2382d..e8ec92401 100644 --- a/src/nodes/QskVertex.h +++ b/src/nodes/QskVertex.h @@ -11,7 +11,6 @@ #include #include #include -#include namespace QskVertex { @@ -216,126 +215,6 @@ namespace QskVertex } } -namespace QskVertex -{ - class ArcIterator - { - public: - inline ArcIterator() = default; - - inline ArcIterator( int stepCount, bool inverted = false ) - { - reset( stepCount, inverted ); - } - - void reset( int stepCount, bool inverted = false ) - { - m_inverted = inverted; - - if ( inverted ) - { - m_cos = 1.0; - m_sin = 0.0; - } - else - { - m_cos = 0.0; - m_sin = 1.0; - } - - m_stepIndex = 0; - m_stepCount = stepCount; - - const auto angleStep = M_PI_2 / stepCount; - m_cosStep = qFastCos( angleStep ); - m_sinStep = qFastSin( angleStep ); - } - - inline bool isInverted() const { return m_inverted; } - - inline qreal cos() const { return m_cos; } - inline qreal sin() const { return m_inverted ? -m_sin : m_sin; } - - inline int step() const { return m_stepIndex; } - inline int stepCount() const { return m_stepCount; } - inline bool isDone() const { return m_stepIndex > m_stepCount; } - - inline void increment() - { - if ( ++m_stepIndex >= m_stepCount ) - { - if ( m_stepIndex == m_stepCount ) - { - /* - Doubles are not numerical stable and the small errors, - sum up when iterating in steps. To avoid having to deal with - fuzzy compares we manually fix cos/sin at the end. - */ - if ( m_inverted ) - { - m_cos = 0.0; - m_sin = -1.0; - } - else - { - m_cos = 1.0; - m_sin = 0.0; - } - } - } - else - { - const auto cos0 = m_cos; - - m_cos = m_cos * m_cosStep + m_sin * m_sinStep; - m_sin = m_sin * m_cosStep - cos0 * m_sinStep; - } - } - - inline void decrement() - { - revert(); - increment(); - revert(); - } - - inline void operator++() { increment(); } - - static int segmentHint( qreal radius ) - { - const auto arcLength = radius * M_PI_2; - return qBound( 3, qCeil( arcLength / 3.0 ), 18 ); // every 3 pixels - } - - inline void revert() - { - m_inverted = !m_inverted; - m_stepIndex = m_stepCount - m_stepIndex; - - m_sin = -m_sin; - } - - ArcIterator reverted() const - { - ArcIterator it = *this; - it.revert(); - - return it; - } - - private: - qreal m_cos; - qreal m_sin; - - int m_stepIndex; - qreal m_cosStep; - qreal m_sinStep; - - int m_stepCount; - bool m_inverted; - }; -} - namespace QskVertex { void debugGeometry( const QSGGeometry& ); diff --git a/src/nodes/QskBoxColorMap.h b/src/nodes/QskVertexHelper.h similarity index 63% rename from src/nodes/QskBoxColorMap.h rename to src/nodes/QskVertexHelper.h index 69f046044..6217f11e5 100644 --- a/src/nodes/QskBoxColorMap.h +++ b/src/nodes/QskVertexHelper.h @@ -3,14 +3,136 @@ * SPDX-License-Identifier: BSD-3-Clause *****************************************************************************/ -#ifndef QSK_BOX_RENDERER_COLOR_MAP_H -#define QSK_BOX_RENDERER_COLOR_MAP_H +#ifndef QSK_VERTEX_HELPER_H +#define QSK_VERTEX_HELPER_H -#include -#include -#include +#include "QskGradient.h" +#include "QskGradientDirection.h" +#include "QskVertex.h" -namespace QskBoxRenderer +#include + +namespace QskVertex +{ + class ArcIterator + { + public: + inline ArcIterator() = default; + + inline ArcIterator( int stepCount, bool inverted = false ) + { + reset( stepCount, inverted ); + } + + void reset( int stepCount, bool inverted = false ) + { + m_inverted = inverted; + + if ( inverted ) + { + m_cos = 1.0; + m_sin = 0.0; + } + else + { + m_cos = 0.0; + m_sin = 1.0; + } + + m_stepIndex = 0; + m_stepCount = stepCount; + + const auto angleStep = M_PI_2 / stepCount; + m_cosStep = qFastCos( angleStep ); + m_sinStep = qFastSin( angleStep ); + } + + inline bool isInverted() const { return m_inverted; } + + inline qreal cos() const { return m_cos; } + inline qreal sin() const { return m_inverted ? -m_sin : m_sin; } + + inline int step() const { return m_stepIndex; } + inline int stepCount() const { return m_stepCount; } + inline bool isDone() const { return m_stepIndex > m_stepCount; } + + inline void increment() + { + if ( ++m_stepIndex >= m_stepCount ) + { + if ( m_stepIndex == m_stepCount ) + { + /* + Doubles are not numerical stable and the small errors, + sum up when iterating in steps. To avoid having to deal with + fuzzy compares we manually fix cos/sin at the end. + */ + if ( m_inverted ) + { + m_cos = 0.0; + m_sin = -1.0; + } + else + { + m_cos = 1.0; + m_sin = 0.0; + } + } + } + else + { + const auto cos0 = m_cos; + + m_cos = m_cos * m_cosStep + m_sin * m_sinStep; + m_sin = m_sin * m_cosStep - cos0 * m_sinStep; + } + } + + inline void decrement() + { + revert(); + increment(); + revert(); + } + + inline void operator++() { increment(); } + + static int segmentHint( qreal radius ) + { + const auto arcLength = radius * M_PI_2; + return qBound( 3, qCeil( arcLength / 3.0 ), 18 ); // every 3 pixels + } + + inline void revert() + { + m_inverted = !m_inverted; + m_stepIndex = m_stepCount - m_stepIndex; + + m_sin = -m_sin; + } + + ArcIterator reverted() const + { + ArcIterator it = *this; + it.revert(); + + return it; + } + + private: + qreal m_cos; + qreal m_sin; + + int m_stepIndex; + qreal m_cosStep; + qreal m_sinStep; + + int m_stepCount; + bool m_inverted; + }; +} + +namespace QskVertex { class ColorMap { @@ -101,7 +223,10 @@ namespace QskBoxRenderer const QskVertex::Color m_color1; const QskVertex::Color m_color2; }; +} +namespace QskVertex +{ class GradientIterator { public: