de-template-ified: much better starting point for the fixes to come
This commit is contained in:
parent
a916bd78c2
commit
cd4a46cc11
@ -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:
|
||||||
|
@ -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
|
|
@ -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
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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 \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user