de-template-ified: much better starting point for the fixes to come

This commit is contained in:
Uwe Rathmann 2023-01-12 20:26:51 +01:00
parent a916bd78c2
commit cd4a46cc11
5 changed files with 208 additions and 381 deletions

View File

@ -15,53 +15,6 @@ class QskBoxShapeMetrics;
namespace QskVertex namespace QskVertex
{ {
class ColorMapNone
{
public:
constexpr inline Color colorAt( qreal ) const
{
return Color();
}
};
class ColorMapSolid
{
public:
constexpr inline ColorMapSolid() = default;
inline ColorMapSolid( const QskGradient& gradient )
: m_color( gradient.rgbStart() )
{
}
inline Color colorAt( qreal ) const
{
return m_color;
}
private:
const Color m_color;
};
class ColorMapGradient
{
public:
inline ColorMapGradient( const QskGradient& gradient )
: m_color1( gradient.rgbStart() )
, m_color2( gradient.rgbEnd() )
{
}
inline Color colorAt( qreal value ) const
{
return m_color1.interpolatedTo( m_color2, value );
}
private:
const Color m_color1;
const Color m_color2;
};
class ColorIterator class ColorIterator
{ {
public: public:

View File

@ -3,34 +3,117 @@
* This file may be used under the terms of the QSkinny License, Version 1.0 * This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/ *****************************************************************************/
#ifndef QSK_SCALE_RENDERER_HPP #include "QskRoundedRect.h"
#define QSK_SCALE_RENDERER_HPP #include "QskGradient.h"
#include "QskGradientDirection.h"
#include "QskRoundedRectRenderer.h"
#include "QskBoxShapeMetrics.h" #include "QskBoxShapeMetrics.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h" #include "QskBoxBorderColors.h"
#include "QskBoxBorderMetrics.h"
#include <qsggeometry.h> namespace
inline int QskRoundedRect::additionalGradientStops( const QskGradient& gradient )
{ {
return qMax( 0, gradient.stepCount() - 1 ); Qt::Orientation orientationOf( const QskGradient& gradient )
{
if ( gradient.isMonochrome() )
return Qt::Vertical;
return gradient.linearDirection().isVertical()
? Qt::Vertical : Qt::Horizontal;
}
inline int extraStops( const QskGradient& gradient )
{
return qMax( 0, gradient.stepCount() - 1 );
}
inline void setBorderGradientLine(
const QskVertex::Line& l, float dx1, float dy1, float dx2, float dy2,
const QskGradientStop& stop, QskVertex::ColoredLine* lines )
{
const auto pos = stop.position();
const float x1 = l.p1.x + pos * dx1;
const float y1 = l.p1.y + pos * dy1;
const float x2 = l.p2.x + pos * dx2;
const float y2 = l.p2.y + pos * dy2;
lines->setLine( x1, y1, x2, y2, stop.rgb() );
}
class ColorMap
{
public:
inline ColorMap( const QskGradient& gradient )
: m_isMonochrome( gradient.isMonochrome() )
, m_color1( gradient.rgbStart() )
, m_color2( gradient.rgbEnd() )
{
}
inline QskVertex::Color colorAt( qreal value ) const
{
if ( m_isMonochrome )
return m_color1;
else
return m_color1.interpolatedTo( m_color2, value );
}
private:
const bool m_isMonochrome;
const QskVertex::Color m_color1;
const QskVertex::Color m_color2;
};
class BorderMap
{
public:
inline BorderMap( int stepCount, const QskGradient& g1, const QskGradient& g2 )
: m_stepCount( stepCount )
, m_color1( g1.rgbStart() )
, m_color2( g2.rgbEnd() )
{
}
inline QskVertex::Color colorAt( int step ) const
{
if ( m_color1 == m_color2 )
return m_color1;
else
return m_color1.interpolatedTo( m_color2, step / m_stepCount );
}
private:
const qreal m_stepCount;
const QskVertex::Color m_color1, m_color2;
};
class BorderMaps
{
public:
inline BorderMaps( int stepCount, const QskBoxBorderColors& colors )
: maps{
{ stepCount, colors.top(), colors.left() },
{ stepCount, colors.right(), colors.top() },
{ stepCount, colors.left(), colors.bottom() },
{ stepCount, colors.bottom(), colors.right() } }
{
}
const BorderMap maps[4];
};
} }
inline int QskRoundedRect::additionalGradientStops( const QskBoxBorderColors& bc ) int QskRoundedRect::extraBorderStops( const QskBoxBorderColors& bc )
{ {
return additionalGradientStops( bc.left() ) return extraStops( bc.left() ) + extraStops( bc.top() )
+ additionalGradientStops( bc.top() ) + extraStops( bc.right() ) + extraStops( bc.bottom() );
+ additionalGradientStops( bc.right() )
+ additionalGradientStops( bc.bottom() );
} }
inline QskRoundedRect::Metrics::Metrics( const QRectF& rect,
QskRoundedRect::Metrics::Metrics( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border ) const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border )
: outerQuad( rect ) : outerQuad( rect )
{ {
isRadiusRegular = shape.isRectellipse(); isRadiusRegular = shape.isRectellipse();
for ( int i = 0; i < 4; i++ ) for ( int i = 0; i < 4; i++ )
@ -174,33 +257,8 @@ inline QskRoundedRect::Metrics::Metrics( const QRectF& rect,
( borderTop == borderRight ) && ( borderTop == borderRight ) &&
( borderRight == borderBottom ); ( borderRight == borderBottom );
} }
template< class T >
inline QskRoundedRect::BorderMaps< T >::BorderMaps( const T& map )
: maps{ map, map, map, map }
{
}
template< class T > QskRoundedRect::BorderValues::BorderValues( const QskRoundedRect::Metrics& metrics )
inline QskRoundedRect::BorderMaps< T >::BorderMaps(
const T& tl, const T& tr, const T& bl, const T& br )
: maps{ tl, tr, bl, br }
{
}
template< class T >
inline int QskRoundedRect::BorderMaps< T >::extraStops( int index ) const
{
return additionalGradientStops( maps[index].gradient() );
}
template< class T >
inline int QskRoundedRect::BorderMaps< T >::extraStops() const
{
return extraStops( 0 ) + extraStops( 1 ) + extraStops( 2 ) + extraStops( 3 );
}
inline QskRoundedRect::BorderValues::BorderValues(
const QskRoundedRect::Metrics& metrics )
: m_metrics( metrics ) : m_metrics( metrics )
, m_isUniform( metrics.isBorderRegular && metrics.isRadiusRegular ) , m_isUniform( metrics.isBorderRegular && metrics.isRadiusRegular )
{ {
@ -251,7 +309,7 @@ inline QskRoundedRect::BorderValues::BorderValues(
} }
} }
inline void QskRoundedRect::BorderValues::setAngle( qreal cos, qreal sin ) void QskRoundedRect::BorderValues::setAngle( qreal cos, qreal sin )
{ {
if ( m_isUniform ) if ( m_isUniform )
{ {
@ -286,58 +344,9 @@ inline void QskRoundedRect::BorderValues::setAngle( qreal cos, qreal sin )
} }
} }
inline qreal QskRoundedRect::BorderValues::dx1( int pos ) const void QskRoundedRect::Stroker::setBorderGradientLines(
{ const BorderValues& v, int c1, const QskGradient& gradient,
return m_isUniform ? m_uniform.dx1 : m_multi.inner[ pos].dx; QskVertex::ColoredLine* lines ) const
}
inline qreal QskRoundedRect::BorderValues::dy1( int pos ) const
{
return m_isUniform ? m_uniform.dy1 : m_multi.inner[ pos ].dy;
}
inline qreal QskRoundedRect::BorderValues::dx2( int pos ) const
{
if ( m_isUniform )
return m_uniform.dx2;
const auto outer = m_multi.outer;
return m_metrics.isRadiusRegular ? outer[ 0 ].dx : outer[ pos ].dx;
}
inline qreal QskRoundedRect::BorderValues::dy2( int pos ) const
{
if ( m_isUniform )
return m_uniform.dy2;
const auto outer = m_multi.outer;
return m_metrics.isRadiusRegular ? outer[ 0 ].dy : outer[ pos ].dy;
}
template< class L >
inline QskRoundedRect::Stroker< L >::Stroker( const QskRoundedRect::Metrics& metrics )
: m_metrics( metrics )
{
}
template< class L >
inline void QskRoundedRect::Stroker< L >::setBorderGradientLine(
const QskVertex::Line& l, float dx1, float dy1, float dx2, float dy2,
const QskGradientStop& stop, L* line ) const
{
const auto pos = stop.position();
const float x1 = l.p1.x + pos * dx1;
const float y1 = l.p1.y + pos * dy1;
const float x2 = l.p2.x + pos * dx2;
const float y2 = l.p2.y + pos * dy2;
line->setLine( x1, y1, x2, y2, stop.rgb() );
}
template< class L >
inline void QskRoundedRect::Stroker< L >::setBorderGradientLines( const BorderValues& v, int c1,
const QskGradient& gradient, L* lines ) const
{ {
if( gradient.stepCount() <= 1 ) if( gradient.stepCount() <= 1 )
{ {
@ -443,8 +452,7 @@ inline void QskRoundedRect::Stroker< L >::setBorderGradientLines( const BorderVa
} }
} }
template< class L > void QskRoundedRect::Stroker::createBorderLines( QskVertex::Line* lines ) const
inline void QskRoundedRect::Stroker< L >::createBorderLines( L* lines ) const
{ {
Q_ASSERT( m_metrics.isRadiusRegular ); Q_ASSERT( m_metrics.isRadiusRegular );
@ -453,10 +461,10 @@ inline void QskRoundedRect::Stroker< L >::createBorderLines( L* lines ) const
const int stepCount = c[ 0 ].stepCount; const int stepCount = c[ 0 ].stepCount;
const int numCornerLines = stepCount + 1; const int numCornerLines = stepCount + 1;
L* linesBR = lines; QskVertex::Line* linesBR = lines;
L* linesTR = linesBR + numCornerLines; QskVertex::Line* linesTR = linesBR + numCornerLines;
L* linesTL = linesTR + numCornerLines; QskVertex::Line* linesTL = linesTR + numCornerLines;
L* linesBL = linesTL + numCornerLines; QskVertex::Line* linesBL = linesTL + numCornerLines;
BorderValues v( m_metrics ); BorderValues v( m_metrics );
@ -515,17 +523,20 @@ inline void QskRoundedRect::Stroker< L >::createBorderLines( L* lines ) const
lines[ 4 * numCornerLines ] = lines[ 0 ]; lines[ 4 * numCornerLines ] = lines[ 0 ];
} }
template< class L > template< class FillMap > void QskRoundedRect::Stroker::createFillLines(
inline void QskRoundedRect::Stroker< L >::createFillLines( QskVertex::ColoredLine* lines, const QskGradient& gradient ) const
Qt::Orientation orientation, L* lines, FillMap& fillMap ) const
{ {
Q_ASSERT( m_metrics.isRadiusRegular ); Q_ASSERT( m_metrics.isRadiusRegular );
Q_ASSERT( gradient.isValid() && gradient.stepCount() <= 1 );
ColorMap fillMap( gradient );
const auto& c = m_metrics.corner; const auto& c = m_metrics.corner;
const int stepCount = c[ 0 ].stepCount; const int stepCount = c[ 0 ].stepCount;
int numLines = 2 * stepCount + 1; int numLines = 2 * stepCount + 1;
const auto orientation = orientationOf( gradient );
if ( orientation == Qt::Vertical ) if ( orientation == Qt::Vertical )
{ {
if ( m_metrics.centerQuad.top < m_metrics.centerQuad.bottom ) if ( m_metrics.centerQuad.top < m_metrics.centerQuad.bottom )
@ -588,35 +599,34 @@ inline void QskRoundedRect::Stroker< L >::createFillLines(
} }
} }
template< class L > void QskRoundedRect::Stroker::createBorderLines(
template< class BorderMap > Qt::Orientation orientation, QskVertex::ColoredLine* lines,
inline void QskRoundedRect::Stroker< L >::createBorderLines( const QskBoxBorderColors& colors ) const
Qt::Orientation orientation, L* borderLines,
const BorderMaps< BorderMap >& borderMaps ) const
{ {
const auto& c = m_metrics.corner; const auto& c = m_metrics.corner;
#if 1 #if 1
// not correct for BorderValuesMulti TODO ...
const int stepCount = c[ 0 ].stepCount; const int stepCount = c[ 0 ].stepCount;
#endif #endif
L* linesBR, * linesTR, * linesTL, * linesBL; const BorderMaps borderMaps( stepCount, colors );
QskVertex::ColoredLine* linesBR, * linesTR, * linesTL, * linesBL;
const int numCornerLines = stepCount + 1; const int numCornerLines = stepCount + 1;
if ( orientation == Qt::Vertical ) if ( orientation == Qt::Vertical )
{ {
linesBR = borderLines; linesBR = lines;
linesTR = linesBR + numCornerLines + borderMaps.extraStops( BottomRight ); linesTR = linesBR + numCornerLines + extraStops( colors.right() );
linesTL = linesTR + numCornerLines + borderMaps.extraStops( TopRight ); linesTL = linesTR + numCornerLines + extraStops( colors.top() );
linesBL = linesTL + numCornerLines + borderMaps.extraStops( TopLeft ); linesBL = linesTL + numCornerLines + extraStops( colors.left() );
} }
else else
{ {
linesTR = borderLines + 1; linesTR = lines + 1;
linesTL = linesTR + numCornerLines + borderMaps.extraStops( TopRight ); linesTL = linesTR + numCornerLines + extraStops( colors.top() );
linesBL = linesTL + numCornerLines + borderMaps.extraStops( TopLeft ); linesBL = linesTL + numCornerLines + extraStops( colors.left() );
linesBR = linesBL + numCornerLines + borderMaps.extraStops( BottomLeft ); linesBR = linesBL + numCornerLines + extraStops( colors.bottom() );
} }
BorderValues v( m_metrics ); BorderValues v( m_metrics );
@ -680,52 +690,56 @@ inline void QskRoundedRect::Stroker< L >::createBorderLines(
v.setAngle( 0.0, 1.0 ); v.setAngle( 0.0, 1.0 );
setBorderGradientLines( v, TopRight, setBorderGradientLines( v, TopRight,
borderMaps.maps[ TopRight ].gradient(), linesTR + numCornerLines ); colors.top(), linesTR + numCornerLines );
setBorderGradientLines( v, BottomLeft, setBorderGradientLines( v, BottomLeft,
borderMaps.maps[ BottomLeft ].gradient(), linesBL + numCornerLines ); colors.bottom(), linesBL + numCornerLines );
v.setAngle( 1.0, 0.0 ); v.setAngle( 1.0, 0.0 );
setBorderGradientLines( v, TopLeft, setBorderGradientLines( v, TopLeft,
borderMaps.maps[ TopLeft ].gradient(), linesTL + numCornerLines ); colors.left(), linesTL + numCornerLines );
setBorderGradientLines( v, BottomRight, setBorderGradientLines( v, BottomRight,
borderMaps.maps[ BottomRight ].gradient(), linesBR + numCornerLines ); colors.right(), linesBR + numCornerLines );
const int k = 4 * numCornerLines + borderMaps.extraStops(); const int k = 4 * numCornerLines + extraBorderStops( colors );
if ( orientation == Qt::Vertical ) if ( orientation == Qt::Vertical )
borderLines[ k ] = borderLines[ 0 ]; lines[ k ] = lines[ 0 ];
else else
borderLines[ 0 ] = borderLines[ k ]; lines[ 0 ] = lines[ k ];
} }
template< class L > void QskRoundedRect::Stroker::createUniformBox(
template< class BorderMap, class FillMap > QskVertex::ColoredLine* borderLines, const QskBoxBorderColors& borderColors,
inline void QskRoundedRect::Stroker< L >::createUniformBox( QskVertex::ColoredLine* fillLines, const QskGradient& gradient ) const
Qt::Orientation orientation, L* borderLines,
const BorderMaps< BorderMap >& borderMaps, L* fillLines, FillMap& fillMap ) const
{ {
Q_ASSERT( m_metrics.isRadiusRegular ); Q_ASSERT( m_metrics.isRadiusRegular );
Q_ASSERT( gradient.isValid() && gradient.stepCount() <= 1 );
const ColorMap fillMap( gradient );
const auto& c = m_metrics.corner; const auto& c = m_metrics.corner;
const int stepCount = c[ 0 ].stepCount; const int stepCount = c[ 0 ].stepCount;
L* linesBR, * linesTR, * linesTL, * linesBL; const BorderMaps borderMaps( stepCount, borderColors );
QskVertex::ColoredLine* linesBR, * linesTR, * linesTL, * linesBL;
linesBR = linesTR = linesTL = linesBL = nullptr; linesBR = linesTR = linesTL = linesBL = nullptr;
const int numCornerLines = stepCount + 1; const int numCornerLines = stepCount + 1;
int numFillLines = fillLines ? 2 * numCornerLines : 0; int numFillLines = fillLines ? 2 * numCornerLines : 0;
const auto orientation = orientationOf( gradient );
if ( orientation == Qt::Vertical ) if ( orientation == Qt::Vertical )
{ {
if ( borderLines ) if ( borderLines )
{ {
linesBR = borderLines; linesBR = borderLines;
linesTR = linesBR + numCornerLines + borderMaps.extraStops( BottomRight ); linesTR = linesBR + numCornerLines + extraStops( borderColors.right() );
linesTL = linesTR + numCornerLines + borderMaps.extraStops( TopRight ); linesTL = linesTR + numCornerLines + extraStops( borderColors.top() );
linesBL = linesTL + numCornerLines + borderMaps.extraStops( TopLeft ); linesBL = linesTL + numCornerLines + extraStops( borderColors.left() );
} }
if ( fillLines ) if ( fillLines )
@ -739,9 +753,9 @@ inline void QskRoundedRect::Stroker< L >::createUniformBox(
if ( borderLines ) if ( borderLines )
{ {
linesTR = borderLines + 1; linesTR = borderLines + 1;
linesTL = linesTR + numCornerLines + borderMaps.extraStops( TopRight ); linesTL = linesTR + numCornerLines + extraStops( borderColors.top() );
linesBL = linesTL + numCornerLines + borderMaps.extraStops( TopLeft ); linesBL = linesTL + numCornerLines + extraStops( borderColors.left() );
linesBR = linesBL + numCornerLines + borderMaps.extraStops( BottomLeft ); linesBR = linesBL + numCornerLines + extraStops( borderColors.bottom() );
} }
if ( fillLines ) if ( fillLines )
@ -859,20 +873,20 @@ inline void QskRoundedRect::Stroker< L >::createUniformBox(
v.setAngle( 0.0, 1.0 ); v.setAngle( 0.0, 1.0 );
setBorderGradientLines( v, TopRight, setBorderGradientLines( v, TopRight,
borderMaps.maps[ TopRight ].gradient(), linesTR + numCornerLines ); borderColors.top(), linesTR + numCornerLines );
setBorderGradientLines( v, BottomLeft, setBorderGradientLines( v, BottomLeft,
borderMaps.maps[ BottomLeft ].gradient(), linesBL + numCornerLines ); borderColors.bottom(), linesBL + numCornerLines );
v.setAngle( 1.0, 0.0 ); v.setAngle( 1.0, 0.0 );
setBorderGradientLines( v, TopLeft, setBorderGradientLines( v, TopLeft,
borderMaps.maps[ TopLeft ].gradient(), linesTL + numCornerLines ); borderColors.left(), linesTL + numCornerLines );
setBorderGradientLines( v, BottomRight, setBorderGradientLines( v, BottomRight,
borderMaps.maps[ BottomRight ].gradient(), linesBR + numCornerLines ); borderColors.right(), linesBR + numCornerLines );
const int k = 4 * numCornerLines + borderMaps.extraStops(); const int k = 4 * numCornerLines + extraBorderStops( borderColors );
if ( orientation == Qt::Vertical ) if ( orientation == Qt::Vertical )
borderLines[ k ] = borderLines[ 0 ]; borderLines[ k ] = borderLines[ 0 ];
@ -880,5 +894,3 @@ inline void QskRoundedRect::Stroker< L >::createUniformBox(
borderLines[ 0 ] = borderLines[ k ]; borderLines[ 0 ] = borderLines[ k ];
} }
} }
#endif

View File

@ -3,14 +3,15 @@
* This file may be used under the terms of the QSkinny License, Version 1.0 * This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/ *****************************************************************************/
#ifndef QSK_SCALE_RENDERER_H #ifndef QSK_ROUNDED_RECT_H
#define QSK_SCALE_RENDERER_H #define QSK_ROUNDED_RECT_H
#include "QskVertex.h" #include "QskVertex.h"
#include "QskRoundedRectRenderer.h" #include "QskRoundedRectRenderer.h"
class QskBoxShapeMetrics; class QskBoxShapeMetrics;
class QskBoxBorderMetrics; class QskBoxBorderMetrics;
class QskBoxBorderColors;
namespace QskRoundedRect namespace QskRoundedRect
{ {
@ -22,8 +23,7 @@ namespace QskRoundedRect
BottomRight = Qt::BottomRightCorner BottomRight = Qt::BottomRightCorner
}; };
int additionalGradientStops( const QskGradient& ); int extraBorderStops( const QskBoxBorderColors& );
int additionalGradientStops( const QskBoxBorderColors& );
class Metrics class Metrics
{ {
@ -50,69 +50,39 @@ namespace QskRoundedRect
bool isTotallyCropped; bool isTotallyCropped;
}; };
class BorderMapNone
{
public:
static inline constexpr QskVertex::Color colorAt( int ) { return QskVertex::Color(); }
inline QskGradient gradient() const { return QskGradient(); }
};
class BorderMapSolid
{
public:
inline BorderMapSolid( const QskVertex::Color color ): m_color( color ) {}
inline QskVertex::Color colorAt( int ) const { return m_color; }
inline QskGradient gradient() const { return QskGradient(); }
const QskVertex::Color m_color;
};
class BorderMapGradient
{
public:
BorderMapGradient( int stepCount,
const QskGradient& gradient1, const QskGradient& gradient2 )
: m_stepCount( stepCount )
, m_color1( gradient1.rgbStart() )
, m_color2( gradient2.rgbEnd() )
, m_gradient( gradient2 )
{
}
inline QskVertex::Color colorAt( int step ) const
{ return m_color1.interpolatedTo( m_color2, step / m_stepCount ); }
inline const QskGradient& gradient() const { return m_gradient; }
private:
const qreal m_stepCount;
const QskVertex::Color m_color1, m_color2;
const QskGradient m_gradient;
};
template< class T >
class BorderMaps
{
public:
BorderMaps( const T& );
BorderMaps( const T&, const T&, const T&, const T& );
int extraStops( int index ) const;
inline int extraStops() const;
T maps[4];
};
class BorderValues class BorderValues
{ {
public: public:
BorderValues( const Metrics& ); BorderValues( const Metrics& );
void setAngle( qreal cos, qreal sin ); void setAngle( qreal cos, qreal sin );
qreal dx1( int pos ) const; inline qreal dx1( int pos ) const
qreal dy1( int pos ) const; {
qreal dx2( int pos ) const; return m_isUniform ? m_uniform.dx1 : m_multi.inner[ pos].dx;
qreal dy2( int pos ) const; }
inline qreal dy1( int pos ) const
{
return m_isUniform ? m_uniform.dy1 : m_multi.inner[ pos ].dy;
}
inline qreal dx2( int pos ) const
{
if ( m_isUniform )
return m_uniform.dx2;
const auto outer = m_multi.outer;
return m_metrics.isRadiusRegular ? outer[ 0 ].dx : outer[ pos ].dx;
}
inline qreal dy2( int pos ) const
{
if ( m_isUniform )
return m_uniform.dy2;
const auto outer = m_multi.outer;
return m_metrics.isRadiusRegular ? outer[ 0 ].dy : outer[ pos ].dy;
}
private: private:
const Metrics& m_metrics; const Metrics& m_metrics;
@ -146,37 +116,30 @@ namespace QskRoundedRect
}; };
}; };
template< class L >
class Stroker class Stroker
{ {
public: public:
Stroker( const Metrics& ); inline Stroker( const Metrics& metrics )
: m_metrics( metrics )
{
}
void createBorderLines( L* ) const; void createBorderLines( QskVertex::Line* ) const;
template< class FillMap > void createFillLines( QskVertex::ColoredLine*, const QskGradient& ) const;
void createFillLines( Qt::Orientation, L*, FillMap& ) const;
template< class BorderMap > void createBorderLines( Qt::Orientation,
void createBorderLines( Qt::Orientation, L*, QskVertex::ColoredLine*, const QskBoxBorderColors& ) const;
const BorderMaps< BorderMap >& ) const;
template< class BorderMap, class FillMap > void createUniformBox( QskVertex::ColoredLine*, const QskBoxBorderColors&,
inline void createUniformBox( Qt::Orientation, L*, QskVertex::ColoredLine*, const QskGradient& ) const;
const BorderMaps< BorderMap >&, L*, FillMap& ) const;
private: private:
void setBorderGradientLine( const QskVertex::Line&,
float dx1, float dy1, float dx2, float dy2,
const QskGradientStop&, L* ) const;
void setBorderGradientLines( const BorderValues&, void setBorderGradientLines( const BorderValues&,
int corner, const QskGradient&, L* ) const; int corner, const QskGradient&, QskVertex::ColoredLine* ) const;
const Metrics& m_metrics; const Metrics& m_metrics;
}; };
} }
#include "QskRoundedRect.hpp"
#endif #endif

View File

@ -325,118 +325,16 @@ static inline int qskFillLineCount(
static inline void qskRenderBorder( const QskRoundedRect::Metrics& metrics, static inline void qskRenderBorder( const QskRoundedRect::Metrics& metrics,
Qt::Orientation orientation, const QskBoxBorderColors& colors, ColoredLine* lines ) Qt::Orientation orientation, const QskBoxBorderColors& colors, ColoredLine* lines )
{ {
using namespace QskRoundedRect; QskRoundedRect::Stroker stroker( metrics );
stroker.createBorderLines( orientation, lines, colors );
Stroker< ColoredLine > stroker( metrics );
if ( colors.isMonochrome() )
{
const BorderMapSolid map( colors.left().rgbStart() );
const BorderMaps< BorderMapSolid > borderMaps( map );
stroker.createBorderLines( orientation, lines, borderMaps );
}
else
{
const int n = metrics.corner[ 0 ].stepCount;
const BorderMaps< BorderMapGradient > borderMaps(
BorderMapGradient( n, colors.top(), colors.left() ),
BorderMapGradient( n, colors.right(), colors.top() ),
BorderMapGradient( n, colors.left(), colors.bottom() ),
BorderMapGradient( n, colors.bottom(), colors.right() ) );
stroker.createBorderLines( orientation, lines, borderMaps );
}
}
static inline void qskRenderUniformFill(
const QskRoundedRect::Metrics& metrics,
const QskGradient& gradient, ColoredLine* lines )
{
using namespace QskRoundedRect;
Q_ASSERT( gradient.stepCount() <= 1 );
Q_ASSERT( metrics.isRadiusRegular );
const auto orientation = qskQtOrientation( gradient );
if ( gradient.isMonochrome() )
{
const ColorMapSolid map( gradient );
Stroker< ColoredLine > stroker( metrics );
stroker.createFillLines( orientation, lines, map );
}
else
{
const ColorMapGradient map( gradient );
Stroker< ColoredLine > stroker( metrics );
stroker.createFillLines( orientation, lines, map );
}
} }
static inline void qskRenderUniformBox( static inline void qskRenderUniformBox(
const QskRoundedRect::Metrics& metrics, const QskBoxBorderColors& borderColors, const QskRoundedRect::Metrics& metrics, const QskBoxBorderColors& borderColors,
const QskGradient& gradient, ColoredLine* fillLines, ColoredLine* borderLines ) const QskGradient& gradient, ColoredLine* fillLines, ColoredLine* borderLines )
{ {
using namespace QskRoundedRect; QskRoundedRect::Stroker stroker( metrics );
stroker.createUniformBox( borderLines, borderColors, fillLines, gradient );
Q_ASSERT( gradient.stepCount() <= 1 );
Q_ASSERT( metrics.isRadiusRegular );
Stroker< ColoredLine > stroker( metrics );
const auto& bc = borderColors;
if ( bc.isMonochrome() )
{
const BorderMapSolid borderMap( bc.left().rgbStart() );
const BorderMaps< BorderMapSolid > borderMaps( borderMap );
if ( gradient.isMonochrome() )
{
const ColorMapSolid fillMap( gradient );
stroker.createUniformBox( Qt::Vertical,
borderLines, borderMaps, fillLines, fillMap );
}
else
{
const ColorMapGradient fillMap( gradient );
stroker.createUniformBox( qskQtOrientation( gradient ),
borderLines, borderMaps, fillLines, fillMap );
}
}
else
{
const int n = metrics.corner[ 0 ].stepCount;
const BorderMaps< BorderMapGradient > borderMaps
(
BorderMapGradient( n, bc.top(), bc.left() ),
BorderMapGradient( n, bc.right(), bc.top() ),
BorderMapGradient( n, bc.left(), bc.bottom() ),
BorderMapGradient( n, bc.bottom(), bc.right() )
);
if ( gradient.isMonochrome() )
{
const ColorMapSolid fillMap( gradient );
stroker.createUniformBox( Qt::Vertical,
borderLines, borderMaps, fillLines, fillMap );
}
else
{
const ColorMapGradient fillMap( gradient );
stroker.createUniformBox( qskQtOrientation( gradient ),
borderLines, borderMaps, fillLines, fillMap );
}
}
} }
static inline void qskRenderFillOrdered( static inline void qskRenderFillOrdered(
@ -471,7 +369,7 @@ void QskRoundedRectRenderer::renderBorderGeometry(
const auto lines = allocateLines< Line >( geometry, lineCount ); const auto lines = allocateLines< Line >( geometry, lineCount );
QskRoundedRect::Stroker< Line > stroker( metrics ); QskRoundedRect::Stroker stroker( metrics );
stroker.createBorderLines( lines ); stroker.createBorderLines( lines );
} }
@ -660,7 +558,7 @@ void QskRoundedRectRenderer::renderRect( const QRectF& rect,
if ( borderColors.isVisible() && metrics.innerQuad != metrics.outerQuad ) if ( borderColors.isVisible() && metrics.innerQuad != metrics.outerQuad )
{ {
borderLineCount = 4 * ( stepCount + 1 ) + 1; borderLineCount = 4 * ( stepCount + 1 ) + 1;
borderLineCount += additionalGradientStops( borderColors ); borderLineCount += extraBorderStops( borderColors );
} }
int lineCount = borderLineCount + fillLineCount; int lineCount = borderLineCount + fillLineCount;
@ -750,7 +648,8 @@ void QskRoundedRectRenderer::renderRect( const QRectF& rect,
{ {
if ( isUniform ) if ( isUniform )
{ {
qskRenderUniformFill( metrics, gradient, lines ); QskRoundedRect::Stroker stroker( metrics );
stroker.createFillLines( lines, gradient );
} }
else else
{ {

View File

@ -109,7 +109,6 @@ HEADERS += \
nodes/QskRectRenderer.h \ nodes/QskRectRenderer.h \
nodes/QskRoundedRectRenderer.h \ nodes/QskRoundedRectRenderer.h \
nodes/QskRoundedRect.h \ nodes/QskRoundedRect.h \
nodes/QskRoundedRect.hpp \
nodes/QskBoxRendererColorMap.h \ nodes/QskBoxRendererColorMap.h \
nodes/QskBoxShadowNode.h \ nodes/QskBoxShadowNode.h \
nodes/QskColorRamp.h \ nodes/QskColorRamp.h \
@ -139,6 +138,7 @@ SOURCES += \
nodes/QskBoxRenderer.cpp \ nodes/QskBoxRenderer.cpp \
nodes/QskRectRenderer.cpp \ nodes/QskRectRenderer.cpp \
nodes/QskRoundedRectRenderer.cpp \ nodes/QskRoundedRectRenderer.cpp \
nodes/QskRoundedRect.cpp \
nodes/QskBoxRendererDEllipse.cpp \ nodes/QskBoxRendererDEllipse.cpp \
nodes/QskBoxShadowNode.cpp \ nodes/QskBoxShadowNode.cpp \
nodes/QskColorRamp.cpp \ nodes/QskColorRamp.cpp \