allowing gradient stops that do not start/end with 0.0/1.0 ( like
QGradient )
This commit is contained in:
parent
1f28eec9de
commit
e67b0b385a
@ -31,10 +31,10 @@ static inline QskGradient::Orientation qskOrientation( Qt::Orientation o )
|
||||
|
||||
static inline bool qskIsGradientValid( const QskGradientStops& stops )
|
||||
{
|
||||
if ( stops.size() < 2 )
|
||||
if ( stops.isEmpty() )
|
||||
return false;
|
||||
|
||||
if ( stops.first().position() != 0.0 || stops.last().position() != 1.0 )
|
||||
if ( stops.first().position() < 0.0 || stops.last().position() > 1.0 )
|
||||
return false;
|
||||
|
||||
if ( !stops.first().color().isValid() )
|
||||
@ -200,9 +200,20 @@ void QskGradient::setStops( const QskGradientStops& stops )
|
||||
m_isDirty = true;
|
||||
}
|
||||
|
||||
int QskGradient::stopCount() const noexcept
|
||||
int QskGradient::stepCount() const noexcept
|
||||
{
|
||||
return m_stops.count();
|
||||
if ( !isValid() )
|
||||
return 0;
|
||||
|
||||
int steps = m_stops.count() - 1;
|
||||
|
||||
if ( m_stops.first().position() > 0.0 )
|
||||
steps++;
|
||||
|
||||
if ( m_stops.last().position() < 1.0 )
|
||||
steps++;
|
||||
|
||||
return steps;
|
||||
}
|
||||
|
||||
qreal QskGradient::stopAt( int index ) const noexcept
|
||||
|
@ -100,7 +100,7 @@ class QSK_EXPORT QskGradient
|
||||
Q_INVOKABLE qreal stopAt( int index ) const noexcept;
|
||||
Q_INVOKABLE QColor colorAt( int index ) const noexcept;
|
||||
|
||||
Q_INVOKABLE int stopCount() const noexcept;
|
||||
int stepCount() const noexcept;
|
||||
|
||||
private:
|
||||
void updateStatusBits() const;
|
||||
|
@ -88,7 +88,6 @@ void QskBoxNode::setBoxData( const QRectF& rect,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
const auto metricsHash = qskMetricsHash( shape, borderMetrics );
|
||||
const auto colorsHash = qskColorsHash( borderColors, fillGradient );
|
||||
|
||||
@ -104,7 +103,6 @@ void QskBoxNode::setBoxData( const QRectF& rect,
|
||||
|
||||
markDirty( QSGNode::DirtyMaterial );
|
||||
markDirty( QSGNode::DirtyGeometry );
|
||||
#endif
|
||||
|
||||
if ( rect.isEmpty() )
|
||||
{
|
||||
@ -112,7 +110,7 @@ void QskBoxNode::setBoxData( const QRectF& rect,
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasFill = fillGradient.isValid();
|
||||
bool hasFill = fillGradient.isVisible();
|
||||
|
||||
bool hasBorder = !borderMetrics.isNull();
|
||||
if ( hasBorder )
|
||||
|
@ -153,16 +153,25 @@ namespace QskVertex
|
||||
, m_value2( value2 )
|
||||
, m_stops( stops )
|
||||
{
|
||||
Q_ASSERT( stops.size() > 2 );
|
||||
if ( stops.first().position() > 0.0 )
|
||||
{
|
||||
m_color1 = m_color2 = stops[ 0 ].color();
|
||||
m_index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_color1 = stops[ 0 ].color();
|
||||
m_color2 = stops[ 1 ].color();
|
||||
m_index = 1;
|
||||
}
|
||||
|
||||
m_color1 = stops[ 0 ].color();
|
||||
m_color2 = stops[ 1 ].color();
|
||||
m_finalIndex = m_stops.count() - 1;
|
||||
if ( stops.last().position() < 1.0 )
|
||||
m_finalIndex++;
|
||||
|
||||
m_valueStep1 = value1;
|
||||
m_valueStep2 = valueAt( stops[ 1 ].position() );
|
||||
m_valueStep2 = valueAt( stops[ m_index ].position() );
|
||||
m_stepSize = m_valueStep2 - m_valueStep1;
|
||||
|
||||
m_index = 1;
|
||||
}
|
||||
|
||||
inline qreal value() const
|
||||
@ -183,13 +192,24 @@ namespace QskVertex
|
||||
|
||||
inline bool advance()
|
||||
{
|
||||
const auto& stop = m_stops[ ++m_index ];
|
||||
m_index++;
|
||||
|
||||
m_color1 = m_color2;
|
||||
m_color2 = stop.color();
|
||||
|
||||
m_valueStep1 = m_valueStep2;
|
||||
m_valueStep2 = valueAt( stop.position() );
|
||||
|
||||
if ( m_index >= m_stops.count() )
|
||||
{
|
||||
m_color2 = m_color1;
|
||||
m_valueStep2 = valueAt( 1.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& stop = m_stops[ m_index ];
|
||||
|
||||
m_color2 = stop.color();
|
||||
m_valueStep2 = valueAt( stop.position() );
|
||||
}
|
||||
|
||||
m_stepSize = m_valueStep2 - m_valueStep1;
|
||||
|
||||
return !isDone();
|
||||
@ -197,7 +217,7 @@ namespace QskVertex
|
||||
|
||||
inline bool isDone() const
|
||||
{
|
||||
return m_index >= m_stops.count() - 1;
|
||||
return m_index >= m_finalIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -209,7 +229,7 @@ namespace QskVertex
|
||||
const qreal m_value1, m_value2;
|
||||
const QskGradientStops m_stops;
|
||||
|
||||
int m_index;
|
||||
int m_index, m_finalIndex;
|
||||
qreal m_valueStep1, m_valueStep2, m_stepSize;
|
||||
Color m_color1, m_color2;
|
||||
};
|
||||
@ -237,7 +257,7 @@ namespace QskVertex
|
||||
ColoredLine* fillOrdered( ContourIterator& contourIt,
|
||||
qreal value1, qreal value2, const QskGradient& gradient, ColoredLine* line )
|
||||
{
|
||||
if ( gradient.stops().size() == 2 )
|
||||
if ( gradient.stepCount() == 1 )
|
||||
{
|
||||
if ( value2 == 1.0 && value1 == 0.0 )
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ namespace
|
||||
|
||||
int additionalGradientStops( const QskGradient& gradient )
|
||||
{
|
||||
return qMax( 0, gradient.stops().count() - 2 );
|
||||
return qMax( 0, gradient.stepCount() - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,10 +575,26 @@ namespace
|
||||
|
||||
auto line = lines + additionalGradientStops( gradient );
|
||||
|
||||
{
|
||||
const auto &stop = stops.first();
|
||||
|
||||
if ( stop.position() > 0.0 )
|
||||
setAdditionalLine( x11, y11, x12, y12, dx1, dy1, dx2, dy2, stop, line-- );
|
||||
}
|
||||
|
||||
for( int i = 1; i < stops.count() - 1; i++ )
|
||||
{
|
||||
setAdditionalLine( x11, y11, x12, y12, dx1, dy1, dx2, dy2, stops[i], line-- );
|
||||
}
|
||||
|
||||
{
|
||||
const auto &stop = stops.last();
|
||||
|
||||
if ( stop.position() < 1.0 )
|
||||
{
|
||||
setAdditionalLine( x11, y11, x12, y12, dx1, dy1, dx2, dy2, stop, line-- );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class BorderMap, class FillMap >
|
||||
@ -931,7 +947,7 @@ static inline int qskFillLineCount(
|
||||
// adding vertexes for the stops - beside the first/last
|
||||
|
||||
if ( !gradient.isMonochrome() )
|
||||
lineCount += gradient.stops().size() - 2;
|
||||
lineCount += gradient.stepCount() - 1;
|
||||
|
||||
return lineCount;
|
||||
}
|
||||
@ -1339,7 +1355,7 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
|
||||
{
|
||||
// degenerated to a rectangle
|
||||
|
||||
fillLineCount = gradient.stops().count();
|
||||
fillLineCount = gradient.stepCount() + 1;
|
||||
|
||||
#if 1
|
||||
// code copied from QskBoxRendererRect.cpp TODO ...
|
||||
@ -1411,7 +1427,7 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
|
||||
}
|
||||
else if ( !gradient.isMonochrome() )
|
||||
{
|
||||
if ( gradient.stops().count() > 2 ||
|
||||
if ( gradient.stepCount() > 1 ||
|
||||
gradient.orientation() == QskGradient::Diagonal )
|
||||
{
|
||||
fillRandom = false;
|
||||
|
@ -430,6 +430,12 @@ static inline void qskCreateBorder(
|
||||
{
|
||||
const auto stops = colors.bottom().stops();
|
||||
|
||||
if ( stops.first().position() > 0.0 )
|
||||
{
|
||||
( line++ )->setLine( in.right, in.bottom,
|
||||
out.right, out.bottom, stops.first().color() );
|
||||
}
|
||||
|
||||
for( const auto& stop : stops )
|
||||
{
|
||||
const qreal x1 = in.right - stop.position() * dx1;
|
||||
@ -437,11 +443,23 @@ static inline void qskCreateBorder(
|
||||
|
||||
( line++ )->setLine( x1, in.bottom, x2, out.bottom, stop.color() );
|
||||
}
|
||||
|
||||
if ( stops.last().position() < 1.0 )
|
||||
{
|
||||
( line++ )->setLine( in.left, in.bottom,
|
||||
out.left, out.bottom, stops.last().color() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto stops = colors.left().stops();
|
||||
|
||||
if ( stops.first().position() > 0.0 )
|
||||
{
|
||||
( line++ )->setLine( in.left, in.bottom,
|
||||
out.left, out.bottom, stops.first().color() );
|
||||
}
|
||||
|
||||
for( const auto& stop : stops )
|
||||
{
|
||||
const qreal y1 = in.bottom + stop.position() * dy1;
|
||||
@ -449,11 +467,23 @@ static inline void qskCreateBorder(
|
||||
|
||||
( line++ )->setLine( in.left, y1, out.left, y2, stop.color() );
|
||||
}
|
||||
|
||||
if ( stops.last().position() < 1.0 )
|
||||
{
|
||||
( line++ )->setLine( in.left, in.top,
|
||||
out.left, out.top, stops.last().color() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto stops = colors.top().stops();
|
||||
|
||||
if ( stops.first().position() > 0.0 )
|
||||
{
|
||||
( line++ )->setLine( in.left, in.top,
|
||||
out.left, out.top, stops.first().color() );
|
||||
}
|
||||
|
||||
for( const auto& stop : stops )
|
||||
{
|
||||
const qreal x1 = in.left + stop.position() * dx1;
|
||||
@ -461,11 +491,23 @@ static inline void qskCreateBorder(
|
||||
|
||||
( line++ )->setLine( x1, in.top, x2, out.top, stop.color() );
|
||||
}
|
||||
|
||||
if ( stops.last().position() < 1.0 )
|
||||
{
|
||||
( line++ )->setLine( in.right, in.top,
|
||||
out.right, out.top, stops.last().color() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto stops = colors.right().stops();
|
||||
|
||||
if ( stops.first().position() > 0.0 )
|
||||
{
|
||||
( line++ )->setLine( in.right, in.top,
|
||||
out.right, out.top, stops.first().color() );
|
||||
}
|
||||
|
||||
for( const auto& stop : stops )
|
||||
{
|
||||
const qreal y1 = in.bottom + ( 1 - stop.position() ) * dy1;
|
||||
@ -473,6 +515,12 @@ static inline void qskCreateBorder(
|
||||
|
||||
( line++ )->setLine( in.right, y1, out.right, y2, stop.color() );
|
||||
}
|
||||
|
||||
if ( stops.last().position() < 1.0 )
|
||||
{
|
||||
( line++ )->setLine( in.right, in.bottom,
|
||||
out.right, out.bottom, stops.last().color() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -528,7 +576,7 @@ void QskBoxRenderer::renderRect(
|
||||
int fillLineCount = 0;
|
||||
if ( gradient.isVisible() && !in.isEmpty() )
|
||||
{
|
||||
fillLineCount = gradient.stops().count();
|
||||
fillLineCount = gradient.stepCount() + 1;
|
||||
|
||||
if ( gradient.orientation() == QskGradient::Diagonal )
|
||||
{
|
||||
@ -566,10 +614,10 @@ void QskBoxRenderer::renderRect(
|
||||
// ### As an optimization we could check orientation and colors
|
||||
// to test whether colors are the same
|
||||
const int additionalLines = -1
|
||||
+ bc.left().stops().count() - 1
|
||||
+ bc.top().stops().count() - 1
|
||||
+ bc.right().stops().count() - 1
|
||||
+ bc.bottom().stops().count() - 1;
|
||||
+ bc.left().stepCount()
|
||||
+ bc.top().stepCount()
|
||||
+ bc.right().stepCount()
|
||||
+ bc.bottom().stepCount();
|
||||
|
||||
borderLineCount += qMax( additionalLines, 0 );
|
||||
}
|
||||
@ -589,7 +637,7 @@ void QskBoxRenderer::renderRect(
|
||||
}
|
||||
else
|
||||
{
|
||||
bool fillRandom = gd.stops().count() <= 2;
|
||||
bool fillRandom = gd.stepCount() <= 1;
|
||||
if ( fillRandom )
|
||||
{
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user