qskinny/src/nodes/QskBoxRendererColorMap.h
Uwe Rathmann 6479937294 All box subcontrols are displayd with vertex lists instead of textures
now. Implementation is almost complete beside of the not yet done Qt
antialiasing mode. Not all sort of linear gradients ( see
QLinearGradients ) are implemented - needs 1-2 days more.
The aspect flags for box primitives have been substantially changed from
too atomic to more strutured units.
The skins are currently incomplete - will be fixed later.
2017-10-17 17:29:02 +02:00

266 lines
6.5 KiB
C++

/******************************************************************************
* 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 <QskGlobal.h>
#include <QskVertex.h>
#include <QskGradient.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 QVector< QskGradientStop > 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;
QVector< QskGradientStop > 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