Fix Rectangle implementation.
This commit is contained in:
parent
2002baaf68
commit
4fb6ee7d25
|
@ -55,64 +55,82 @@ QT_BEGIN_NAMESPACE
|
||||||
// XXX todo - should we change rectangle to draw entirely within its width/height?
|
// XXX todo - should we change rectangle to draw entirely within its width/height?
|
||||||
|
|
||||||
QSGPen::QSGPen(QObject *parent)
|
QSGPen::QSGPen(QObject *parent)
|
||||||
: QObject(parent), _width(1), _color("#000000"), _valid(false)
|
: QObject(parent)
|
||||||
|
, m_width(1)
|
||||||
|
, m_color("#000000")
|
||||||
|
, m_aligned(true)
|
||||||
|
, m_valid(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal QSGPen::width() const
|
||||||
|
{
|
||||||
|
return m_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSGPen::setWidth(qreal w)
|
||||||
|
{
|
||||||
|
if (m_width == w && m_valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_width = w;
|
||||||
|
m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
|
||||||
|
emit penChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QColor QSGPen::color() const
|
QColor QSGPen::color() const
|
||||||
{
|
{
|
||||||
return _color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSGPen::setColor(const QColor &c)
|
void QSGPen::setColor(const QColor &c)
|
||||||
{
|
{
|
||||||
_color = c;
|
m_color = c;
|
||||||
_valid = (_color.alpha() && _width >= 1) ? true : false;
|
m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
|
||||||
emit penChanged();
|
emit penChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
int QSGPen::width() const
|
bool QSGPen::aligned() const
|
||||||
{
|
{
|
||||||
return _width;
|
return m_aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSGPen::setWidth(int w)
|
void QSGPen::setAligned(bool aligned)
|
||||||
{
|
{
|
||||||
if (_width == w && _valid)
|
if (aligned == m_aligned)
|
||||||
return;
|
return;
|
||||||
|
m_aligned = aligned;
|
||||||
_width = w;
|
m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
|
||||||
_valid = (_color.alpha() && _width >= 1) ? true : false;
|
|
||||||
emit penChanged();
|
emit penChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QSGPen::isValid() const
|
bool QSGPen::isValid() const
|
||||||
{
|
{
|
||||||
return _valid;
|
return m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGGradientStop::QSGGradientStop(QObject *parent)
|
QSGGradientStop::QSGGradientStop(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal QSGGradientStop::position() const
|
qreal QSGGradientStop::position() const
|
||||||
{
|
{
|
||||||
return m_position;
|
return m_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSGGradientStop::setPosition(qreal position)
|
void QSGGradientStop::setPosition(qreal position)
|
||||||
{
|
{
|
||||||
m_position = position; updateGradient();
|
m_position = position; updateGradient();
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor QSGGradientStop::color() const
|
QColor QSGGradientStop::color() const
|
||||||
{
|
{
|
||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSGGradientStop::setColor(const QColor &color)
|
void QSGGradientStop::setColor(const QColor &color)
|
||||||
{
|
{
|
||||||
m_color = color; updateGradient();
|
m_color = color; updateGradient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +146,12 @@ QSGGradient::QSGGradient(QObject *parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGGradient::~QSGGradient()
|
QSGGradient::~QSGGradient()
|
||||||
{
|
{
|
||||||
delete m_gradient;
|
delete m_gradient;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDeclarativeListProperty<QSGGradientStop> QSGGradient::stops()
|
QDeclarativeListProperty<QSGGradientStop> QSGGradient::stops()
|
||||||
{
|
{
|
||||||
return QDeclarativeListProperty<QSGGradientStop>(this, m_stops);
|
return QDeclarativeListProperty<QSGGradientStop>(this, m_stops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,8 +275,8 @@ QSGNode *QSGRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *da
|
||||||
if (d->pen && d->pen->isValid()) {
|
if (d->pen && d->pen->isValid()) {
|
||||||
rectangle->setPenColor(d->pen->color());
|
rectangle->setPenColor(d->pen->color());
|
||||||
rectangle->setPenWidth(d->pen->width());
|
rectangle->setPenWidth(d->pen->width());
|
||||||
|
rectangle->setAligned(d->pen->aligned());
|
||||||
} else {
|
} else {
|
||||||
rectangle->setPenColor(QColor());
|
|
||||||
rectangle->setPenWidth(0);
|
rectangle->setPenWidth(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,26 +58,31 @@ class Q_DECLARATIVE_PRIVATE_EXPORT QSGPen : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(int width READ width WRITE setWidth NOTIFY penChanged)
|
Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY penChanged)
|
||||||
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
|
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
|
||||||
|
Q_PROPERTY(bool aligned READ aligned WRITE setAligned NOTIFY penChanged)
|
||||||
public:
|
public:
|
||||||
QSGPen(QObject *parent=0);
|
QSGPen(QObject *parent=0);
|
||||||
|
|
||||||
int width() const;
|
qreal width() const;
|
||||||
void setWidth(int w);
|
void setWidth(qreal w);
|
||||||
|
|
||||||
QColor color() const;
|
QColor color() const;
|
||||||
void setColor(const QColor &c);
|
void setColor(const QColor &c);
|
||||||
|
|
||||||
|
bool aligned() const;
|
||||||
|
void setAligned(bool aligned);
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void penChanged();
|
void penChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _width;
|
qreal m_width;
|
||||||
QColor _color;
|
QColor m_color;
|
||||||
bool _valid;
|
bool m_aligned : 1;
|
||||||
|
bool m_valid : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Q_AUTOTEST_EXPORT QSGGradientStop : public QObject
|
class Q_AUTOTEST_EXPORT QSGGradientStop : public QObject
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
virtual void setPenWidth(qreal width) = 0;
|
virtual void setPenWidth(qreal width) = 0;
|
||||||
virtual void setGradientStops(const QGradientStops &stops) = 0;
|
virtual void setGradientStops(const QGradientStops &stops) = 0;
|
||||||
virtual void setRadius(qreal radius) = 0;
|
virtual void setRadius(qreal radius) = 0;
|
||||||
|
virtual void setAligned(bool aligned) = 0;
|
||||||
|
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include <private/qsgcontext_p.h>
|
#include <private/qsgcontext_p.h>
|
||||||
|
|
||||||
#include <QtCore/qmath.h>
|
#include <QtCore/qmath.h>
|
||||||
|
#include <QtCore/qvarlengtharray.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@ QSGDefaultRectangleNode::QSGDefaultRectangleNode(QSGContext *context)
|
||||||
: m_border(0)
|
: m_border(0)
|
||||||
, m_radius(0)
|
, m_radius(0)
|
||||||
, m_pen_width(0)
|
, m_pen_width(0)
|
||||||
|
, m_aligned(true)
|
||||||
, m_gradient_is_opaque(true)
|
, m_gradient_is_opaque(true)
|
||||||
, m_dirty_geometry(false)
|
, m_dirty_geometry(false)
|
||||||
, m_default_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
|
, m_default_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
|
||||||
|
@ -186,6 +188,14 @@ void QSGDefaultRectangleNode::setRadius(qreal radius)
|
||||||
m_dirty_geometry = true;
|
m_dirty_geometry = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QSGDefaultRectangleNode::setAligned(bool aligned)
|
||||||
|
{
|
||||||
|
if (aligned == m_aligned)
|
||||||
|
return;
|
||||||
|
m_aligned = aligned;
|
||||||
|
m_dirty_geometry = true;
|
||||||
|
}
|
||||||
|
|
||||||
void QSGDefaultRectangleNode::update()
|
void QSGDefaultRectangleNode::update()
|
||||||
{
|
{
|
||||||
if (m_dirty_geometry) {
|
if (m_dirty_geometry) {
|
||||||
|
@ -225,8 +235,10 @@ struct ColorVertex
|
||||||
|
|
||||||
void QSGDefaultRectangleNode::updateGeometry()
|
void QSGDefaultRectangleNode::updateGeometry()
|
||||||
{
|
{
|
||||||
|
qreal penWidth = m_aligned ? qreal(qRound(m_pen_width)) : m_pen_width;
|
||||||
|
|
||||||
// fast path for the simple case...
|
// fast path for the simple case...
|
||||||
if ((m_pen_width == 0 || m_border_material.color().alpha() == 0)
|
if ((penWidth == 0 || m_border_material.color().alpha() == 0)
|
||||||
&& m_radius == 0
|
&& m_radius == 0
|
||||||
&& m_material_type == TypeFlat) {
|
&& m_material_type == TypeFlat) {
|
||||||
QSGGeometry::updateRectGeometry(&m_default_geometry, m_rect);
|
QSGGeometry::updateRectGeometry(&m_default_geometry, m_rect);
|
||||||
|
@ -234,9 +246,6 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ### This part down below is not optimal, using QVectors and reallocation for
|
|
||||||
// every change, but its all going to be fixed up in rewrite...
|
|
||||||
|
|
||||||
QSGGeometry *fill = geometry();
|
QSGGeometry *fill = geometry();
|
||||||
|
|
||||||
// Check that the vertex type matches the material.
|
// Check that the vertex type matches the material.
|
||||||
|
@ -253,9 +262,12 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
int borderVertexCount = 0;
|
int borderVertexCount = 0;
|
||||||
int borderIndexCount = 0;
|
int borderIndexCount = 0;
|
||||||
|
|
||||||
QVector<uchar> fillVertexData;
|
// Preallocate arrays for a rectangle with 18 segments per corner and 3 gradient stops.
|
||||||
QVector<Vertex> borderVertexData;
|
QVarLengthArray<uchar, sizeof(ColorVertex) * (19 * 4 + 3 * 2)> fillVertices;
|
||||||
QVector<ushort> borderIndexData;
|
QVarLengthArray<Vertex, 19 * 8 + 3 * 2> borderVertices;
|
||||||
|
QVarLengthArray<ushort, 19 * 8 + 3 * 4 + 2> borderIndices;
|
||||||
|
int borderIndexHead = 0;
|
||||||
|
int borderIndexTail = 0;
|
||||||
|
|
||||||
Color4ub fillColor = colorToColor4ub(m_fill_material.color());
|
Color4ub fillColor = colorToColor4ub(m_fill_material.color());
|
||||||
const QGradientStops &stops = m_gradient_stops;
|
const QGradientStops &stops = m_gradient_stops;
|
||||||
|
@ -264,19 +276,20 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
// Rounded corners.
|
// Rounded corners.
|
||||||
|
|
||||||
// Radius should never exceeds half of the width or half of the height
|
// Radius should never exceeds half of the width or half of the height
|
||||||
qreal radius = qMin(qMin(m_rect.width() / 2, m_rect.height() / 2), m_radius);
|
qreal radius = qMin(qMin(m_rect.width() * qreal(0.5), m_rect.height() * qreal(0.5)), m_radius);
|
||||||
QRectF innerRect = m_rect;
|
QRectF innerRect = m_rect;
|
||||||
innerRect.adjust(radius, radius, -radius, -radius);
|
innerRect.adjust(radius, radius, -radius, -radius);
|
||||||
if (m_pen_width & 1) {
|
if (m_aligned && (int(penWidth) & 1)) {
|
||||||
// Pen width is odd, so add the offset as documented.
|
// Pen width is odd, so add the offset as documented.
|
||||||
innerRect.moveLeft(innerRect.left() + qreal(0.5));
|
innerRect.moveLeft(innerRect.left() + qreal(0.5));
|
||||||
innerRect.moveTop(innerRect.top() + qreal(0.5));
|
innerRect.moveTop(innerRect.top() + qreal(0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal innerRadius = radius - m_pen_width * qreal(0.5);
|
qreal innerRadius = radius - penWidth * qreal(0.5);
|
||||||
qreal outerRadius = radius + m_pen_width * qreal(0.5);
|
qreal outerRadius = radius + penWidth * qreal(0.5);
|
||||||
|
|
||||||
int segments = qMin(30, qCeil(outerRadius)); // Number of segments per corner.
|
// Number of segments per corner, approximately one per 3 pixels.
|
||||||
|
int segments = qBound(3, qCeil(outerRadius * (M_PI / 6)), 18);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -292,17 +305,15 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Overestimate the number of vertices and indices, reduce afterwards when the actual numbers are known.
|
// Overestimate the number of vertices and indices, reduce afterwards when the actual numbers are known.
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
// The reason I add extra vertices where the gradient lines intersect the border is
|
// The reason I add extra vertices where the gradient lines intersect the border is
|
||||||
// to avoid pixel sized gaps between the fill and the border caused by floating point
|
// to avoid pixel sized gaps between the fill and the border caused by floating point
|
||||||
// inaccuracies.
|
// inaccuracies.
|
||||||
borderVertexData.resize((segments + 1) * 2 * 4 + m_gradient_stops.size() * 2);
|
borderVertices.resize((segments + 1) * 2 * 4 + m_gradient_stops.size() * 2);
|
||||||
|
borderIndices.resize((segments + 1) * 2 * 4 + m_gradient_stops.size() * 4 + 2);
|
||||||
|
borderIndexHead = borderIndexTail = (borderIndices.count() >> 1) - 1;
|
||||||
}
|
}
|
||||||
fillVertexData.resize(((segments + 1) * 4 + m_gradient_stops.size() * 2) * fill->stride());
|
fillVertices.resize(((segments + 1) * 4 + m_gradient_stops.size() * 2) * fill->stride());
|
||||||
|
|
||||||
Vertex *borderVertices = borderVertexData.data();
|
|
||||||
void *fillVertices = fillVertexData.data(); // Can be Vertex, ColorVertex or TextureVertex.
|
|
||||||
|
|
||||||
|
|
||||||
int nextGradientStop = 0;
|
int nextGradientStop = 0;
|
||||||
qreal gradientPos = (radius - innerRadius) / (innerRect.height() + 2 * radius);
|
qreal gradientPos = (radius - innerRadius) / (innerRect.height() + 2 * radius);
|
||||||
|
@ -313,18 +324,26 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
qreal plx = 0; // previous inner left x-coordinate.
|
qreal plx = 0; // previous inner left x-coordinate.
|
||||||
qreal prx = 0; // previous inner right x-coordinate.
|
qreal prx = 0; // previous inner right x-coordinate.
|
||||||
|
|
||||||
|
qreal angle = qreal(0.5) * M_PI / qreal(segments);
|
||||||
|
qreal cosStep = qFastCos(angle);
|
||||||
|
qreal sinStep = qFastSin(angle);
|
||||||
|
|
||||||
for (int part = 0; part < 2; ++part) {
|
for (int part = 0; part < 2; ++part) {
|
||||||
|
qreal c = 1 - part;
|
||||||
|
qreal s = part;
|
||||||
for (int i = 0; i <= segments; ++i) {
|
for (int i = 0; i <= segments; ++i) {
|
||||||
//### Should change to calculate sin/cos only once.
|
|
||||||
qreal angle = qreal(0.5 * M_PI) * (part + i / qreal(segments));
|
|
||||||
qreal s = qFastSin(angle);
|
|
||||||
qreal c = qFastCos(angle);
|
|
||||||
qreal y = (part ? innerRect.bottom() : innerRect.top()) - innerRadius * c; // current inner y-coordinate.
|
qreal y = (part ? innerRect.bottom() : innerRect.top()) - innerRadius * c; // current inner y-coordinate.
|
||||||
qreal lx = innerRect.left() - innerRadius * s; // current inner left x-coordinate.
|
qreal lx = innerRect.left() - innerRadius * s; // current inner left x-coordinate.
|
||||||
qreal rx = innerRect.right() + innerRadius * s; // current inner right x-coordinate.
|
qreal rx = innerRect.right() + innerRadius * s; // current inner right x-coordinate.
|
||||||
qreal Y = (part ? innerRect.bottom() : innerRect.top()) - outerRadius * c; // current outer y-coordinate.
|
qreal Y = (part ? innerRect.bottom() : innerRect.top()) - outerRadius * c; // current outer y-coordinate.
|
||||||
qreal lX = innerRect.left() - outerRadius * s; // current outer left x-coordinate.
|
qreal lX = innerRect.left() - outerRadius * s; // current outer left x-coordinate.
|
||||||
qreal rX = innerRect.right() + outerRadius * s; // current outer right x-coordinate.
|
qreal rX = innerRect.right() + outerRadius * s; // current outer right x-coordinate.
|
||||||
|
{
|
||||||
|
// Rotate
|
||||||
|
qreal tmp = c;
|
||||||
|
c = c * cosStep - s * sinStep;
|
||||||
|
s = s * cosStep + tmp * sinStep;
|
||||||
|
}
|
||||||
|
|
||||||
gradientPos = ((part ? innerRect.height() : 0) + radius - innerRadius * c) / (innerRect.height() + 2 * radius);
|
gradientPos = ((part ? innerRect.height() : 0) + radius - innerRadius * c) / (innerRect.height() + 2 * radius);
|
||||||
while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos) {
|
while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos) {
|
||||||
|
@ -335,20 +354,20 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
qreal glx = plx * (1 - t) + t * lx;
|
qreal glx = plx * (1 - t) + t * lx;
|
||||||
qreal grx = prx * (1 - t) + t * rx;
|
qreal grx = prx * (1 - t) + t * rx;
|
||||||
|
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(grx, gy);
|
borderVertices[borderVertexCount++].position = QVector2D(grx, gy);
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(glx, gy);
|
borderVertices[borderVertexCount++].position = QVector2D(glx, gy);
|
||||||
|
|
||||||
int first = borderIndexData.first();
|
int first = borderIndices[borderIndexHead];
|
||||||
borderIndexData.prepend(borderVertexCount - 1);
|
borderIndices[--borderIndexHead] = borderVertexCount - 1;
|
||||||
borderIndexData.prepend(first);
|
borderIndices[--borderIndexHead] = first;
|
||||||
|
|
||||||
int last = borderIndexData.at(borderIndexData.size() - 2);
|
int last = borderIndices[borderIndexTail - 2];
|
||||||
borderIndexData.append(last);
|
borderIndices[borderIndexTail++] = last;
|
||||||
borderIndexData.append(borderVertexCount - 2);
|
borderIndices[borderIndexTail++] = borderVertexCount - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorVertex *vertices = (ColorVertex *)fillVertices;
|
ColorVertex *vertices = (ColorVertex *)fillVertices.data();
|
||||||
|
|
||||||
fillColor = colorToColor4ub(stops.at(nextGradientStop).second);
|
fillColor = colorToColor4ub(stops.at(nextGradientStop).second);
|
||||||
vertices[fillVertexCount].position = QVector2D(grx, gy);
|
vertices[fillVertexCount].position = QVector2D(grx, gy);
|
||||||
|
@ -361,21 +380,21 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
++nextGradientStop;
|
++nextGradientStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(rX, Y);
|
borderVertices[borderVertexCount++].position = QVector2D(rX, Y);
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(lX, Y);
|
borderVertices[borderVertexCount++].position = QVector2D(lX, Y);
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(rx, y);
|
borderVertices[borderVertexCount++].position = QVector2D(rx, y);
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(lx, y);
|
borderVertices[borderVertexCount++].position = QVector2D(lx, y);
|
||||||
|
|
||||||
borderIndexData.prepend(borderVertexCount - 1);
|
borderIndices[--borderIndexHead] = borderVertexCount - 1;
|
||||||
borderIndexData.prepend(borderVertexCount - 3);
|
borderIndices[--borderIndexHead] = borderVertexCount - 3;
|
||||||
borderIndexData.append(borderVertexCount - 4);
|
borderIndices[borderIndexTail++] = borderVertexCount - 4;
|
||||||
borderIndexData.append(borderVertexCount - 2);
|
borderIndices[borderIndexTail++] = borderVertexCount - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stops.isEmpty()) {
|
if (stops.isEmpty()) {
|
||||||
Q_ASSERT(m_material_type == TypeFlat);
|
Q_ASSERT(m_material_type == TypeFlat);
|
||||||
Vertex *vertices = (Vertex *)fillVertices;
|
Vertex *vertices = (Vertex *)fillVertices.data();
|
||||||
vertices[fillVertexCount++].position = QVector2D(rx, y);
|
vertices[fillVertexCount++].position = QVector2D(rx, y);
|
||||||
vertices[fillVertexCount++].position = QVector2D(lx, y);
|
vertices[fillVertexCount++].position = QVector2D(lx, y);
|
||||||
} else {
|
} else {
|
||||||
|
@ -390,7 +409,7 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
fillColor = (colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t);
|
fillColor = (colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorVertex *vertices = (ColorVertex *)fillVertices;
|
ColorVertex *vertices = (ColorVertex *)fillVertices.data();
|
||||||
vertices[fillVertexCount].position = QVector2D(rx, y);
|
vertices[fillVertexCount].position = QVector2D(rx, y);
|
||||||
vertices[fillVertexCount].color = fillColor;
|
vertices[fillVertexCount].color = fillColor;
|
||||||
++fillVertexCount;
|
++fillVertexCount;
|
||||||
|
@ -405,15 +424,14 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (penWidth) {
|
||||||
if (m_pen_width) {
|
|
||||||
// Close border.
|
// Close border.
|
||||||
ushort first = borderIndexData.at(0);
|
ushort first = borderIndices[borderIndexHead];
|
||||||
ushort second = borderIndexData.at(1);
|
ushort second = borderIndices[borderIndexHead + 1];
|
||||||
borderIndexData.append(first);
|
borderIndices[borderIndexTail++] = first;
|
||||||
borderIndexData.append(second);
|
borderIndices[borderIndexTail++] = second;
|
||||||
|
|
||||||
borderIndexCount = borderIndexData.size();
|
borderIndexCount = borderIndexTail - borderIndexHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -423,27 +441,23 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
QRectF outerRect = m_rect;
|
QRectF outerRect = m_rect;
|
||||||
|
|
||||||
qreal halfPenWidth = 0;
|
qreal halfPenWidth = 0;
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
if (m_pen_width & 1) {
|
if (m_aligned && (int(penWidth) & 1)) {
|
||||||
// Pen width is odd, so add the offset as documented.
|
// Pen width is odd, so add the offset as documented.
|
||||||
innerRect.moveLeft(innerRect.left() + qreal(0.5));
|
innerRect.moveLeft(innerRect.left() + qreal(0.5));
|
||||||
innerRect.moveTop(innerRect.top() + qreal(0.5));
|
innerRect.moveTop(innerRect.top() + qreal(0.5));
|
||||||
outerRect = innerRect;
|
outerRect = innerRect;
|
||||||
}
|
}
|
||||||
halfPenWidth = m_pen_width * qreal(0.5);
|
halfPenWidth = penWidth * qreal(0.5);
|
||||||
innerRect.adjust(halfPenWidth, halfPenWidth, -halfPenWidth, -halfPenWidth);
|
innerRect.adjust(halfPenWidth, halfPenWidth, -halfPenWidth, -halfPenWidth);
|
||||||
outerRect.adjust(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
outerRect.adjust(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
borderVertexData.resize((2 + stops.size()) * 2 + 4);
|
borderVertices.resize((2 + stops.size()) * 2 + 4);
|
||||||
borderIndexData.resize((2 + stops.size()) * 2 * 2 + 4);
|
borderIndices.resize((2 + stops.size()) * 2 * 2 + 4);
|
||||||
}
|
}
|
||||||
fillVertexData.resize((2 + stops.size()) * 2 * fill->stride());
|
fillVertices.resize((2 + stops.size()) * 2 * fill->stride());
|
||||||
|
|
||||||
void *fillVertices = fillVertexData.data();
|
|
||||||
Vertex *borderVertices = (Vertex *) borderVertexData.data();
|
|
||||||
ushort *borderIndices = borderIndexData.data();
|
|
||||||
|
|
||||||
int nextGradientStop = 0;
|
int nextGradientStop = 0;
|
||||||
qreal gradientPos = halfPenWidth / m_rect.height();
|
qreal gradientPos = halfPenWidth / m_rect.height();
|
||||||
|
@ -459,7 +473,7 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
qreal gy = (innerRect.top() - halfPenWidth) + stops.at(nextGradientStop).first * m_rect.height();
|
qreal gy = (innerRect.top() - halfPenWidth) + stops.at(nextGradientStop).first * m_rect.height();
|
||||||
Q_ASSERT(fillVertexCount >= 2);
|
Q_ASSERT(fillVertexCount >= 2);
|
||||||
|
|
||||||
ColorVertex *vertices = (ColorVertex *)fillVertices;
|
ColorVertex *vertices = (ColorVertex *)fillVertices.data();
|
||||||
|
|
||||||
fillColor = colorToColor4ub(stops.at(nextGradientStop).second);
|
fillColor = colorToColor4ub(stops.at(nextGradientStop).second);
|
||||||
vertices[fillVertexCount].position = QVector2D(innerRect.right(), gy);
|
vertices[fillVertexCount].position = QVector2D(innerRect.right(), gy);
|
||||||
|
@ -469,7 +483,7 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
vertices[fillVertexCount].color = fillColor;
|
vertices[fillVertexCount].color = fillColor;
|
||||||
++fillVertexCount;
|
++fillVertexCount;
|
||||||
|
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(innerRect.right(), gy);
|
borderVertices[borderVertexCount++].position = QVector2D(innerRect.right(), gy);
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(innerRect.left(), gy);
|
borderVertices[borderVertexCount++].position = QVector2D(innerRect.left(), gy);
|
||||||
}
|
}
|
||||||
|
@ -479,7 +493,7 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
|
|
||||||
if (stops.isEmpty()) {
|
if (stops.isEmpty()) {
|
||||||
Q_ASSERT(m_material_type == TypeFlat);
|
Q_ASSERT(m_material_type == TypeFlat);
|
||||||
Vertex *vertices = (Vertex *)fillVertices;
|
Vertex *vertices = (Vertex *)fillVertices.data();
|
||||||
vertices[fillVertexCount++].position = QVector2D(innerRect.right(), y);
|
vertices[fillVertexCount++].position = QVector2D(innerRect.right(), y);
|
||||||
vertices[fillVertexCount++].position = QVector2D(innerRect.left(), y);
|
vertices[fillVertexCount++].position = QVector2D(innerRect.left(), y);
|
||||||
} else {
|
} else {
|
||||||
|
@ -494,7 +508,7 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
fillColor = (colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t);
|
fillColor = (colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorVertex *vertices = (ColorVertex *)fillVertices;
|
ColorVertex *vertices = (ColorVertex *)fillVertices.data();
|
||||||
vertices[fillVertexCount].position = QVector2D(innerRect.right(), y);
|
vertices[fillVertexCount].position = QVector2D(innerRect.right(), y);
|
||||||
vertices[fillVertexCount].color = fillColor;
|
vertices[fillVertexCount].color = fillColor;
|
||||||
++fillVertexCount;
|
++fillVertexCount;
|
||||||
|
@ -503,13 +517,13 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
++fillVertexCount;
|
++fillVertexCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(innerRect.right(), y);
|
borderVertices[borderVertexCount++].position = QVector2D(innerRect.right(), y);
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(innerRect.left(), y);
|
borderVertices[borderVertexCount++].position = QVector2D(innerRect.left(), y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
// Add four corners.
|
// Add four corners.
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(outerRect.right(), outerRect.top());
|
borderVertices[borderVertexCount++].position = QVector2D(outerRect.right(), outerRect.top());
|
||||||
borderVertices[borderVertexCount++].position = QVector2D(outerRect.left(), outerRect.top());
|
borderVertices[borderVertexCount++].position = QVector2D(outerRect.left(), outerRect.top());
|
||||||
|
@ -531,15 +545,15 @@ void QSGDefaultRectangleNode::updateGeometry()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy from temporary datastructures to geometry...
|
// Copy from temporary datastructures to geometry...
|
||||||
if (m_pen_width) {
|
if (penWidth) {
|
||||||
borderGeometry->allocate(borderVertexCount, borderIndexCount);
|
borderGeometry->allocate(borderVertexCount, borderIndexCount);
|
||||||
memcpy(borderGeometry->indexData(), borderIndexData.constData(), borderIndexCount * sizeof(quint16));
|
memcpy(borderGeometry->indexData(), borderIndices.constData() + borderIndexHead, borderIndexCount * sizeof(quint16));
|
||||||
memcpy(borderGeometry->vertexData(), borderVertexData.constData(), borderVertexCount * sizeof(Vertex));
|
memcpy(borderGeometry->vertexData(), borderVertices.constData(), borderVertexCount * sizeof(Vertex));
|
||||||
m_border->markDirty(DirtyGeometry);
|
m_border->markDirty(DirtyGeometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
fill->allocate(fillVertexCount);
|
fill->allocate(fillVertexCount);
|
||||||
memcpy(fill->vertexData(), fillVertexData.constData(), fillVertexCount * fill->stride());
|
memcpy(fill->vertexData(), fillVertices.constData(), fillVertexCount * fill->stride());
|
||||||
|
|
||||||
markDirty(DirtyGeometry);
|
markDirty(DirtyGeometry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ public:
|
||||||
virtual void setPenWidth(qreal width);
|
virtual void setPenWidth(qreal width);
|
||||||
virtual void setGradientStops(const QGradientStops &stops);
|
virtual void setGradientStops(const QGradientStops &stops);
|
||||||
virtual void setRadius(qreal radius);
|
virtual void setRadius(qreal radius);
|
||||||
|
virtual void setAligned(bool aligned);
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -87,8 +88,9 @@ private:
|
||||||
QRectF m_rect;
|
QRectF m_rect;
|
||||||
QGradientStops m_gradient_stops;
|
QGradientStops m_gradient_stops;
|
||||||
qreal m_radius;
|
qreal m_radius;
|
||||||
int m_pen_width;
|
qreal m_pen_width;
|
||||||
|
|
||||||
|
uint m_aligned : 1;
|
||||||
uint m_gradient_is_opaque : 1;
|
uint m_gradient_is_opaque : 1;
|
||||||
uint m_dirty_geometry : 1;
|
uint m_dirty_geometry : 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue