special code for corner cases disabled

This commit is contained in:
Uwe Rathmann 2024-06-03 15:36:15 +02:00
parent beb31f9f1f
commit fb635664de
4 changed files with 72 additions and 49 deletions

View File

@ -130,12 +130,17 @@ QPainterPath QskArcMetrics::painterPath( const QRectF& ellipseRect ) const
if ( t <= 0.0 || qFuzzyIsNull( m_spanAngle ) )
return QPainterPath();
#if 0
/*
We do not have a proper solution for situations, where
the width leads to overlapping upper/lower or left/right parts.
*/
const auto innerRect = ellipseRect.adjusted( t, t, -t, -t );
QPainterPath path;
if ( innerRect.isEmpty() )
{
QPainterPath path;
if ( qAbs( m_spanAngle ) >= 360.0 )
{
path.addEllipse( ellipseRect );
@ -148,24 +153,23 @@ QPainterPath QskArcMetrics::painterPath( const QRectF& ellipseRect ) const
path.lineTo( ellipseRect.center() );
path.closeSubpath();
}
return path;
}
else
{
const auto t2 = 0.5 * t;
const auto r = ellipseRect.adjusted( t2, t2, -t2, -t2 );
#endif
QPainterPath arcPath;
arcPath.arcMoveTo( r, m_startAngle ); // replaces the dummy arcMoveTo above
arcPath.arcTo( r, m_startAngle, m_spanAngle );
const auto t2 = 0.5 * t;
const auto r = ellipseRect.adjusted( t2, t2, -t2, -t2 );
QPainterPathStroker stroker;
stroker.setCapStyle( Qt::FlatCap );
stroker.setWidth( t );
QPainterPath path;
path.arcMoveTo( r, m_startAngle ); // replaces the dummy arcMoveTo above
path.arcTo( r, m_startAngle, m_spanAngle );
path = stroker.createStroke( arcPath );
}
QPainterPathStroker stroker;
stroker.setCapStyle( Qt::FlatCap );
stroker.setWidth( t );
return path;
return stroker.createStroke( path );
}
QRectF QskArcMetrics::boundingRect( const QRectF& ellipseRect ) const

View File

@ -7,6 +7,7 @@
#include "QskArcMetrics.h"
#include "QskArcShadowNode.h"
#include "QskArcRenderNode.h"
#include "QskArcRenderer.h"
#include "QskMargins.h"
#include "QskGradient.h"
#include "QskShapeNode.h"
@ -17,7 +18,6 @@
#include <qpainterpath.h>
// #define ARC_BORDER_NODE
#define ARC_FILL_NODE
#ifdef ARC_BORDER_NODE
using BorderNode = QskArcRenderNode;
@ -26,18 +26,15 @@
using BorderNode = QskStrokeNode;
#endif
#ifdef ARC_FILL_NODE
using FillNode = QskArcRenderNode;
#else
using FillNode = QskShapeNode;
#endif
namespace
{
enum NodeRole
{
ShadowRole,
FillRole,
PathRole,
ArcRole,
BorderRole
};
}
@ -84,7 +81,8 @@ static inline QRectF qskEffectiveRect(
static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
{
static const QVector< quint8 > roles = { ShadowRole, FillRole, BorderRole };
static const QVector< quint8 > roles =
{ ShadowRole, PathRole, ArcRole, BorderRole };
auto oldNode = QskSGNode::findChildNode( parentNode, role );
QskSGNode::replaceChildNode( roles, role, parentNode, oldNode, node );
@ -120,17 +118,21 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
auto shadowNode = static_cast< QskArcShadowNode* >(
QskSGNode::findChildNode( this, ShadowRole ) );
auto fillNode = static_cast< FillNode* >(
QskSGNode::findChildNode( this, FillRole ) );
auto pathNode = static_cast< QskShapeNode* >(
QskSGNode::findChildNode( this, PathRole ) );
auto arcNode = static_cast< QskArcRenderNode* >(
QskSGNode::findChildNode( this, ArcRole ) );
auto borderNode = static_cast< BorderNode* >(
QskSGNode::findChildNode( this, BorderRole ) );
const auto arcRect = qskEffectiveRect( rect, borderWidth );
if ( arcRect.isEmpty() )
if ( metricsArc.isNull() || arcRect.isEmpty() )
{
delete shadowNode;
delete fillNode;
delete pathNode;
delete arcNode;
delete borderNode;
return;
}
@ -172,22 +174,39 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
if ( isFillNodeVisible )
{
if ( fillNode == nullptr )
if ( QskArcRenderer::isGradientSupported( gradient ) )
{
fillNode = new FillNode;
QskSGNode::setNodeRole( fillNode, FillRole );
}
delete pathNode;
pathNode = nullptr;
#ifdef ARC_FILL_NODE
fillNode->updateNode( arcRect, metricsArc, gradient );
#else
fillNode->updateNode( path, QTransform(), arcRect, gradient );
#endif
if ( arcNode == nullptr )
{
arcNode = new QskArcRenderNode;
QskSGNode::setNodeRole( arcNode, ArcRole );
}
arcNode->updateNode( arcRect, metricsArc, gradient );
}
else
{
delete arcNode;
arcNode = nullptr;
if ( pathNode == nullptr )
{
pathNode = new QskShapeNode;
QskSGNode::setNodeRole( pathNode, PathRole );
}
pathNode->updateNode( path, QTransform(), arcRect, gradient );
}
}
else
{
delete fillNode;
fillNode = nullptr;
delete pathNode;
pathNode = nullptr;
delete arcNode;
arcNode = nullptr;
}
if ( isStrokeNodeVisible )
@ -214,6 +233,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
}
qskUpdateChildren( this, ShadowRole, shadowNode );
qskUpdateChildren( this, FillRole, fillNode );
qskUpdateChildren( this, PathRole, pathNode );
qskUpdateChildren( this, ArcRole, arcNode );
qskUpdateChildren( this, BorderRole, borderNode );
}

View File

@ -264,13 +264,12 @@ void QskArcRenderer::renderFillGeometry( const QRectF& rect,
renderFillGeometry( rect, metrics, 0.0, geometry );
}
bool QskArcRenderer::isGradientSupported(
const QskArcMetrics& metrics, const QskGradient& gradient )
bool QskArcRenderer::isGradientSupported( const QskGradient& gradient )
{
if ( metrics.isNull() || !gradient.isVisible() || gradient.isMonochrome() )
return true;
if ( gradient.isVisible() && !gradient.isMonochrome() )
return gradient.type() == QskGradient::Stops;
return gradient.type() == QskGradient::Stops;
return true;
}
void QskArcRenderer::renderArc( const QRectF& rect,

View File

@ -22,7 +22,7 @@ namespace QskArcRenderer
see QSGGeometry::defaultAttributes_Point2D()
- clip nodes
- using shaders setting the color information
- using shaders setting the colors
*/
QSK_EXPORT void renderBorderGeometry( const QRectF&,
@ -35,10 +35,10 @@ namespace QskArcRenderer
const QskArcMetrics&, QSGGeometry& );
/*
Filling the geometry usually with color information:
Filling the geometry with color information:
see QSGGeometry::defaultAttributes_ColoredPoint2D()
*/
QSK_EXPORT bool isGradientSupported( const QskArcMetrics&, const QskGradient& );
QSK_EXPORT bool isGradientSupported( const QskGradient& );
QSK_EXPORT void renderArc( const QRectF&,
const QskArcMetrics&, qreal borderWidth, const QColor& borderColor,