QskLinesNode reorganized
This commit is contained in:
parent
bf19d6464c
commit
5d3cba5650
|
@ -4,7 +4,6 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "QskLinesNode.h"
|
#include "QskLinesNode.h"
|
||||||
#include "QskIntervalF.h"
|
|
||||||
#include "QskVertex.h"
|
#include "QskVertex.h"
|
||||||
#include "QskStippleMetrics.h"
|
#include "QskStippleMetrics.h"
|
||||||
#include "QskSGNode.h"
|
#include "QskSGNode.h"
|
||||||
|
@ -186,10 +185,19 @@ void QskLinesNode::setGlobalPosition(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::updateGrid( const QColor& color, qreal lineWidth,
|
void QskLinesNode::updateLines( const QColor& color,
|
||||||
const QskStippleMetrics& stippleMetrics, const QTransform& transform,
|
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
||||||
const QskIntervalF& xBoundaries, const QVector< qreal >& xValues,
|
const QTransform& transform, const QRectF& rect )
|
||||||
const QskIntervalF& yBoundaries, const QVector< qreal >& yValues )
|
{
|
||||||
|
// using QVarLengthArray instead. TODO ...
|
||||||
|
updateLines( color, lineWidth, stippleMetrics, transform,
|
||||||
|
rect, { rect.left(), rect.right() }, { rect.top(), rect.bottom() } );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskLinesNode::updateLines( const QColor& color,
|
||||||
|
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
||||||
|
const QTransform& transform, const QRectF& rect,
|
||||||
|
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
Q_D( QskLinesNode );
|
||||||
|
|
||||||
|
@ -203,8 +211,7 @@ void QskLinesNode::updateGrid( const QColor& color, qreal lineWidth,
|
||||||
|
|
||||||
hash = stippleMetrics.hash( hash );
|
hash = stippleMetrics.hash( hash );
|
||||||
hash = qHash( transform, hash );
|
hash = qHash( transform, hash );
|
||||||
hash = qHashBits( &xBoundaries, sizeof( xBoundaries ), hash );
|
hash = qHashBits( &rect, sizeof( QRectF ), hash );
|
||||||
hash = qHashBits( &yBoundaries, sizeof( yBoundaries ), hash );
|
|
||||||
hash = qHash( xValues, hash );
|
hash = qHash( xValues, hash );
|
||||||
hash = qHash( yValues, hash );
|
hash = qHash( yValues, hash );
|
||||||
|
|
||||||
|
@ -216,15 +223,15 @@ void QskLinesNode::updateGrid( const QColor& color, qreal lineWidth,
|
||||||
|
|
||||||
if( d->dirty )
|
if( d->dirty )
|
||||||
{
|
{
|
||||||
if ( !( stippleMetrics.isValid()
|
if ( rect.isEmpty() || !stippleMetrics.isValid()
|
||||||
&& color.isValid() && color.alpha() > 0 ) )
|
|| !color.isValid() || color.alpha() == 0 )
|
||||||
{
|
{
|
||||||
QskSGNode::resetGeometry( this );
|
QskSGNode::resetGeometry( this );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateGeometry( stippleMetrics, transform,
|
updateGeometry( stippleMetrics,
|
||||||
xBoundaries, xValues, yBoundaries, yValues );
|
transform, rect, xValues, yValues );
|
||||||
}
|
}
|
||||||
|
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
@ -237,40 +244,34 @@ void QskLinesNode::updateGrid( const QColor& color, qreal lineWidth,
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::updateGeometry(
|
void QskLinesNode::updateGeometry(
|
||||||
const QskStippleMetrics& stippleMetrics, const QTransform& transform,
|
const QskStippleMetrics& stippleMetrics,
|
||||||
const QskIntervalF& xBoundaries, const QVector< qreal >& xValues,
|
const QTransform& transform, const QRectF& rect,
|
||||||
const QskIntervalF& yBoundaries, const QVector< qreal >& yValues )
|
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
Q_D( QskLinesNode );
|
||||||
|
|
||||||
const auto x1 = mapX( transform, xBoundaries.lowerBound() );
|
auto& geom = d->geometry;
|
||||||
const auto x2 = mapX( transform, xBoundaries.upperBound() );
|
|
||||||
|
|
||||||
const auto y1 = mapY( transform, yBoundaries.lowerBound() );
|
const auto y1 = mapY( transform, rect.top() );
|
||||||
const auto y2 = mapY( transform, yBoundaries.upperBound() );
|
const auto y2 = mapY( transform, rect.bottom() );
|
||||||
|
|
||||||
|
const auto x1 = mapX( transform, rect.left() );
|
||||||
|
const auto x2 = mapX( transform, rect.right() );
|
||||||
|
|
||||||
|
QSGGeometry::Point2D* points = nullptr;
|
||||||
|
|
||||||
if ( stippleMetrics.isSolid() )
|
if ( stippleMetrics.isSolid() )
|
||||||
{
|
{
|
||||||
using namespace QskVertex;
|
using namespace QskVertex;
|
||||||
|
|
||||||
auto lines = allocateLines< Line >(
|
geom.allocate( 2 * ( xValues.count() + yValues.count() ) );
|
||||||
d->geometry, xValues.count() + yValues.count() );
|
points = geom.vertexDataAsPoint2D();
|
||||||
|
|
||||||
for ( auto x : xValues )
|
points = setSolidLines( Qt::Vertical, y1, y2,
|
||||||
{
|
transform, xValues.count(), xValues.constData(), points );
|
||||||
x = mapX( transform, x );
|
|
||||||
x = d->round( true, x );
|
|
||||||
|
|
||||||
lines++->setVLine( x, y1, y2 );
|
points = setSolidLines( Qt::Horizontal, x1, x2,
|
||||||
}
|
transform, yValues.count(), yValues.constData(), points );
|
||||||
|
|
||||||
for ( auto y : yValues )
|
|
||||||
{
|
|
||||||
y = mapY( transform, y );
|
|
||||||
y = d->round( false, y );
|
|
||||||
|
|
||||||
lines++->setHLine( x1, x2, y );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -279,49 +280,115 @@ void QskLinesNode::updateGeometry(
|
||||||
const int countX = stroker.pointCount( 0.0, y1, 0.0, y2 );
|
const int countX = stroker.pointCount( 0.0, y1, 0.0, y2 );
|
||||||
const int countY = stroker.pointCount( x1, 0.0, x2, 0.0 );
|
const int countY = stroker.pointCount( x1, 0.0, x2, 0.0 );
|
||||||
|
|
||||||
auto count = xValues.count() * countX + yValues.count() * countY;
|
d->geometry.allocate( xValues.count() * countX + yValues.count() * countY );
|
||||||
|
points = d->geometry.vertexDataAsPoint2D();
|
||||||
|
|
||||||
d->geometry.allocate( count );
|
points = setStippledLines( Qt::Vertical, y1, y2,
|
||||||
auto points = d->geometry.vertexDataAsPoint2D();
|
transform, xValues.count(), xValues.constData(),
|
||||||
|
stippleMetrics, points );
|
||||||
|
|
||||||
/*
|
points = setStippledLines( Qt::Horizontal, x1, x2,
|
||||||
We have to calculate the first line only. All others are
|
transform, yValues.count(), yValues.constData(),
|
||||||
translation without changing the positions of the dashes.
|
stippleMetrics, points );
|
||||||
*/
|
}
|
||||||
auto p0 = points;
|
|
||||||
|
|
||||||
for ( int i = 0; i < xValues.count(); i++ )
|
Q_ASSERT( geom.vertexCount() == ( points - geom.vertexDataAsPoint2D() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
|
Qt::Orientation orientation, qreal v1, qreal v2,
|
||||||
|
const QTransform& transform, int count, const qreal* values,
|
||||||
|
const QskStippleMetrics& stippleMetrics, QSGGeometry::Point2D* points ) const
|
||||||
{
|
{
|
||||||
auto x = mapX( transform, xValues[i] );
|
Q_D( const QskLinesNode );
|
||||||
|
|
||||||
|
if ( count <= 0 )
|
||||||
|
return points;
|
||||||
|
|
||||||
|
DashStroker stroker( stippleMetrics );
|
||||||
|
|
||||||
|
// Calculating the dashes for the first line
|
||||||
|
|
||||||
|
const auto line0 = points;
|
||||||
|
int dashCount = 0;
|
||||||
|
|
||||||
|
if ( orientation == Qt::Vertical )
|
||||||
|
{
|
||||||
|
auto x = mapX( transform, values[0] );
|
||||||
x = d->round( true, x );
|
x = d->round( true, x );
|
||||||
|
|
||||||
if ( i == 0 )
|
points = stroker.addDashes( points, x, v1, x, v2 );
|
||||||
{
|
dashCount = points - line0;
|
||||||
points = stroker.addDashes( points, x, y1, x, y2 );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( int j = 0; j < countX; j++ )
|
auto y = mapY( transform, values[0] );
|
||||||
points++->set( x, p0[j].y );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p0 = points;
|
|
||||||
|
|
||||||
for ( int i = 0; i < yValues.count(); i++ )
|
|
||||||
{
|
|
||||||
auto y = mapY( transform, yValues[i] );
|
|
||||||
y = d->round( false, y );
|
y = d->round( false, y );
|
||||||
|
|
||||||
if ( i == 0 )
|
points = stroker.addDashes( points, v1, y, v2, y );
|
||||||
|
dashCount = points - line0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all other dashes are translations of the dashes of the first line
|
||||||
|
|
||||||
|
if ( orientation == Qt::Vertical )
|
||||||
{
|
{
|
||||||
points = stroker.addDashes( points, x1, y, x2, y );
|
for ( int i = 1; i < count; i++ )
|
||||||
|
{
|
||||||
|
auto x = mapX( transform, values[i] );
|
||||||
|
x = d->round( true, x );
|
||||||
|
|
||||||
|
for ( int j = 0; j < dashCount; j++ )
|
||||||
|
points++->set( x, line0[j].y );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( int j = 0; j < countY; j++ )
|
for ( int i = 1; i < count; i++ )
|
||||||
points++->set( p0[j].x, y );
|
{
|
||||||
|
auto y = mapY( transform, values[i] );
|
||||||
|
y = d->round( false, y );
|
||||||
|
|
||||||
|
for ( int j = 0; j < dashCount; j++ )
|
||||||
|
points++->set( line0[j].x, y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGGeometry::Point2D* QskLinesNode::setSolidLines(
|
||||||
|
Qt::Orientation orientation, qreal v1, qreal v2,
|
||||||
|
const QTransform& transform, int count, const qreal* values,
|
||||||
|
QSGGeometry::Point2D* points ) const
|
||||||
|
{
|
||||||
|
Q_D( const QskLinesNode );
|
||||||
|
|
||||||
|
if ( count <= 0 )
|
||||||
|
return points;
|
||||||
|
|
||||||
|
auto lines = reinterpret_cast< QskVertex::Line* >( points );
|
||||||
|
|
||||||
|
if ( orientation == Qt::Vertical )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
auto x = mapX( transform, values[i] );
|
||||||
|
x = d->round( true, x );
|
||||||
|
|
||||||
|
lines++->setVLine( x, v1, v2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
auto y = mapY( transform, values[i] );
|
||||||
|
y = d->round( false, y );
|
||||||
|
|
||||||
|
lines++->setHLine( v1, v2, y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast< QSGGeometry::Point2D* >( lines );
|
||||||
|
}
|
||||||
|
|
|
@ -32,19 +32,27 @@ class QSK_EXPORT QskLinesNode : public QSGGeometryNode
|
||||||
void setGlobalPosition( const QPointF&, qreal devicePixelRatio );
|
void setGlobalPosition( const QPointF&, qreal devicePixelRatio );
|
||||||
void setGlobalPosition( const QQuickItem* );
|
void setGlobalPosition( const QQuickItem* );
|
||||||
|
|
||||||
void setLineColor( const QColor& );
|
void updateLines( const QColor&, qreal lineWidth,
|
||||||
void setLineWidth( qreal );
|
const QskStippleMetrics&, const QTransform&, const QRectF&,
|
||||||
|
const QVector< qreal >&, const QVector< qreal >& );
|
||||||
|
|
||||||
void updateGrid( const QColor&, qreal lineWidth,
|
void updateLines( const QColor&, qreal lineWidth,
|
||||||
const QskStippleMetrics&, const QTransform&,
|
const QskStippleMetrics&, const QTransform&, const QRectF& );
|
||||||
const QskIntervalF&, const QVector< qreal >&,
|
|
||||||
const QskIntervalF&, const QVector< qreal >& );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateGeometry(
|
void updateGeometry(
|
||||||
const QskStippleMetrics&, const QTransform&,
|
const QskStippleMetrics&, const QTransform&, const QRectF&,
|
||||||
const QskIntervalF&, const QVector< qreal >&,
|
const QVector< qreal >&, const QVector< qreal >& );
|
||||||
const QskIntervalF&, const QVector< qreal >& );
|
|
||||||
|
QSGGeometry::Point2D* setSolidLines(
|
||||||
|
Qt::Orientation, qreal, qreal,
|
||||||
|
const QTransform&, int count, const qreal* values,
|
||||||
|
QSGGeometry::Point2D* ) const;
|
||||||
|
|
||||||
|
QSGGeometry::Point2D* setStippledLines(
|
||||||
|
Qt::Orientation, qreal, qreal,
|
||||||
|
const QTransform&, int count, const qreal* values,
|
||||||
|
const QskStippleMetrics&, QSGGeometry::Point2D* ) const;
|
||||||
|
|
||||||
Q_DECLARE_PRIVATE( QskLinesNode )
|
Q_DECLARE_PRIVATE( QskLinesNode )
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue