working towards introducing new type of gradients

This commit is contained in:
Uwe Rathmann 2022-10-25 18:17:21 +02:00
parent 5712873f21
commit 506dd4f60c
3 changed files with 82 additions and 85 deletions

View File

@ -64,6 +64,10 @@ class QSK_EXPORT QskGradient
void setOrientation( Orientation ) noexcept; void setOrientation( Orientation ) noexcept;
Orientation orientation() const noexcept; Orientation orientation() const noexcept;
bool isHorizontal() const noexcept;
bool isVertical() const noexcept;
bool isTilted() const noexcept;
bool isValid() const noexcept; bool isValid() const noexcept;
bool isMonochrome() const noexcept; bool isMonochrome() const noexcept;
bool isVisible() const noexcept; bool isVisible() const noexcept;
@ -143,6 +147,21 @@ inline QskGradient::Orientation QskGradient::orientation() const noexcept
return m_orientation; return m_orientation;
} }
inline bool QskGradient::isHorizontal() const noexcept
{
return orientation() == Horizontal;
}
inline bool QskGradient::isVertical() const noexcept
{
return orientation() == Vertical;
}
inline bool QskGradient::isTilted() const noexcept
{
return orientation() == Diagonal;
}
inline const QskGradientStops& QskGradient::stops() const noexcept inline const QskGradientStops& QskGradient::stops() const noexcept
{ {
#if 1 #if 1

View File

@ -870,7 +870,7 @@ namespace
static inline Qt::Orientation qskQtOrientation( const QskGradient& gradient ) static inline Qt::Orientation qskQtOrientation( const QskGradient& gradient )
{ {
return ( gradient.orientation() == QskGradient::Vertical ) ? Qt::Vertical : Qt::Horizontal; return gradient.isVertical() ? Qt::Vertical : Qt::Horizontal;
} }
static inline int qskFillLineCount( static inline int qskFillLineCount(
@ -883,65 +883,56 @@ static inline int qskFillLineCount(
int lineCount = 0; int lineCount = 0;
switch ( gradient.orientation() ) if ( gradient.isTilted() )
{ {
case QskGradient::Diagonal: lineCount += 2 * ( stepCount + 1 );
{
lineCount += 2 * ( stepCount + 1 );
if ( metrics.centerQuad.left >= metrics.centerQuad.right ) if ( metrics.centerQuad.left >= metrics.centerQuad.right )
lineCount--; lineCount--;
if ( metrics.centerQuad.top >= metrics.centerQuad.bottom ) if ( metrics.centerQuad.top >= metrics.centerQuad.bottom )
lineCount--; lineCount--;
/* /*
For diagonal lines the points at the opposite For diagonal lines the points at the opposite
side are no points interpolating the outline. side are no points interpolating the outline.
So we need to insert interpolating lines on both sides So we need to insert interpolating lines on both sides
*/ */
lineCount *= 2; // a real ellipse could be done with lineCount lines: TODO ... lineCount *= 2; // a real ellipse could be done with lineCount lines: TODO ...
#if 1 #if 1
/* /*
The termination of the fill algorithm is a bit random The termination of the fill algorithm is a bit random
and might result in having an additional line. and might result in having an additional line.
Until this effect is completely understood, we better Until this effect is completely understood, we better
reserve memory for this to avoid crashes. reserve memory for this to avoid crashes.
*/ */
lineCount++; // happens in a corner case - needs to be understood: TODO lineCount++; // happens in a corner case - needs to be understood: TODO
#endif #endif
}
else if ( gradient.isVertical() )
{
lineCount += qMax( metrics.corner[ TopLeft ].stepCount,
metrics.corner[ TopRight ].stepCount ) + 1;
break; lineCount += qMax( metrics.corner[ BottomLeft ].stepCount,
} metrics.corner[ BottomRight ].stepCount ) + 1;
case QskGradient::Vertical:
{
lineCount += qMax( metrics.corner[ TopLeft ].stepCount,
metrics.corner[ TopRight ].stepCount ) + 1;
lineCount += qMax( metrics.corner[ BottomLeft ].stepCount, if ( metrics.centerQuad.top >= metrics.centerQuad.bottom )
metrics.corner[ BottomRight ].stepCount ) + 1; lineCount--;
}
else if ( gradient.isHorizontal() )
{
lineCount += qMax( metrics.corner[ TopLeft ].stepCount,
metrics.corner[ BottomLeft ].stepCount ) + 1;
if ( metrics.centerQuad.top >= metrics.centerQuad.bottom ) lineCount += qMax( metrics.corner[ TopRight ].stepCount,
lineCount--; metrics.corner[ BottomRight ].stepCount ) + 1;
break; if ( metrics.centerQuad.left >= metrics.centerQuad.right )
} lineCount--;
case QskGradient::Horizontal:
{
lineCount += qMax( metrics.corner[ TopLeft ].stepCount,
metrics.corner[ BottomLeft ].stepCount ) + 1;
lineCount += qMax( metrics.corner[ TopRight ].stepCount,
metrics.corner[ BottomRight ].stepCount ) + 1;
if ( metrics.centerQuad.left >= metrics.centerQuad.right )
lineCount--;
break;
}
} }
// adding vertexes for the stops - beside the first/last // adding vertexes for the stops - beside the first/last
@ -1117,7 +1108,7 @@ static inline void qskRenderFillOrdered(
implemented TODO ... implemented TODO ...
*/ */
if ( gradient.orientation() == QskGradient::Horizontal ) if ( gradient.isHorizontal() )
{ {
HRectEllipseIterator it( metrics ); HRectEllipseIterator it( metrics );
QskVertex::fillOrdered( it, r.left, r.right, gradient, lines ); QskVertex::fillOrdered( it, r.left, r.right, gradient, lines );
@ -1360,7 +1351,7 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
#if 1 #if 1
// code copied from QskBoxRendererRect.cpp TODO ... // code copied from QskBoxRendererRect.cpp TODO ...
if ( gradient.orientation() == QskGradient::Diagonal ) if ( gradient.isTilted() )
{ {
if ( metrics.centerQuad.width == metrics.centerQuad.height ) if ( metrics.centerQuad.width == metrics.centerQuad.height )
{ {
@ -1403,8 +1394,7 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
bool extraLine = false; bool extraLine = false;
if ( borderLineCount > 0 && fillLineCount > 0 ) if ( borderLineCount > 0 && fillLineCount > 0 )
{ {
if ( !gradient.isMonochrome() && if ( !gradient.isMonochrome() && gradient.isTilted() )
( gradient.orientation() == QskGradient::Diagonal ) )
{ {
/* /*
The filling ends at 45° and we have no implementation The filling ends at 45° and we have no implementation
@ -1427,11 +1417,8 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
} }
else if ( !gradient.isMonochrome() ) else if ( !gradient.isMonochrome() )
{ {
if ( gradient.stepCount() > 1 || if ( gradient.stepCount() > 1 || gradient.isTilted() )
gradient.orientation() == QskGradient::Diagonal )
{
fillRandom = false; fillRandom = false;
}
} }
if ( fillRandom ) if ( fillRandom )
@ -1460,7 +1447,7 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
{ {
renderRectFill( metrics.innerQuad, gradient, line ); renderRectFill( metrics.innerQuad, gradient, line );
} }
else if ( gradient.orientation() == QskGradient::Diagonal ) else if ( gradient.isTilted() )
{ {
renderDiagonalFill( metrics, gradient, fillLineCount, line ); renderDiagonalFill( metrics, gradient, fillLineCount, line );
} }
@ -1496,7 +1483,7 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
{ {
renderRectFill( metrics.innerQuad, gradient, line ); renderRectFill( metrics.innerQuad, gradient, line );
} }
else if ( gradient.orientation() == QskGradient::Diagonal ) else if ( gradient.isTilted() )
{ {
renderDiagonalFill( metrics, gradient, fillLineCount, line ); renderDiagonalFill( metrics, gradient, fillLineCount, line );
} }

View File

@ -345,36 +345,27 @@ namespace
static inline void qskCreateFillOrdered( const QskBoxRenderer::Quad& rect, static inline void qskCreateFillOrdered( const QskBoxRenderer::Quad& rect,
const QskGradient& gradient, ColoredLine* line ) const QskGradient& gradient, ColoredLine* line )
{ {
switch ( gradient.orientation() ) if ( gradient.isHorizontal() )
{ {
case QskGradient::Horizontal: HRectIterator it( rect );
line = QskVertex::fillOrdered( it, rect.left, rect.right, gradient, line );
}
else if ( gradient.isVertical() )
{
VRectIterator it( rect );
line = QskVertex::fillOrdered( it, rect.top, rect.bottom, gradient, line );
}
else
{
if ( rect.width == rect.height )
{ {
HRectIterator it( rect ); DSquareIterator it( rect );
line = QskVertex::fillOrdered( it, rect.left, rect.right, gradient, line ); line = QskVertex::fillOrdered( it, 0.0, 1.0, gradient, line );
break;
} }
case QskGradient::Vertical: else
{ {
VRectIterator it( rect ); DRectIterator it( rect );
line = QskVertex::fillOrdered( it, rect.top, rect.bottom, gradient, line ); line = QskVertex::fillOrdered( it, 0.0, 1.0, gradient, line );
break;
}
case QskGradient::Diagonal:
{
if ( rect.width == rect.height )
{
DSquareIterator it( rect );
line = QskVertex::fillOrdered( it, 0.0, 1.0, gradient, line );
}
else
{
DRectIterator it( rect );
line = QskVertex::fillOrdered( it, 0.0, 1.0, gradient, line );
}
break;
} }
} }
} }
@ -578,7 +569,7 @@ void QskBoxRenderer::renderRect(
{ {
fillLineCount = gradient.stepCount() + 1; fillLineCount = gradient.stepCount() + 1;
if ( gradient.orientation() == QskGradient::Diagonal ) if ( gradient.isTilted() )
{ {
if ( in.width == in.height ) if ( in.width == in.height )
{ {
@ -645,7 +636,7 @@ void QskBoxRenderer::renderRect(
but we didn't implement a random fill algo for but we didn't implement a random fill algo for
diagonal gradients yet. diagonal gradients yet.
*/ */
fillRandom = gd.orientation() != QskGradient::Diagonal; fillRandom = !gd.isTilted();
} }
if ( fillRandom ) if ( fillRandom )