Name |
---|
QskVertex |
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_BOX_RENDERER_COLOR_MAP_H
#define QSK_BOX_RENDERER_COLOR_MAP_H
#include <QskGradient.h>
#include <QskVertex.h>
#include <cassert>
class QskBoxShapeMetrics;
namespace QskVertex
{
class ColorMapNone
{
public:
constexpr inline Color colorAt( qreal ) const
{
return Color();
}
};
class ColorMapSolid
{
public:
constexpr inline ColorMapSolid( Color color )
: m_color( color )
{
}
inline Color colorAt( qreal ) const
{
return m_color;
}
private:
const Color m_color;
};
class ColorMapGradient
{
public:
inline ColorMapGradient( Color color1, Color color2 )
: m_color1( color1 )
, m_color2( color2 )
{
}
inline Color colorAt( qreal value ) const
{
return m_color1.interpolatedTo( m_color2, value );
}
private:
const Color m_color1;
const Color m_color2;
};
class ColorIterator
{
public:
static inline bool advance()
{
return false;
}
inline qreal value() const
{
assert( false );
return 0.0;
}
inline Color color() const
{
assert( false );
return Color();
}
static inline bool isDone()
{
return true;
}
};
class SolidColorIterator : public ColorIterator
{
public:
inline SolidColorIterator( const QColor& color )
: m_color( color )
{
}
inline Color colorAt( qreal ) const
{
return m_color;
}
private:
const Color m_color;
};
class TwoColorIterator01 : public ColorIterator
{
public:
inline TwoColorIterator01( const QColor& color1, const QColor& color2 )
: m_color1( color1 )
, m_color2( color2 )
{
}
inline Color colorAt( qreal value ) const
{
return m_color1.interpolatedTo( m_color2, value );
}
private:
const Color m_color1, m_color2;
};
class TwoColorIterator : public ColorIterator
{
public:
inline TwoColorIterator( qreal value1, qreal value2,
const QColor& color1, const QColor& color2 )
: m_value1( value1 )
, m_range( value2 - value1 )
, m_color1( color1 )
, m_color2( color2 )
{
}
inline Color colorAt( qreal value ) const
{
const qreal r = ( value - m_value1 ) / m_range;
return m_color1.interpolatedTo( m_color2, r );
}
private:
const qreal m_value1, m_range;
const Color m_color1, m_color2;
};
class GradientColorIterator : public ColorIterator
{
public:
inline GradientColorIterator( qreal value1, qreal value2,
const QskGradientStops& stops )
: m_value1( value1 )
, m_value2( value2 )
, m_stops( stops )
{
Q_ASSERT( stops.size() > 2 );
m_color1 = stops[ 0 ].color();
m_color2 = stops[ 1 ].color();
m_valueStep1 = value1;
m_valueStep2 = valueAt( stops[ 1 ].position() );
m_stepSize = m_valueStep2 - m_valueStep1;
m_index = 1;
}
inline qreal value() const
{
return m_valueStep2;
}
inline Color color() const
{
return m_color2;
}
inline Color colorAt( qreal value ) const
{
const qreal r = ( value - m_valueStep1 ) / m_stepSize;
return m_color1.interpolatedTo( m_color2, r );
}
inline bool advance()
{
const auto& stop = m_stops[ ++m_index ];
m_color1 = m_color2;
m_color2 = stop.color();
m_valueStep1 = m_valueStep2;
m_valueStep2 = valueAt( stop.position() );
m_stepSize = m_valueStep2 - m_valueStep1;
return !isDone();
}
inline bool isDone() const
{
return m_index >= m_stops.count() - 1;
}
private:
inline qreal valueAt( qreal pos ) const
{
return m_value1 + pos * ( ( m_value2 - m_value1 ) );
}
const qreal m_value1, m_value2;
const QskGradientStops m_stops;
int m_index;
qreal m_valueStep1, m_valueStep2, m_stepSize;
Color m_color1, m_color2;
};
template< class ContourIterator, class ColorIterator >
ColoredLine* fillOrdered( ContourIterator& contourIt,
ColorIterator& colorIt, ColoredLine* line )
{
do
{
while ( !colorIt.isDone() && ( colorIt.value() < contourIt.value() ) )
{
contourIt.setGradientLine( colorIt, line++ );
colorIt.advance();
}
contourIt.setContourLine( colorIt, line++ );
} while ( contourIt.advance() );
return line;
}
template< class ContourIterator >
ColoredLine* fillOrdered( ContourIterator& contourIt,
qreal value1, qreal value2, const QskGradient& gradient, ColoredLine* line )
{
if ( gradient.stops().size() == 2 )
{
if ( value2 == 1.0 && value1 == 0.0 )
{
TwoColorIterator01 colorIt( gradient.startColor(), gradient.endColor() );
line = fillOrdered( contourIt, colorIt, line );
}
else
{
TwoColorIterator colorIt( value1, value2,
gradient.startColor(), gradient.endColor() );
line = fillOrdered( contourIt, colorIt, line );
}
}
else
{
GradientColorIterator colorIt( value1, value2, gradient.stops() );
line = fillOrdered( contourIt, colorIt, line );
}
return line;
}
}
#endif
Updated on 28 July 2023 at 14:02:30 CEST