special code for corner cases disabled
This commit is contained in:
parent
beb31f9f1f
commit
fb635664de
|
@ -130,12 +130,17 @@ QPainterPath QskArcMetrics::painterPath( const QRectF& ellipseRect ) const
|
||||||
if ( t <= 0.0 || qFuzzyIsNull( m_spanAngle ) )
|
if ( t <= 0.0 || qFuzzyIsNull( m_spanAngle ) )
|
||||||
return QPainterPath();
|
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 );
|
const auto innerRect = ellipseRect.adjusted( t, t, -t, -t );
|
||||||
|
|
||||||
QPainterPath path;
|
|
||||||
|
|
||||||
if ( innerRect.isEmpty() )
|
if ( innerRect.isEmpty() )
|
||||||
{
|
{
|
||||||
|
QPainterPath path;
|
||||||
|
|
||||||
if ( qAbs( m_spanAngle ) >= 360.0 )
|
if ( qAbs( m_spanAngle ) >= 360.0 )
|
||||||
{
|
{
|
||||||
path.addEllipse( ellipseRect );
|
path.addEllipse( ellipseRect );
|
||||||
|
@ -148,24 +153,23 @@ QPainterPath QskArcMetrics::painterPath( const QRectF& ellipseRect ) const
|
||||||
path.lineTo( ellipseRect.center() );
|
path.lineTo( ellipseRect.center() );
|
||||||
path.closeSubpath();
|
path.closeSubpath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
{
|
|
||||||
const auto t2 = 0.5 * t;
|
|
||||||
const auto r = ellipseRect.adjusted( t2, t2, -t2, -t2 );
|
|
||||||
|
|
||||||
QPainterPath arcPath;
|
const auto t2 = 0.5 * t;
|
||||||
arcPath.arcMoveTo( r, m_startAngle ); // replaces the dummy arcMoveTo above
|
const auto r = ellipseRect.adjusted( t2, t2, -t2, -t2 );
|
||||||
arcPath.arcTo( r, m_startAngle, m_spanAngle );
|
|
||||||
|
|
||||||
QPainterPathStroker stroker;
|
QPainterPath path;
|
||||||
stroker.setCapStyle( Qt::FlatCap );
|
path.arcMoveTo( r, m_startAngle ); // replaces the dummy arcMoveTo above
|
||||||
stroker.setWidth( t );
|
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
|
QRectF QskArcMetrics::boundingRect( const QRectF& ellipseRect ) const
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "QskArcMetrics.h"
|
#include "QskArcMetrics.h"
|
||||||
#include "QskArcShadowNode.h"
|
#include "QskArcShadowNode.h"
|
||||||
#include "QskArcRenderNode.h"
|
#include "QskArcRenderNode.h"
|
||||||
|
#include "QskArcRenderer.h"
|
||||||
#include "QskMargins.h"
|
#include "QskMargins.h"
|
||||||
#include "QskGradient.h"
|
#include "QskGradient.h"
|
||||||
#include "QskShapeNode.h"
|
#include "QskShapeNode.h"
|
||||||
|
@ -17,7 +18,6 @@
|
||||||
#include <qpainterpath.h>
|
#include <qpainterpath.h>
|
||||||
|
|
||||||
// #define ARC_BORDER_NODE
|
// #define ARC_BORDER_NODE
|
||||||
#define ARC_FILL_NODE
|
|
||||||
|
|
||||||
#ifdef ARC_BORDER_NODE
|
#ifdef ARC_BORDER_NODE
|
||||||
using BorderNode = QskArcRenderNode;
|
using BorderNode = QskArcRenderNode;
|
||||||
|
@ -26,18 +26,15 @@
|
||||||
using BorderNode = QskStrokeNode;
|
using BorderNode = QskStrokeNode;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARC_FILL_NODE
|
|
||||||
using FillNode = QskArcRenderNode;
|
|
||||||
#else
|
|
||||||
using FillNode = QskShapeNode;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
enum NodeRole
|
enum NodeRole
|
||||||
{
|
{
|
||||||
ShadowRole,
|
ShadowRole,
|
||||||
FillRole,
|
|
||||||
|
PathRole,
|
||||||
|
ArcRole,
|
||||||
|
|
||||||
BorderRole
|
BorderRole
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -84,7 +81,8 @@ static inline QRectF qskEffectiveRect(
|
||||||
|
|
||||||
static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
|
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 );
|
auto oldNode = QskSGNode::findChildNode( parentNode, role );
|
||||||
QskSGNode::replaceChildNode( roles, role, parentNode, oldNode, node );
|
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* >(
|
auto shadowNode = static_cast< QskArcShadowNode* >(
|
||||||
QskSGNode::findChildNode( this, ShadowRole ) );
|
QskSGNode::findChildNode( this, ShadowRole ) );
|
||||||
|
|
||||||
auto fillNode = static_cast< FillNode* >(
|
auto pathNode = static_cast< QskShapeNode* >(
|
||||||
QskSGNode::findChildNode( this, FillRole ) );
|
QskSGNode::findChildNode( this, PathRole ) );
|
||||||
|
|
||||||
|
auto arcNode = static_cast< QskArcRenderNode* >(
|
||||||
|
QskSGNode::findChildNode( this, ArcRole ) );
|
||||||
|
|
||||||
auto borderNode = static_cast< BorderNode* >(
|
auto borderNode = static_cast< BorderNode* >(
|
||||||
QskSGNode::findChildNode( this, BorderRole ) );
|
QskSGNode::findChildNode( this, BorderRole ) );
|
||||||
|
|
||||||
const auto arcRect = qskEffectiveRect( rect, borderWidth );
|
const auto arcRect = qskEffectiveRect( rect, borderWidth );
|
||||||
if ( arcRect.isEmpty() )
|
if ( metricsArc.isNull() || arcRect.isEmpty() )
|
||||||
{
|
{
|
||||||
delete shadowNode;
|
delete shadowNode;
|
||||||
delete fillNode;
|
delete pathNode;
|
||||||
|
delete arcNode;
|
||||||
delete borderNode;
|
delete borderNode;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -172,22 +174,39 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
|
||||||
|
|
||||||
if ( isFillNodeVisible )
|
if ( isFillNodeVisible )
|
||||||
{
|
{
|
||||||
if ( fillNode == nullptr )
|
if ( QskArcRenderer::isGradientSupported( gradient ) )
|
||||||
{
|
{
|
||||||
fillNode = new FillNode;
|
delete pathNode;
|
||||||
QskSGNode::setNodeRole( fillNode, FillRole );
|
pathNode = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ARC_FILL_NODE
|
if ( arcNode == nullptr )
|
||||||
fillNode->updateNode( arcRect, metricsArc, gradient );
|
{
|
||||||
#else
|
arcNode = new QskArcRenderNode;
|
||||||
fillNode->updateNode( path, QTransform(), arcRect, gradient );
|
QskSGNode::setNodeRole( arcNode, ArcRole );
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
delete fillNode;
|
delete pathNode;
|
||||||
fillNode = nullptr;
|
pathNode = nullptr;
|
||||||
|
|
||||||
|
delete arcNode;
|
||||||
|
arcNode = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isStrokeNodeVisible )
|
if ( isStrokeNodeVisible )
|
||||||
|
@ -214,6 +233,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
|
||||||
}
|
}
|
||||||
|
|
||||||
qskUpdateChildren( this, ShadowRole, shadowNode );
|
qskUpdateChildren( this, ShadowRole, shadowNode );
|
||||||
qskUpdateChildren( this, FillRole, fillNode );
|
qskUpdateChildren( this, PathRole, pathNode );
|
||||||
|
qskUpdateChildren( this, ArcRole, arcNode );
|
||||||
qskUpdateChildren( this, BorderRole, borderNode );
|
qskUpdateChildren( this, BorderRole, borderNode );
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,13 +264,12 @@ void QskArcRenderer::renderFillGeometry( const QRectF& rect,
|
||||||
renderFillGeometry( rect, metrics, 0.0, geometry );
|
renderFillGeometry( rect, metrics, 0.0, geometry );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskArcRenderer::isGradientSupported(
|
bool QskArcRenderer::isGradientSupported( const QskGradient& gradient )
|
||||||
const QskArcMetrics& metrics, const QskGradient& gradient )
|
|
||||||
{
|
{
|
||||||
if ( metrics.isNull() || !gradient.isVisible() || gradient.isMonochrome() )
|
if ( gradient.isVisible() && !gradient.isMonochrome() )
|
||||||
return true;
|
return gradient.type() == QskGradient::Stops;
|
||||||
|
|
||||||
return gradient.type() == QskGradient::Stops;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskArcRenderer::renderArc( const QRectF& rect,
|
void QskArcRenderer::renderArc( const QRectF& rect,
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace QskArcRenderer
|
||||||
see QSGGeometry::defaultAttributes_Point2D()
|
see QSGGeometry::defaultAttributes_Point2D()
|
||||||
|
|
||||||
- clip nodes
|
- clip nodes
|
||||||
- using shaders setting the color information
|
- using shaders setting the colors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QSK_EXPORT void renderBorderGeometry( const QRectF&,
|
QSK_EXPORT void renderBorderGeometry( const QRectF&,
|
||||||
|
@ -35,10 +35,10 @@ namespace QskArcRenderer
|
||||||
const QskArcMetrics&, QSGGeometry& );
|
const QskArcMetrics&, QSGGeometry& );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Filling the geometry usually with color information:
|
Filling the geometry with color information:
|
||||||
see QSGGeometry::defaultAttributes_ColoredPoint2D()
|
see QSGGeometry::defaultAttributes_ColoredPoint2D()
|
||||||
*/
|
*/
|
||||||
QSK_EXPORT bool isGradientSupported( const QskArcMetrics&, const QskGradient& );
|
QSK_EXPORT bool isGradientSupported( const QskGradient& );
|
||||||
|
|
||||||
QSK_EXPORT void renderArc( const QRectF&,
|
QSK_EXPORT void renderArc( const QRectF&,
|
||||||
const QskArcMetrics&, qreal borderWidth, const QColor& borderColor,
|
const QskArcMetrics&, qreal borderWidth, const QColor& borderColor,
|
||||||
|
|
Loading…
Reference in New Issue