QskArcRenderer started with some boilerplate code
This commit is contained in:
parent
0afecc4b9e
commit
49e1d54724
|
@ -101,6 +101,7 @@ list(APPEND SOURCES
|
|||
|
||||
list(APPEND HEADERS
|
||||
nodes/QskArcNode.h
|
||||
nodes/QskArcRenderer.h
|
||||
nodes/QskArcShadowNode.h
|
||||
nodes/QskBasicLinesNode.h
|
||||
nodes/QskBoxNode.h
|
||||
|
@ -141,6 +142,7 @@ list(APPEND PRIVATE_HEADERS
|
|||
|
||||
list(APPEND SOURCES
|
||||
nodes/QskArcNode.cpp
|
||||
nodes/QskArcRenderer.cpp
|
||||
nodes/QskArcShadowNode.cpp
|
||||
nodes/QskBasicLinesNode.cpp
|
||||
nodes/QskBoxNode.cpp
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskArcRenderer.h"
|
||||
#include "QskArcMetrics.h"
|
||||
#include "QskGradient.h"
|
||||
#include "QskVertex.h"
|
||||
|
||||
#include <qsggeometry.h>
|
||||
|
||||
static inline QskVertex::Line* qskAllocateLines(
|
||||
QSGGeometry& geometry, int lineCount )
|
||||
{
|
||||
geometry.allocate( 2 * lineCount ); // 2 points per line
|
||||
return reinterpret_cast< QskVertex::Line* >( geometry.vertexData() );
|
||||
}
|
||||
|
||||
static inline QskVertex::ColoredLine* qskAllocateColoredLines(
|
||||
QSGGeometry& geometry, int lineCount )
|
||||
{
|
||||
geometry.allocate( 2 * lineCount ); // 2 points per line
|
||||
return reinterpret_cast< QskVertex::ColoredLine* >( geometry.vertexData() );
|
||||
}
|
||||
|
||||
static inline int qskApproximatedCircumference( const QRectF& rect )
|
||||
{
|
||||
const qreal a = rect.width();
|
||||
const qreal b = rect.height();
|
||||
|
||||
const auto ratio = a / b;
|
||||
if ( ratio > 0.9 || ratio < 1.1 )
|
||||
return std::max( a, b ) * 2.0 * M_PI; // circle
|
||||
|
||||
// Srinivasa Ramanujan: https://en.wikipedia.org/wiki/Ellipse#Circumference
|
||||
|
||||
const qreal d1 = ( a - b );
|
||||
const qreal d2 = ( a + b );
|
||||
const qreal h = ( d1 * d1 ) / ( d2 * d2 );
|
||||
|
||||
return M_PI * d2 * ( 1.0 + ( 3 * h / ( 10 + sqrt( 4 - 3 * h ) ) ) );
|
||||
}
|
||||
|
||||
static inline int qskStepCount( const QRectF& rect )
|
||||
{
|
||||
const int length = qskApproximatedCircumference( rect );
|
||||
return std::max( 3, qCeil( length / 3.0 ) );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class Stroker
|
||||
{
|
||||
public:
|
||||
Stroker( const QRectF&, const QskArcMetrics& metrics, qreal borderWidth );
|
||||
|
||||
int fillCount() const;
|
||||
int borderCount() const;
|
||||
|
||||
void setBorderLines( QskVertex::Line* ) const;
|
||||
|
||||
private:
|
||||
const QRectF& m_rect;
|
||||
const QskArcMetrics& m_metrics;
|
||||
const qreal m_borderWidth;
|
||||
};
|
||||
}
|
||||
|
||||
Stroker::Stroker( const QRectF& rect, const QskArcMetrics& metrics, qreal borderWidth )
|
||||
: m_rect( rect )
|
||||
, m_metrics( metrics )
|
||||
, m_borderWidth( borderWidth )
|
||||
{
|
||||
Q_ASSERT( metrics.sizeMode() == Qt::AbsoluteSize );
|
||||
}
|
||||
|
||||
int Stroker::fillCount() const
|
||||
{
|
||||
return 0; // TODO
|
||||
}
|
||||
|
||||
int Stroker::borderCount() const
|
||||
{
|
||||
if ( m_metrics.isNull() )
|
||||
return 0;
|
||||
|
||||
int n = qskStepCount( m_rect );
|
||||
if ( !m_metrics.isClosed() )
|
||||
{
|
||||
n = qCeil( n * qAbs( m_metrics.spanAngle() ) / 360.0 );
|
||||
n += 1; // closing line
|
||||
}
|
||||
|
||||
n *= 2; // inner/outer border
|
||||
n += 1; // dummy line connection inner/outer border
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void Stroker::setBorderLines( QskVertex::Line* lines ) const
|
||||
{
|
||||
Q_UNUSED( lines );
|
||||
}
|
||||
|
||||
void QskArcRenderer::renderBorderGeometry( const QRectF& rect,
|
||||
const QskArcMetrics& metrics, qreal borderWidth, QSGGeometry& geometry )
|
||||
{
|
||||
geometry.setDrawingMode( QSGGeometry::DrawTriangleStrip );
|
||||
|
||||
Stroker stroker( rect, metrics, borderWidth );
|
||||
|
||||
const auto lines = qskAllocateLines( geometry, stroker.borderCount() );
|
||||
if ( lines )
|
||||
stroker.setBorderLines( lines );
|
||||
}
|
||||
|
||||
void QskArcRenderer::renderFillGeometry( const QRectF& rect,
|
||||
const QskArcMetrics& metrics, qreal borderWidth, QSGGeometry& geometry )
|
||||
{
|
||||
Q_UNUSED( rect );
|
||||
Q_UNUSED( geometry );
|
||||
|
||||
Stroker stroker( rect, metrics, borderWidth );
|
||||
|
||||
const auto lines = qskAllocateColoredLines( geometry, stroker.fillCount() );
|
||||
if ( lines )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
void QskArcRenderer::renderFillGeometry( const QRectF& rect,
|
||||
const QskArcMetrics& metrics, QSGGeometry& geometry )
|
||||
{
|
||||
renderFillGeometry( rect, metrics, 0.0, geometry );
|
||||
}
|
||||
|
||||
bool QskArcRenderer::isGradientSupported(
|
||||
const QskArcMetrics& metrics, const QskGradient& gradient )
|
||||
{
|
||||
if ( metrics.isNull() || !gradient.isVisible() || gradient.isMonochrome() )
|
||||
return true;
|
||||
|
||||
return gradient.type() == QskGradient::Stops;
|
||||
}
|
||||
|
||||
void QskArcRenderer::renderArc( const QRectF& rect,
|
||||
const QskArcMetrics& metrics, qreal borderWidth, const QColor& borderColor,
|
||||
const QskGradient& gradient, QSGGeometry& geometry )
|
||||
{
|
||||
Q_UNUSED( rect );
|
||||
Q_UNUSED( metrics );
|
||||
Q_UNUSED( borderWidth );
|
||||
Q_UNUSED( borderColor );
|
||||
Q_UNUSED( gradient );
|
||||
Q_UNUSED( geometry );
|
||||
}
|
||||
|
||||
void QskArcRenderer::renderArc( const QRectF& rect, const QskArcMetrics& metrics,
|
||||
const QskGradient& gradient, QSGGeometry& geometry )
|
||||
{
|
||||
renderArc( rect, metrics, 0, QColor(), gradient, geometry );
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_ARC_RENDERER_H
|
||||
#define QSK_ARC_RENDERER_H
|
||||
|
||||
#include "QskGlobal.h"
|
||||
|
||||
class QskArcMetrics;
|
||||
class QskGradient;
|
||||
|
||||
class QSGGeometry;
|
||||
class QRectF;
|
||||
class QColor;
|
||||
|
||||
namespace QskArcRenderer
|
||||
{
|
||||
/*
|
||||
Filling the geometry without any color information:
|
||||
see QSGGeometry::defaultAttributes_Point2D()
|
||||
|
||||
- clip nodes
|
||||
- using shaders setting the color information
|
||||
*/
|
||||
|
||||
QSK_EXPORT void renderBorderGeometry( const QRectF&,
|
||||
const QskArcMetrics&, qreal borderWidth, QSGGeometry& );
|
||||
|
||||
QSK_EXPORT void renderFillGeometry( const QRectF&,
|
||||
const QskArcMetrics&, qreal borderWidth, QSGGeometry& );
|
||||
|
||||
QSK_EXPORT void renderFillGeometry( const QRectF&,
|
||||
const QskArcMetrics&, QSGGeometry& );
|
||||
|
||||
/*
|
||||
Filling the geometry usually with color information:
|
||||
see QSGGeometry::defaultAttributes_ColoredPoint2D()
|
||||
*/
|
||||
QSK_EXPORT bool isGradientSupported( const QskArcMetrics&, const QskGradient& );
|
||||
|
||||
QSK_EXPORT void renderArc( const QRectF&,
|
||||
const QskArcMetrics&, qreal borderWidth, const QColor& borderColor,
|
||||
const QskGradient&, QSGGeometry& );
|
||||
|
||||
QSK_EXPORT void renderArc( const QRectF&, const QskArcMetrics&,
|
||||
const QskGradient&, QSGGeometry& );
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue