157 lines
4.3 KiB
C++
157 lines
4.3 KiB
C++
/******************************************************************************
|
|
* QSkinny - Copyright (C) The authors
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*****************************************************************************/
|
|
|
|
#include "QskArcRenderNode.h"
|
|
#include "QskGradient.h"
|
|
#include "QskArcRenderer.h"
|
|
#include "QskArcMetrics.h"
|
|
#include "QskGradient.h"
|
|
#include "QskSGNode.h"
|
|
#include "QskFillNodePrivate.h"
|
|
|
|
class QskArcRenderNodePrivate final : public QskFillNodePrivate
|
|
{
|
|
public:
|
|
inline void resetNode( QskArcRenderNode* node )
|
|
{
|
|
hash = 0;
|
|
node->resetGeometry();
|
|
}
|
|
|
|
inline bool updateHash( const QRectF& rect, const QskArcMetrics& metrics,
|
|
bool radial, qreal borderWidth, const QColor& borderColor,
|
|
const QskGradient& gradient )
|
|
{
|
|
QskHashValue value = 3496;
|
|
|
|
value = qHashBits( &rect, sizeof( QRectF ), value );
|
|
value = metrics.hash( value );
|
|
value = qHash( radial, value );
|
|
value = qHash( borderWidth, value );
|
|
value = qHashBits( &borderColor, sizeof( borderColor ), value );
|
|
|
|
if ( gradient.isVisible() )
|
|
value = gradient.hash( value );
|
|
|
|
if ( hash != value )
|
|
{
|
|
hash = value;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
QskHashValue hash = 0;
|
|
};
|
|
|
|
QskArcRenderNode::QskArcRenderNode()
|
|
: QskFillNode( *new QskArcRenderNodePrivate )
|
|
{
|
|
}
|
|
|
|
QskArcRenderNode::~QskArcRenderNode()
|
|
{
|
|
}
|
|
|
|
void QskArcRenderNode::updateFilling( const QRectF& rect,
|
|
const QskArcMetrics& metrics, const QskGradient& gradient )
|
|
{
|
|
updateFilling( rect, metrics, false, 0.0, gradient );
|
|
}
|
|
|
|
void QskArcRenderNode::updateFilling( const QRectF& rect,
|
|
const QskArcMetrics& arcMetrics, bool radial,
|
|
qreal borderWidth, const QskGradient& gradient )
|
|
{
|
|
Q_D( QskArcRenderNode );
|
|
|
|
const auto metrics = arcMetrics.toAbsolute( rect.size() );
|
|
const auto borderMax = 0.5 * metrics.thickness();
|
|
|
|
const bool hasFill = gradient.isVisible() && ( borderWidth < borderMax );
|
|
const bool hasBorder = false;
|
|
|
|
if ( rect.isEmpty() || metrics.isNull() || !( hasFill || hasBorder ) )
|
|
{
|
|
d->resetNode( this );
|
|
return;
|
|
}
|
|
|
|
borderWidth = qMin( borderWidth, borderMax );
|
|
|
|
if ( !d->updateHash( rect, metrics, radial, borderWidth, QColor(), gradient ) )
|
|
{
|
|
d->resetNode( this );
|
|
return;
|
|
}
|
|
|
|
#if 1
|
|
const bool coloredGeometry = hasHint( PreferColoredGeometry )
|
|
&& QskArcRenderer::isGradientSupported( rect, metrics, gradient );
|
|
Q_ASSERT( coloredGeometry ); // TODO ...
|
|
#endif
|
|
|
|
auto& geometry = *this->geometry();
|
|
|
|
setColoring( QskFillNode::Polychrome );
|
|
|
|
QskArcRenderer::setColoredFillLines( rect, metrics, radial,
|
|
borderWidth, gradient, geometry );
|
|
|
|
markDirty( QSGNode::DirtyGeometry );
|
|
}
|
|
|
|
void QskArcRenderNode::updateBorder( const QRectF& rect,
|
|
const QskArcMetrics& metrics, bool radial,
|
|
qreal borderWidth, const QColor& borderColor )
|
|
{
|
|
updateArc( rect, metrics, radial, borderWidth, borderColor, QskGradient() );
|
|
}
|
|
|
|
void QskArcRenderNode::updateArc(
|
|
const QRectF& rect, const QskArcMetrics& arcMetrics, bool radial,
|
|
qreal borderWidth, const QColor& borderColor, const QskGradient& gradient )
|
|
{
|
|
Q_D( QskArcRenderNode );
|
|
|
|
const auto metrics = arcMetrics.toAbsolute( rect.size() );
|
|
const auto borderMax = 0.5 * metrics.thickness();
|
|
|
|
const bool hasFill = gradient.isVisible() && ( borderWidth < borderMax );
|
|
const bool hasBorder = ( borderWidth > 0.0 )
|
|
&& borderColor.isValid() && ( borderColor.alpha() > 0 );
|
|
|
|
if ( rect.isEmpty() || metrics.isNull() || !( hasFill || hasBorder ) )
|
|
{
|
|
d->resetNode( this );
|
|
return;
|
|
}
|
|
|
|
borderWidth = qMin( borderWidth, borderMax );
|
|
|
|
if ( !d->updateHash( rect, metrics, radial, borderWidth, borderColor, gradient ) )
|
|
{
|
|
d->resetNode( this );
|
|
return;
|
|
}
|
|
|
|
#if 1
|
|
const bool coloredGeometry = hasHint( PreferColoredGeometry )
|
|
&& QskArcRenderer::isGradientSupported( rect, metrics, gradient );
|
|
Q_ASSERT( coloredGeometry ); // TODO ...
|
|
#endif
|
|
|
|
auto& geometry = *this->geometry();
|
|
|
|
setColoring( QskFillNode::Polychrome );
|
|
|
|
QskArcRenderer::setColoredBorderAndFillLines( rect, metrics, radial,
|
|
borderWidth, borderColor, gradient, geometry );
|
|
|
|
markDirty( QSGNode::DirtyGeometry );
|
|
}
|