QskBoxRenderer improvements
This commit is contained in:
parent
4bd294f72c
commit
21e1206b2d
|
@ -205,44 +205,77 @@ namespace QskVertex
|
||||||
Color m_color1, m_color2;
|
Color m_color1, m_color2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline ColoredLine* fillUp( ColoredLine* lines, const ColoredLine& l, int count )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < count; i++ )
|
||||||
|
*lines++ = l;
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
template< class ContourIterator, class ColorIterator >
|
template< class ContourIterator, class ColorIterator >
|
||||||
ColoredLine* fillOrdered( ContourIterator& contourIt,
|
ColoredLine* fillOrdered( ContourIterator& contourIt,
|
||||||
ColorIterator& colorIt, ColoredLine* line )
|
ColorIterator& colorIt, int lineCount, ColoredLine* lines )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
When the the vector exceeds [ 0.0, 1.0 ] we might have
|
||||||
|
gradient lines lying outside the contour.
|
||||||
|
This effect could be precalculated - however we might end
|
||||||
|
up difficult code with potential bugs.
|
||||||
|
|
||||||
|
So we allow the allocation code to ignore the effect by
|
||||||
|
adding duplicates of the last line.
|
||||||
|
*/
|
||||||
|
const auto value0 = contourIt.value();
|
||||||
|
ColoredLine* l = lines;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while ( !colorIt.isDone() && ( colorIt.value() < contourIt.value() ) )
|
while ( !colorIt.isDone() && ( colorIt.value() < contourIt.value() ) )
|
||||||
{
|
{
|
||||||
if ( contourIt.setGradientLine( colorIt.value(), colorIt.color(), line ) )
|
const auto value = colorIt.value();
|
||||||
line++;
|
|
||||||
|
/*
|
||||||
|
When having a gradient vector below 0.0 we
|
||||||
|
will have gradient lines outside of the contour
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( value > value0 )
|
||||||
|
contourIt.setGradientLine( value, colorIt.color(), l++ );
|
||||||
|
|
||||||
colorIt.advance();
|
colorIt.advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto color = colorIt.colorAt( contourIt.value() );
|
const auto color = colorIt.colorAt( contourIt.value() );
|
||||||
contourIt.setContourLine( color, line++ );
|
contourIt.setContourLine( color, l++ );
|
||||||
|
|
||||||
} while ( contourIt.advance() );
|
} while ( contourIt.advance() );
|
||||||
|
|
||||||
return line;
|
if ( lineCount >= 0 )
|
||||||
|
{
|
||||||
|
if ( const auto count = lineCount - ( l - lines ) )
|
||||||
|
l = QskVertex::fillUp( l, *( l - 1 ), count );
|
||||||
|
}
|
||||||
|
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class ContourIterator >
|
template< class ContourIterator >
|
||||||
ColoredLine* fillOrdered( ContourIterator& contourIt,
|
ColoredLine* fillOrdered( ContourIterator& contourIt,
|
||||||
const QskGradient& gradient, ColoredLine* line )
|
const QskGradient& gradient, int lineCount, ColoredLine* lines )
|
||||||
{
|
{
|
||||||
if ( gradient.stepCount() == 1 )
|
if ( gradient.stepCount() == 1 )
|
||||||
{
|
{
|
||||||
SimpleColorIterator colorIt( gradient.rgbStart(), gradient.rgbEnd() );
|
SimpleColorIterator colorIt( gradient.rgbStart(), gradient.rgbEnd() );
|
||||||
line = fillOrdered( contourIt, colorIt, line );
|
lines = fillOrdered( contourIt, colorIt, lineCount, lines );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GradientColorIterator colorIt( gradient.stops() );
|
GradientColorIterator colorIt( gradient.stops() );
|
||||||
line = fillOrdered( contourIt, colorIt, line );
|
lines = fillOrdered( contourIt, colorIt, lineCount, lines );
|
||||||
}
|
}
|
||||||
|
|
||||||
return line;
|
return lines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -610,7 +610,7 @@ void QskRoundedRectRenderer::renderDiagonalFill( const QskRoundedRectRenderer::M
|
||||||
const ValueCurve curve( metrics );
|
const ValueCurve curve( metrics );
|
||||||
|
|
||||||
DRectellipseIterator it( metrics, curve );
|
DRectellipseIterator it( metrics, curve );
|
||||||
auto line = QskVertex::fillOrdered( it, gradient, lines );
|
auto line = QskVertex::fillOrdered( it, gradient, -1, lines );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
There are a couple of reasons, why less points have been rendered
|
There are a couple of reasons, why less points have been rendered
|
||||||
|
|
|
@ -132,9 +132,6 @@ namespace
|
||||||
|
|
||||||
inline bool setGradientLine( qreal value, Color color, ColoredLine* line )
|
inline bool setGradientLine( qreal value, Color color, ColoredLine* line )
|
||||||
{
|
{
|
||||||
if ( value <= m_corners[0].value || value >= m_corners[3].value )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const qreal m = m_v.dy / m_v.dx;
|
const qreal m = m_v.dy / m_v.dx;
|
||||||
|
|
||||||
const qreal x = m_v.x + m_v.dx * value;
|
const qreal x = m_v.x + m_v.dx * value;
|
||||||
|
@ -253,19 +250,19 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
static ColoredLine* qskAddFillLines( const Quad& rect,
|
static ColoredLine* qskAddFillLines( const Quad& rect,
|
||||||
const QskGradient& gradient, ColoredLine* line )
|
const QskGradient& gradient, int lineCount, ColoredLine* line )
|
||||||
{
|
{
|
||||||
const auto dir = gradient.linearDirection();
|
const auto dir = gradient.linearDirection();
|
||||||
|
|
||||||
if ( dir.isTilted() )
|
if ( dir.isTilted() )
|
||||||
{
|
{
|
||||||
DRectIterator it( rect, dir.vector() );
|
DRectIterator it( rect, dir.vector() );
|
||||||
line = QskVertex::fillOrdered( it, gradient, line );
|
line = QskVertex::fillOrdered( it, gradient, lineCount, line );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HVRectIterator it( rect, dir.vector() );
|
HVRectIterator it( rect, dir.vector() );
|
||||||
line = QskVertex::fillOrdered( it, gradient, line );
|
line = QskVertex::fillOrdered( it, gradient, lineCount, line );
|
||||||
}
|
}
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
|
@ -410,9 +407,9 @@ void QskRectRenderer::renderBorder( const QRectF& rect,
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskRectRenderer::renderFill0( const QskVertex::Quad& rect,
|
void QskRectRenderer::renderFill0( const QskVertex::Quad& rect,
|
||||||
const QskGradient& gradient, QskVertex::ColoredLine* line )
|
const QskGradient& gradient, int lineCount, QskVertex::ColoredLine* line )
|
||||||
{
|
{
|
||||||
qskAddFillLines( rect, gradient, line );
|
qskAddFillLines( rect, gradient, lineCount, line );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskRectRenderer::renderFill( const QRectF& rect,
|
void QskRectRenderer::renderFill( const QRectF& rect,
|
||||||
|
@ -477,10 +474,10 @@ void QskRectRenderer::renderRect( const QRectF& rect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto line = allocateLines< ColoredLine >(
|
const auto lines = allocateLines< ColoredLine >(
|
||||||
geometry, borderLineCount + fillLineCount );
|
geometry, borderLineCount + fillLineCount );
|
||||||
|
|
||||||
auto l = line;
|
auto l = lines;
|
||||||
|
|
||||||
if ( fillLineCount > 0 )
|
if ( fillLineCount > 0 )
|
||||||
{
|
{
|
||||||
|
@ -493,12 +490,14 @@ void QskRectRenderer::renderRect( const QRectF& rect,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( gradient.stepCount() <= 1 && !gradient.linearDirection().isTilted() )
|
const auto dir = gradient.linearDirection();
|
||||||
|
|
||||||
|
if ( gradient.stepCount() <= 1 && !dir.isTilted() )
|
||||||
{
|
{
|
||||||
const auto c1 = gradient.rgbStart();
|
const auto c1 = gradient.rgbStart();
|
||||||
const auto c2 = gradient.rgbEnd();
|
const auto c2 = gradient.rgbEnd();
|
||||||
|
|
||||||
if ( gradient.linearDirection().isVertical() )
|
if ( dir.isVertical() )
|
||||||
{
|
{
|
||||||
( l++ )->setHLine( rect.left(), rect.right(), rect.top(), c1 );
|
( l++ )->setHLine( rect.left(), rect.right(), rect.top(), c1 );
|
||||||
( l++ )->setHLine( rect.left(), rect.right(), rect.bottom(), c2 );
|
( l++ )->setHLine( rect.left(), rect.right(), rect.bottom(), c2 );
|
||||||
|
@ -511,27 +510,11 @@ void QskRectRenderer::renderRect( const QRectF& rect,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
l = qskAddFillLines( in, gradient, l );
|
l = qskAddFillLines( in, gradient, fillLineCount, l );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( l < line + fillLineCount )
|
Q_ASSERT( l - lines == fillLineCount );
|
||||||
{
|
|
||||||
/*
|
|
||||||
When the the vector exceeds [ 0.0, 1.0 ] we might have
|
|
||||||
gradient lines lying outside the rectangle.
|
|
||||||
Precalculating this effect would save some memory - however
|
|
||||||
these corner cases are not worth to make the implementation
|
|
||||||
even more complicated.
|
|
||||||
So let's fill the memory with duplicates of the final
|
|
||||||
contour line instead.
|
|
||||||
*/
|
|
||||||
const auto& llast = *( l - 1 );
|
|
||||||
while ( l < line + fillLineCount )
|
|
||||||
*l++ = llast;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_ASSERT( l - line == fillLineCount );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( borderLineCount > 0 )
|
if ( borderLineCount > 0 )
|
||||||
|
@ -546,6 +529,6 @@ void QskRectRenderer::renderRect( const QRectF& rect,
|
||||||
l = qskAddBorderLines( rect, in, borderColors, l );
|
l = qskAddBorderLines( rect, in, borderColors, l );
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT( l - line == borderLineCount + fillLineCount );
|
Q_ASSERT( l - lines == borderLineCount + fillLineCount );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace QskVertex
|
||||||
namespace QskRectRenderer
|
namespace QskRectRenderer
|
||||||
{
|
{
|
||||||
void renderFill0( const QskVertex::Quad&,
|
void renderFill0( const QskVertex::Quad&,
|
||||||
const QskGradient&, QskVertex::ColoredLine* );
|
const QskGradient&, int lineCount, QskVertex::ColoredLine* );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,78 +27,6 @@ namespace
|
||||||
BottomRight = Qt::BottomRightCorner
|
BottomRight = Qt::BottomRightCorner
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArcIterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline ArcIterator() = default;
|
|
||||||
|
|
||||||
inline ArcIterator( int stepCount, bool inverted = false )
|
|
||||||
{
|
|
||||||
reset( stepCount, inverted );
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset( int stepCount, bool inverted )
|
|
||||||
{
|
|
||||||
m_inverted = inverted;
|
|
||||||
|
|
||||||
if ( inverted )
|
|
||||||
{
|
|
||||||
m_cos = 1.0;
|
|
||||||
m_sin = 0.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_cos = 0.0;
|
|
||||||
m_sin = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stepIndex = 0;
|
|
||||||
m_stepCount = stepCount;
|
|
||||||
|
|
||||||
const double angleStep = M_PI_2 / stepCount;
|
|
||||||
m_cosStep = qFastCos( angleStep );
|
|
||||||
m_sinStep = qFastSin( angleStep );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isInverted() const { return m_inverted; }
|
|
||||||
|
|
||||||
inline double cos() const { return m_cos; }
|
|
||||||
inline double sin() const { return m_inverted ? -m_sin : m_sin; }
|
|
||||||
|
|
||||||
inline int step() const { return m_stepIndex; }
|
|
||||||
inline int stepCount() const { return m_stepCount; }
|
|
||||||
inline bool isDone() const { return m_stepIndex > m_stepCount; }
|
|
||||||
|
|
||||||
inline void increment()
|
|
||||||
{
|
|
||||||
const double cos0 = m_cos;
|
|
||||||
|
|
||||||
m_cos = m_cos * m_cosStep + m_sin * m_sinStep;
|
|
||||||
m_sin = m_sin * m_cosStep - cos0 * m_sinStep;
|
|
||||||
|
|
||||||
++m_stepIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void operator++() { increment(); }
|
|
||||||
|
|
||||||
static int segmentHint( double radius )
|
|
||||||
{
|
|
||||||
const double arcLength = radius * M_PI_2;
|
|
||||||
return qBound( 3, qCeil( arcLength / 3.0 ), 18 ); // every 3 pixels
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
double m_cos;
|
|
||||||
double m_sin;
|
|
||||||
|
|
||||||
int m_stepIndex;
|
|
||||||
double m_cosStep;
|
|
||||||
double m_sinStep;
|
|
||||||
|
|
||||||
int m_stepCount;
|
|
||||||
bool m_inverted;
|
|
||||||
};
|
|
||||||
|
|
||||||
int additionalGradientStops( const QskGradient& gradient )
|
int additionalGradientStops( const QskGradient& gradient )
|
||||||
{
|
{
|
||||||
return qMax( 0, gradient.stepCount() - 1 );
|
return qMax( 0, gradient.stepCount() - 1 );
|
||||||
|
@ -205,7 +133,8 @@ namespace
|
||||||
{ return m_uniform ? m_outer[ 0 ].dy : m_outer[ pos ].dy; }
|
{ return m_uniform ? m_outer[ 0 ].dy : m_outer[ pos ].dy; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_uniform;
|
const bool m_uniform;
|
||||||
|
|
||||||
class Values
|
class Values
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -882,8 +811,6 @@ static inline Qt::Orientation qskQtOrientation( const QskGradient& gradient )
|
||||||
static inline int qskFillLineCount(
|
static inline int qskFillLineCount(
|
||||||
const QskRoundedRectRenderer::Metrics& metrics, const QskGradient& gradient )
|
const QskRoundedRectRenderer::Metrics& metrics, const QskGradient& gradient )
|
||||||
{
|
{
|
||||||
const int stepCount = metrics.corner[ 0 ].stepCount;
|
|
||||||
|
|
||||||
if ( !gradient.isVisible() )
|
if ( !gradient.isVisible() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -915,7 +842,7 @@ static inline int qskFillLineCount(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lineCount += 2 * ( stepCount + 1 );
|
lineCount += 2 * ( metrics.corner[ 0 ].stepCount + 1 );
|
||||||
|
|
||||||
if ( metrics.centerQuad.left >= metrics.centerQuad.right )
|
if ( metrics.centerQuad.left >= metrics.centerQuad.right )
|
||||||
lineCount--;
|
lineCount--;
|
||||||
|
@ -1111,7 +1038,7 @@ static inline void qskRenderBoxRandom(
|
||||||
|
|
||||||
static inline void qskRenderFillOrdered(
|
static inline void qskRenderFillOrdered(
|
||||||
const QskRoundedRectRenderer::Metrics& metrics,
|
const QskRoundedRectRenderer::Metrics& metrics,
|
||||||
const QskGradient& gradient, ColoredLine* lines )
|
const QskGradient& gradient, int lineCount, ColoredLine* lines )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
The algo for irregular radii at opposite corners is not yet
|
The algo for irregular radii at opposite corners is not yet
|
||||||
|
@ -1121,12 +1048,12 @@ static inline void qskRenderFillOrdered(
|
||||||
if ( gradient.linearDirection().isHorizontal() )
|
if ( gradient.linearDirection().isHorizontal() )
|
||||||
{
|
{
|
||||||
HRectEllipseIterator it( metrics );
|
HRectEllipseIterator it( metrics );
|
||||||
QskVertex::fillOrdered( it, gradient, lines );
|
QskVertex::fillOrdered( it, gradient, lineCount, lines );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VRectEllipseIterator it( metrics );
|
VRectEllipseIterator it( metrics );
|
||||||
QskVertex::fillOrdered( it, gradient, lines );
|
QskVertex::fillOrdered( it, gradient, lineCount, lines );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1434,6 +1361,7 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
QSGGeometry& geometry )
|
QSGGeometry& geometry )
|
||||||
{
|
{
|
||||||
const Metrics metrics( rect, shape, border );
|
const Metrics metrics( rect, shape, border );
|
||||||
|
const auto isTilted = gradient.linearDirection().isTilted();
|
||||||
|
|
||||||
int fillLineCount = 0;
|
int fillLineCount = 0;
|
||||||
|
|
||||||
|
@ -1446,7 +1374,7 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
fillLineCount = gradient.stepCount() + 1;
|
fillLineCount = gradient.stepCount() + 1;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if ( gradient.linearDirection().isTilted() )
|
if ( isTilted )
|
||||||
{
|
{
|
||||||
if ( metrics.centerQuad.width == metrics.centerQuad.height )
|
if ( metrics.centerQuad.width == metrics.centerQuad.height )
|
||||||
{
|
{
|
||||||
|
@ -1489,7 +1417,7 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
bool extraLine = false;
|
bool extraLine = false;
|
||||||
if ( borderLineCount > 0 && fillLineCount > 0 )
|
if ( borderLineCount > 0 && fillLineCount > 0 )
|
||||||
{
|
{
|
||||||
if ( !gradient.isMonochrome() && gradient.linearDirection().isTilted() )
|
if ( !gradient.isMonochrome() && isTilted )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
The filling ends at 45° and we have no implementation
|
The filling ends at 45° and we have no implementation
|
||||||
|
@ -1501,7 +1429,7 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto line = allocateLines< ColoredLine >( geometry, lineCount );
|
auto lines = allocateLines< ColoredLine >( geometry, lineCount );
|
||||||
|
|
||||||
bool fillRandom = true;
|
bool fillRandom = true;
|
||||||
if ( fillLineCount > 0 )
|
if ( fillLineCount > 0 )
|
||||||
|
@ -1512,7 +1440,7 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
}
|
}
|
||||||
else if ( !gradient.isMonochrome() )
|
else if ( !gradient.isMonochrome() )
|
||||||
{
|
{
|
||||||
if ( gradient.stepCount() > 1 || gradient.linearDirection().isTilted() )
|
if ( gradient.stepCount() > 1 || isTilted )
|
||||||
fillRandom = false;
|
fillRandom = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1534,24 +1462,25 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
if ( fillRandom )
|
if ( fillRandom )
|
||||||
{
|
{
|
||||||
qskRenderBoxRandom( metrics, borderColors,
|
qskRenderBoxRandom( metrics, borderColors,
|
||||||
gradient, line, line + fillLineCount );
|
gradient, lines, lines + fillLineCount );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( metrics.isTotallyCropped )
|
if ( metrics.isTotallyCropped )
|
||||||
{
|
{
|
||||||
QskRectRenderer::renderFill0( metrics.innerQuad, gradient, line );
|
QskRectRenderer::renderFill0( metrics.innerQuad,
|
||||||
|
gradient, fillLineCount, lines );
|
||||||
}
|
}
|
||||||
else if ( gradient.linearDirection().isTilted() )
|
else if ( isTilted )
|
||||||
{
|
{
|
||||||
renderDiagonalFill( metrics, gradient, fillLineCount, line );
|
renderDiagonalFill( metrics, gradient, fillLineCount, lines );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qskRenderFillOrdered( metrics, gradient, line );
|
qskRenderFillOrdered( metrics, gradient, fillLineCount, lines );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto borderLines = line + fillLineCount;
|
auto borderLines = lines + fillLineCount;
|
||||||
if ( extraLine )
|
if ( extraLine )
|
||||||
borderLines++;
|
borderLines++;
|
||||||
|
|
||||||
|
@ -1560,7 +1489,7 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
|
|
||||||
if ( extraLine )
|
if ( extraLine )
|
||||||
{
|
{
|
||||||
const auto l = line + fillLineCount;
|
const auto l = lines + fillLineCount;
|
||||||
l[ 0 ].p1 = l[ -1 ].p2;
|
l[ 0 ].p1 = l[ -1 ].p2;
|
||||||
l[ 0 ].p2 = l[ 1 ].p1;
|
l[ 0 ].p2 = l[ 1 ].p1;
|
||||||
}
|
}
|
||||||
|
@ -1570,21 +1499,22 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
{
|
{
|
||||||
if ( fillRandom )
|
if ( fillRandom )
|
||||||
{
|
{
|
||||||
qskRenderFillRandom( metrics, gradient, line );
|
qskRenderFillRandom( metrics, gradient, lines );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( metrics.isTotallyCropped )
|
if ( metrics.isTotallyCropped )
|
||||||
{
|
{
|
||||||
QskRectRenderer::renderFill0( metrics.innerQuad, gradient, line );
|
QskRectRenderer::renderFill0( metrics.innerQuad,
|
||||||
|
gradient, fillLineCount, lines );
|
||||||
}
|
}
|
||||||
else if ( gradient.linearDirection().isTilted() )
|
else if ( isTilted )
|
||||||
{
|
{
|
||||||
renderDiagonalFill( metrics, gradient, fillLineCount, line );
|
renderDiagonalFill( metrics, gradient, fillLineCount, lines );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qskRenderFillOrdered( metrics, gradient, line );
|
qskRenderFillOrdered( metrics, gradient, fillLineCount, lines );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1596,6 +1526,6 @@ void QskRoundedRectRenderer::renderRectellipse( const QRectF& rect,
|
||||||
border colors, we could treat it like filling without border. TODO ...
|
border colors, we could treat it like filling without border. TODO ...
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
qskRenderBorder( metrics, Qt::Vertical, borderColors, line );
|
qskRenderBorder( metrics, Qt::Vertical, borderColors, lines );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <qcolor.h>
|
#include <qcolor.h>
|
||||||
#include <qsggeometry.h>
|
#include <qsggeometry.h>
|
||||||
|
#include <qmath.h>
|
||||||
|
|
||||||
namespace QskVertex
|
namespace QskVertex
|
||||||
{
|
{
|
||||||
|
@ -213,6 +214,81 @@ namespace QskVertex
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class ArcIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline ArcIterator() = default;
|
||||||
|
|
||||||
|
inline ArcIterator( int stepCount, bool inverted = false )
|
||||||
|
{
|
||||||
|
reset( stepCount, inverted );
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset( int stepCount, bool inverted )
|
||||||
|
{
|
||||||
|
m_inverted = inverted;
|
||||||
|
|
||||||
|
if ( inverted )
|
||||||
|
{
|
||||||
|
m_cos = 1.0;
|
||||||
|
m_sin = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cos = 0.0;
|
||||||
|
m_sin = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stepIndex = 0;
|
||||||
|
m_stepCount = stepCount;
|
||||||
|
|
||||||
|
const double angleStep = M_PI_2 / stepCount;
|
||||||
|
m_cosStep = qFastCos( angleStep );
|
||||||
|
m_sinStep = qFastSin( angleStep );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isInverted() const { return m_inverted; }
|
||||||
|
|
||||||
|
inline double cos() const { return m_cos; }
|
||||||
|
inline double sin() const { return m_inverted ? -m_sin : m_sin; }
|
||||||
|
|
||||||
|
inline int step() const { return m_stepIndex; }
|
||||||
|
inline int stepCount() const { return m_stepCount; }
|
||||||
|
inline bool isDone() const { return m_stepIndex > m_stepCount; }
|
||||||
|
|
||||||
|
inline void increment()
|
||||||
|
{
|
||||||
|
const double cos0 = m_cos;
|
||||||
|
|
||||||
|
m_cos = m_cos * m_cosStep + m_sin * m_sinStep;
|
||||||
|
m_sin = m_sin * m_cosStep - cos0 * m_sinStep;
|
||||||
|
|
||||||
|
++m_stepIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator++() { increment(); }
|
||||||
|
|
||||||
|
static int segmentHint( double radius )
|
||||||
|
{
|
||||||
|
const double arcLength = radius * M_PI_2;
|
||||||
|
return qBound( 3, qCeil( arcLength / 3.0 ), 18 ); // every 3 pixels
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_cos;
|
||||||
|
double m_sin;
|
||||||
|
|
||||||
|
int m_stepIndex;
|
||||||
|
double m_cosStep;
|
||||||
|
double m_sinStep;
|
||||||
|
|
||||||
|
int m_stepCount;
|
||||||
|
bool m_inverted;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace QskVertex
|
namespace QskVertex
|
||||||
{
|
{
|
||||||
void debugGeometry( const QSGGeometry& );
|
void debugGeometry( const QSGGeometry& );
|
||||||
|
|
Loading…
Reference in New Issue