aspectRatio for conic gradients added to support f.e for filling ellipsoid arcs.
This commit is contained in:
parent
e858e15b41
commit
9e99735d2f
@ -171,7 +171,7 @@ QskGradient::QskGradient( const QGradient& qGradient )
|
||||
QskGradient::QskGradient( const QskGradient& other ) noexcept
|
||||
: m_stops( other.m_stops )
|
||||
, m_values{ other.m_values[0], other.m_values[1],
|
||||
other.m_values[2], other.m_values[3], }
|
||||
other.m_values[2], other.m_values[3], other.m_values[4] }
|
||||
, m_type( other.m_type )
|
||||
, m_spreadMode( other.m_spreadMode )
|
||||
, m_stretchMode( other.m_stretchMode )
|
||||
@ -197,6 +197,7 @@ QskGradient& QskGradient::operator=( const QskGradient& other ) noexcept
|
||||
m_values[1] = other.m_values[1];
|
||||
m_values[2] = other.m_values[2];
|
||||
m_values[3] = other.m_values[3];
|
||||
m_values[4] = other.m_values[4];
|
||||
|
||||
m_isDirty = other.m_isDirty;
|
||||
m_isValid = other.m_isValid;
|
||||
@ -215,6 +216,7 @@ bool QskGradient::operator==( const QskGradient& other ) const noexcept
|
||||
&& ( m_values[1] == other.m_values[1] )
|
||||
&& ( m_values[2] == other.m_values[2] )
|
||||
&& ( m_values[3] == other.m_values[3] )
|
||||
&& ( m_values[4] == other.m_values[4] )
|
||||
&& ( m_stops == other.m_stops );
|
||||
}
|
||||
|
||||
@ -439,6 +441,10 @@ void QskGradient::stretchTo( const QRectF& rect )
|
||||
case Conic:
|
||||
{
|
||||
transform.map( m_values[0], m_values[1], &m_values[0], &m_values[1] );
|
||||
|
||||
if ( m_values[4] == 0.0 && !rect.isEmpty() )
|
||||
m_values[4] = rect.width() / rect.height();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -657,6 +663,13 @@ void QskGradient::setConicDirection( qreal x, qreal y,
|
||||
setConicDirection( QskConicDirection( x, y, startAngle, spanAngle ) );
|
||||
}
|
||||
|
||||
void QskGradient::setConicDirection( qreal x, qreal y,
|
||||
qreal startAngle, qreal spanAngle, qreal aspectRatio )
|
||||
{
|
||||
const QskConicDirection dir( x, y, startAngle, spanAngle, aspectRatio );
|
||||
setConicDirection( dir );
|
||||
}
|
||||
|
||||
void QskGradient::setConicDirection( const QskConicDirection& direction )
|
||||
{
|
||||
m_type = Conic;
|
||||
@ -665,6 +678,7 @@ void QskGradient::setConicDirection( const QskConicDirection& direction )
|
||||
m_values[1] = direction.center().y();
|
||||
m_values[2] = direction.startAngle();
|
||||
m_values[3] = direction.spanAngle();
|
||||
m_values[4] = direction.aspectRatio();
|
||||
}
|
||||
|
||||
QskConicDirection QskGradient::conicDirection() const
|
||||
@ -674,7 +688,10 @@ QskConicDirection QskGradient::conicDirection() const
|
||||
if ( m_type != Conic )
|
||||
return QskConicDirection( 0.5, 0.5, 0.0, 0.0 );
|
||||
|
||||
return QskConicDirection( m_values[0], m_values[1], m_values[2], m_values[3] );
|
||||
QskConicDirection dir( m_values[0], m_values[1], m_values[2], m_values[3] );
|
||||
dir.setAspectRatio( m_values[4] );
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
void QskGradient::setDirection( Type type )
|
||||
@ -702,7 +719,7 @@ void QskGradient::setDirection( Type type )
|
||||
void QskGradient::resetDirection()
|
||||
{
|
||||
m_type = Stops;
|
||||
m_values[0] = m_values[1] = m_values[2] = m_values[3] = 0.0;
|
||||
m_values[0] = m_values[1] = m_values[2] = m_values[3] = m_values[4] = 0.0;
|
||||
}
|
||||
|
||||
QskGradient QskGradient::effectiveGradient() const
|
||||
@ -803,6 +820,7 @@ QDebug operator<<( QDebug debug, const QskGradient& gradient )
|
||||
const auto dir = gradient.conicDirection();
|
||||
|
||||
debug << dir.center().x() << "," << dir.center().y()
|
||||
<< ",AR:" << dir.aspectRatio()
|
||||
<< ",[" << dir.startAngle() << "," << dir.spanAngle() << "])";
|
||||
break;
|
||||
}
|
||||
|
@ -97,8 +97,14 @@ class QSK_EXPORT QskGradient
|
||||
void setRadialDirection( const qreal x, qreal y, qreal radiusX, qreal radiusY );
|
||||
QskRadialDirection radialDirection() const;
|
||||
|
||||
void setConicDirection( qreal, qreal );
|
||||
void setConicDirection( qreal, qreal, qreal, qreal = 360.0 );
|
||||
void setConicDirection( qreal x, qreal y );
|
||||
|
||||
void setConicDirection( qreal x, qreal y,
|
||||
qreal startAngle, qreal spanAngle = 360.0 );
|
||||
|
||||
void setConicDirection( qreal x, qreal y,
|
||||
qreal startAngle, qreal spanAngle, qreal aspectRatio );
|
||||
|
||||
void setConicDirection( const QskConicDirection& );
|
||||
QskConicDirection conicDirection() const;
|
||||
|
||||
@ -172,9 +178,9 @@ class QSK_EXPORT QskGradient
|
||||
/*
|
||||
Linear: x1, y1, x2, y2
|
||||
Radial: centerX, centerY, radiusX, radiusY
|
||||
Conic: centerX, centerY, startAngle, spanAngle
|
||||
Conic: centerX, centerY, startAngle, spanAngle, aspectRatio
|
||||
*/
|
||||
qreal m_values[4] = {};
|
||||
qreal m_values[5] = {};
|
||||
|
||||
unsigned int m_type : 3;
|
||||
unsigned int m_spreadMode : 3;
|
||||
|
@ -228,6 +228,11 @@ void QskConicDirection::setSpanAngle( qreal degrees ) noexcept
|
||||
m_spanAngle = qBound( -360.0, degrees, 360.0 );
|
||||
}
|
||||
|
||||
void QskConicDirection::setAspectRatio( qreal ratio ) noexcept
|
||||
{
|
||||
m_aspectRatio = qMax( ratio, 0.0 );
|
||||
}
|
||||
|
||||
// -- QskRadialDirection
|
||||
|
||||
void QskRadialDirection::setCenter( const QPointF& center ) noexcept
|
||||
|
@ -105,16 +105,19 @@ class QSK_EXPORT QskConicDirection
|
||||
Q_PROPERTY( qreal y READ y WRITE setY )
|
||||
Q_PROPERTY( qreal startAngle READ startAngle WRITE setStartAngle )
|
||||
Q_PROPERTY( qreal spanAngle READ spanAngle WRITE setSpanAngle )
|
||||
Q_PROPERTY( qreal aspectRatio READ aspectRatio WRITE setAspectRatio )
|
||||
|
||||
public:
|
||||
// counter-clockwise
|
||||
constexpr QskConicDirection() noexcept = default;
|
||||
|
||||
constexpr QskConicDirection( qreal x, qreal y, qreal startAngle = 0.0 ) noexcept;
|
||||
constexpr QskConicDirection( qreal x, qreal y, qreal startAngle, qreal spanAngle ) noexcept;
|
||||
constexpr QskConicDirection( qreal x, qreal y,
|
||||
qreal startAngle, qreal spanAngle, qreal aspectRatio = 0.0 ) noexcept;
|
||||
|
||||
constexpr QskConicDirection( const QPointF&, qreal startAngle = 0.0 ) noexcept;
|
||||
constexpr QskConicDirection( const QPointF&, qreal startAngle, qreal spanAngle ) noexcept;
|
||||
constexpr QskConicDirection( const QPointF&,
|
||||
qreal startAngle, qreal spanAngle, qreal aspectRatio = 0.0 ) noexcept;
|
||||
|
||||
constexpr QPointF center() const noexcept;
|
||||
void setCenter(const QPointF& center) noexcept;
|
||||
@ -132,11 +135,15 @@ class QSK_EXPORT QskConicDirection
|
||||
constexpr qreal spanAngle() const noexcept;
|
||||
void setSpanAngle( qreal ) noexcept;
|
||||
|
||||
constexpr qreal aspectRatio() const noexcept;
|
||||
void setAspectRatio( qreal ) noexcept;
|
||||
|
||||
private:
|
||||
qreal m_x = 0.5;
|
||||
qreal m_y = 0.5;
|
||||
qreal m_startAngle = 0.0;
|
||||
qreal m_spanAngle = 360.0;
|
||||
qreal m_aspectRatio = 0.0;
|
||||
};
|
||||
|
||||
class QSK_EXPORT QskRadialDirection
|
||||
@ -299,12 +306,13 @@ inline constexpr QskConicDirection::QskConicDirection(
|
||||
{
|
||||
}
|
||||
|
||||
inline constexpr QskConicDirection::QskConicDirection(
|
||||
qreal x, qreal y, qreal startAngle, qreal spanAngle ) noexcept
|
||||
inline constexpr QskConicDirection::QskConicDirection( qreal x, qreal y,
|
||||
qreal startAngle, qreal spanAngle, qreal aspectRatio ) noexcept
|
||||
: m_x( x )
|
||||
, m_y( y )
|
||||
, m_startAngle( startAngle )
|
||||
, m_spanAngle( spanAngle )
|
||||
, m_aspectRatio( aspectRatio )
|
||||
{
|
||||
}
|
||||
|
||||
@ -314,9 +322,9 @@ inline constexpr QskConicDirection::QskConicDirection(
|
||||
{
|
||||
}
|
||||
|
||||
inline constexpr QskConicDirection::QskConicDirection(
|
||||
const QPointF& pos, qreal startAngle, qreal spanAngle ) noexcept
|
||||
: QskConicDirection( pos.x(), pos.y(), startAngle, spanAngle )
|
||||
inline constexpr QskConicDirection::QskConicDirection( const QPointF& pos,
|
||||
qreal startAngle, qreal spanAngle, qreal apectRatio ) noexcept
|
||||
: QskConicDirection( pos.x(), pos.y(), startAngle, spanAngle, apectRatio )
|
||||
{
|
||||
}
|
||||
|
||||
@ -345,6 +353,11 @@ inline constexpr qreal QskConicDirection::y() const noexcept
|
||||
return m_y;
|
||||
}
|
||||
|
||||
inline constexpr qreal QskConicDirection::aspectRatio() const noexcept
|
||||
{
|
||||
return m_aspectRatio;
|
||||
}
|
||||
|
||||
inline constexpr QskRadialDirection::QskRadialDirection(
|
||||
qreal x, qreal y, qreal radius ) noexcept
|
||||
: m_x( x )
|
||||
|
@ -510,6 +510,16 @@ namespace
|
||||
|
||||
const auto dir = gradient.conicDirection();
|
||||
|
||||
float ratio = dir.aspectRatio();
|
||||
if ( ratio <= 0.0f )
|
||||
ratio = 1.0f;
|
||||
|
||||
if ( ratio != m_aspectRatio )
|
||||
{
|
||||
m_aspectRatio = ratio;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
const QVector2D center( dir.x(), dir.y() );
|
||||
|
||||
if ( center != m_center )
|
||||
@ -555,6 +565,7 @@ namespace
|
||||
const auto mat = static_cast< const ConicMaterial* >( other );
|
||||
|
||||
if ( ( m_center != mat->m_center )
|
||||
|| !qskFuzzyCompare( m_aspectRatio, mat->m_aspectRatio )
|
||||
|| !qskFuzzyCompare( m_start, mat->m_start )
|
||||
|| !qskFuzzyCompare( m_span, mat->m_span ) )
|
||||
{
|
||||
@ -567,6 +578,7 @@ namespace
|
||||
QSGMaterialShader* createShader() const override;
|
||||
|
||||
QVector2D m_center;
|
||||
float m_aspectRatio = 1.0;
|
||||
float m_start = 0.0;
|
||||
float m_span = 1.0;
|
||||
};
|
||||
@ -585,6 +597,7 @@ namespace
|
||||
GradientShaderGL::initialize();
|
||||
|
||||
m_centerCoordId = program()->uniformLocation( "centerCoord" );
|
||||
m_aspectRatioId = program()->uniformLocation( "aspectRatio" );
|
||||
m_startId = program()->uniformLocation( "start" );
|
||||
m_spanId = program()->uniformLocation( "span" );
|
||||
}
|
||||
@ -594,12 +607,14 @@ namespace
|
||||
auto material = static_cast< const ConicMaterial* >( newMaterial );
|
||||
|
||||
program()->setUniformValue( m_centerCoordId, material->m_center );
|
||||
program()->setUniformValue( m_aspectRatioId, material->m_aspectRatio );
|
||||
program()->setUniformValue( m_startId, material->m_start );
|
||||
program()->setUniformValue( m_spanId, material->m_span );
|
||||
}
|
||||
|
||||
private:
|
||||
int m_centerCoordId = -1;
|
||||
int m_aspectRatioId = -1;
|
||||
int m_startId = -1;
|
||||
int m_spanId = -1;
|
||||
};
|
||||
@ -620,7 +635,7 @@ namespace
|
||||
auto matNew = static_cast< ConicMaterial* >( newMaterial );
|
||||
auto matOld = static_cast< ConicMaterial* >( oldMaterial );
|
||||
|
||||
Q_ASSERT( state.uniformData()->size() >= 84 );
|
||||
Q_ASSERT( state.uniformData()->size() >= 88 );
|
||||
|
||||
auto data = state.uniformData()->data();
|
||||
bool changed = false;
|
||||
@ -639,22 +654,28 @@ namespace
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ( matOld == nullptr || matNew->m_aspectRatio != matOld->m_aspectRatio )
|
||||
{
|
||||
memcpy( data + 72, &matNew->m_aspectRatio, 4 );
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ( matOld == nullptr || matNew->m_start != matOld->m_start )
|
||||
{
|
||||
memcpy( data + 72, &matNew->m_start, 4 );
|
||||
memcpy( data + 76, &matNew->m_start, 4 );
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ( matOld == nullptr || matNew->m_span != matOld->m_span )
|
||||
{
|
||||
memcpy( data + 76, &matNew->m_span, 4 );
|
||||
memcpy( data + 80, &matNew->m_span, 4 );
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ( state.isOpacityDirty() )
|
||||
{
|
||||
const float opacity = state.opacity();
|
||||
memcpy( data + 80, &opacity, 4 );
|
||||
memcpy( data + 84, &opacity, 4 );
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ layout( std140, binding = 0 ) uniform buf
|
||||
{
|
||||
mat4 matrix;
|
||||
vec2 centerCoord;
|
||||
float aspectRatio;
|
||||
float start;
|
||||
float span;
|
||||
float opacity;
|
||||
|
@ -7,6 +7,7 @@ layout( std140, binding = 0 ) uniform buf
|
||||
{
|
||||
mat4 matrix;
|
||||
vec2 centerCoord;
|
||||
float aspectRatio;
|
||||
float start;
|
||||
float span;
|
||||
float opacity;
|
||||
@ -17,5 +18,7 @@ out gl_PerVertex { vec4 gl_Position; };
|
||||
void main()
|
||||
{
|
||||
coord = vertexCoord.xy - ubuf.centerCoord;
|
||||
coord.y *= ubuf.aspectRatio;
|
||||
|
||||
gl_Position = ubuf.matrix * vertexCoord;
|
||||
}
|
||||
|
Binary file not shown.
@ -1,6 +1,7 @@
|
||||
attribute vec4 vertexCoord;
|
||||
|
||||
uniform mat4 matrix;
|
||||
uniform highp float aspectRatio;
|
||||
uniform vec2 centerCoord;
|
||||
|
||||
varying vec2 coord;
|
||||
@ -8,5 +9,7 @@ varying vec2 coord;
|
||||
void main()
|
||||
{
|
||||
coord = vertexCoord.xy - centerCoord;
|
||||
coord.y *= aspectRatio;
|
||||
|
||||
gl_Position = matrix * vertexCoord;
|
||||
}
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user