6#ifndef QSK_VERTEX_HELPER_H
7#define QSK_VERTEX_HELPER_H
9#include "QskGradient.h"
10#include "QskGradientDirection.h"
22 inline ArcIterator(
int stepCount,
bool inverted =
false )
24 reset( stepCount, inverted );
27 void reset(
int stepCount,
bool inverted =
false )
29 m_inverted = inverted;
43 m_stepCount = stepCount;
45 const auto angleStep = M_PI_2 / stepCount;
46 m_cosStep = qFastCos( angleStep );
47 m_sinStep = qFastSin( angleStep );
50 inline bool isInverted()
const {
return m_inverted; }
52 inline qreal cos()
const {
return m_cos; }
53 inline qreal sin()
const {
return m_inverted ? -m_sin : m_sin; }
55 inline int step()
const {
return m_stepIndex; }
56 inline int stepCount()
const {
return m_stepCount; }
57 inline bool isDone()
const {
return m_stepIndex > m_stepCount; }
59 inline void increment()
61 if ( ++m_stepIndex >= m_stepCount )
63 if ( m_stepIndex == m_stepCount )
84 const auto cos0 = m_cos;
86 m_cos = m_cos * m_cosStep + m_sin * m_sinStep;
87 m_sin = m_sin * m_cosStep - cos0 * m_sinStep;
91 inline void decrement()
98 inline void operator++() { increment(); }
100 static int segmentHint( qreal radius )
102 const auto arcLength = radius * M_PI_2;
103 return qBound( 3, qCeil( arcLength / 3.0 ), 18 );
108 m_inverted = !m_inverted;
109 m_stepIndex = m_stepCount - m_stepIndex;
146 : m_isTransparent( !gradient.isVisible() )
147 , m_isMonochrome( gradient.isMonochrome() )
148 , m_color1( gradient.rgbStart() )
149 , m_color2( gradient.rgbEnd() )
151 if ( !m_isMonochrome )
153 const auto dir = gradient.linearDirection();
157 m_dx = dir.x2() - dir.x1();
158 m_dy = dir.y2() - dir.y1();
159 m_dot = m_dx * m_dx + m_dy * m_dy;
163 inline void setLine( qreal x1, qreal y1, qreal x2, qreal y2,
166 if ( m_isMonochrome )
168 line->setLine( x1, y1, x2, y2, m_color1 );
172 const auto c1 = colorAt( x1, y1 );
173 const auto c2 = colorAt( x2, y2 );
175 line->setLine( x1, y1, c1, x2, y2, c2 );
179 inline bool isMonochrome()
const {
return m_isMonochrome; }
180 inline bool isTransparent()
const {
return m_isTransparent; }
182 static inline bool isGradientSupported(
185 if ( gradient.isMonochrome() )
188 switch( gradient.stepCount() )
195 Q_ASSERT( gradient.stretchMode() != QskGradient::StretchToSize );
196 return gradient.linearDirection().contains( rect );
207 return m_color1.interpolatedTo( m_color2, valueAt( x, y ) );
210 inline qreal valueAt( qreal x, qreal y )
const
212 const qreal dx = x - m_x;
213 const qreal dy = y - m_y;
215 return ( dx * m_dx + dy * m_dy ) / m_dot;
218 const bool m_isTransparent;
219 const bool m_isMonochrome;
221 qreal m_x, m_y, m_dx, m_dy, m_dot;
230 class GradientIterator
233 GradientIterator() =
default;
241 inline GradientIterator(
248 inline GradientIterator(
const QskGradientStops& stops )
250 , m_color1( stops.first().rgb() )
251 , m_color2( m_color1 )
252 , m_pos1( stops.first().position() )
261 m_color1 = m_color2 = color;
272 inline void reset(
const QskGradientStops& stops )
277 m_color1 = m_color2 = stops.first().rgb();
278 m_pos1 = m_pos2 = stops.first().position();
281 inline qreal position()
const
293 if ( m_color1 == m_color2 )
298 return m_color1.interpolatedTo( m_color2, pos );
302 if ( m_pos2 == m_pos1 )
305 const auto r = ( pos - m_pos1 ) / ( m_pos2 - m_pos1 );
306 return m_color1.interpolatedTo( m_color2, r );
310 inline bool advance()
318 if ( ++m_index < m_stops.size() )
320 const auto& s = m_stops[ m_index ];
322 m_pos2 = s.position();
329 inline bool isDone()
const
334 return m_index >= m_stops.size();
338 QskGradientStops m_stops;