6#include <QtCore/qmath.h>
23 c.getRgbF(&
r, &
g, &
b, &
a);
38 void set(
float primary,
float secondary,
Color4ub ncolor,
bool vertical)
41 x = secondary;
y = primary;
43 x = primary;
y = secondary;
53 void set(
float primary,
float secondary,
Color4ub ncolor,
float dPrimary,
float dSecondary,
bool vertical)
55 Vertex::set(primary, secondary, ncolor, vertical);
57 dx = dSecondary; dy = dPrimary;
59 dx = dPrimary; dy = dSecondary;
79 , m_antialiasing(
false)
80 , m_gradient_is_opaque(true)
81 , m_dirty_geometry(
false)
82 , m_gradient_is_vertical(true)
83 , m_geometry(
QSGGeometry::defaultAttributes_ColoredPoint2D(), 0)
87#ifdef QSG_RUNTIME_DESCRIPTION
135 for (
int i = 0;
i < stops.
size(); ++
i)
232 penWidth =
qRound(penWidth);
236 int vertexStride =
g->sizeOfVertex();
240 SmoothVertex *smoothVertices;
245 Color4ub transparent = { 0, 0, 0, 0 };
252 int nextGradientStop = 0;
253 float gradientPos = penWidth / gradientLength;
254 while (nextGradientStop < stops.
size() && stops.
at(nextGradientStop).first <= gradientPos)
256 int lastGradientStop = stops.
size() - 1;
257 float lastGradientPos = 1.0f - penWidth / gradientLength;
258 while (lastGradientStop >= nextGradientStop && stops.
at(lastGradientStop).first >= lastGradientPos)
260 int gradientIntersections = (lastGradientStop - nextGradientStop + 1);
288 const float innerRadiusTL =
qMax(radiusTL - penWidth * 1.0f, 0.01);
289 const float innerRadiusTR =
qMax(radiusTR - penWidth * 1.0f, 0.01);
290 const float innerRadiusBL =
qMax(radiusBL - penWidth * 1.0f, 0.01);
291 const float innerRadiusBR =
qMax(radiusBR - penWidth * 1.0f, 0.01);
292 const float outerRadiusTL = radiusTL;
293 const float outerRadiusTR = radiusTR;
294 const float outerRadiusBL = radiusBL;
295 const float outerRadiusBR = radiusBR;
298 int segmentsTL = radiusTL == 0 ? 0 :
qBound(3,
qCeil(radiusTL * (
M_PI / 6)), 18);
299 int segmentsTR = radiusTR == 0 ? 0 :
qBound(3,
qCeil(radiusTR * (
M_PI / 6)), 18);
300 int segmentsBL = radiusBL == 0 ? 0 :
qBound(3,
qCeil(radiusBL * (
M_PI / 6)), 18);
301 int segmentsBR = radiusBR == 0 ? 0 :
qBound(3,
qCeil(radiusBR * (
M_PI / 6)), 18);
307 if (innerRadiusTL == innerRadiusTR) {
308 if (segmentsTL <= segmentsTR)
313 if (innerRadiusBL == innerRadiusBR){
314 if (segmentsBL <= segmentsBR)
320 if (innerRadiusTL == innerRadiusBL) {
321 if (segmentsTL <= segmentsBL)
326 if (innerRadiusTR == innerRadiusBR) {
327 if (segmentsTR <= segmentsBR)
334 const int sumSegments = segmentsTL + segmentsTR + segmentsBL + segmentsBR;
356 const int innerVertexCount = (sumSegments + 4) * 2 + gradientIntersections * 2;
357 const int outerVertexCount = (sumSegments + 4) * 2;
358 int vertexCount = innerVertexCount;
360 vertexCount += innerVertexCount;
362 vertexCount += outerVertexCount;
364 vertexCount += outerVertexCount;
367 const int fillIndexCount = innerVertexCount;
368 const int innerAAIndexCount = innerVertexCount * 2 + 2;
369 const int borderIndexCount = innerVertexCount * 2 + 2;
370 const int outerAAIndexCount = outerVertexCount * 2 + 2;
381 indexCount += fillIndexCount;
383 innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1;
384 indexCount += innerAAIndexCount;
387 borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1;
388 indexCount += borderIndexCount;
391 outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1;
392 indexCount += outerAAIndexCount;
395 g->allocate(vertexCount, indexCount);
396 vertices =
reinterpret_cast<Vertex *
>(
g->vertexData());
397 memset(vertices, 0, vertexCount * vertexStride);
402 float innerXPrev = 0.;
403 float innerYLeftPrev = 0.;
404 float innerYRightPrev = 0.;
406 const float angleTL = 0.5f * float(
M_PI) / segmentsTL;
407 const float cosStepTL =
qFastCos(angleTL);
408 const float sinStepTL =
qFastSin(angleTL);
409 const float angleTR = 0.5f * float(
M_PI) / segmentsTR;
410 const float cosStepTR =
qFastCos(angleTR);
411 const float sinStepTR =
qFastSin(angleTR);
412 const float angleBL = 0.5f * float(
M_PI) / segmentsBL;
413 const float cosStepBL =
qFastCos(angleBL);
414 const float sinStepBL =
qFastSin(angleBL);
415 const float angleBR = 0.5f * float(
M_PI) / segmentsBR;
416 const float cosStepBR =
qFastCos(angleBR);
417 const float sinStepBR =
qFastSin(angleBR);
449 const float outerXCenter[][2] = {{
457 const float outerYCenter[][2] = {{
465 const float innerXCenter[][2] = { {
473 const float innerYCenter[][2] = { {
481 const float innerRadius[][2] = {{
489 const float outerRadius[][2] = {{
505 const float cosStep[][2] = {{
513 const float sinStep[][2] = {{
521 auto fillColorFromX = [&](
float x) {
523 float t = (
x - gradientStart) / gradientLength;
527 while (
i < stops.
size()) {
530 if (prev.first <=
t &&
next.first >
t) {
531 t = (
t - prev.first) / (
next.first - prev.first);
538 for (
int part = 0; part < 2; ++part) {
540 float cosSegmentAngleLeft = 1. - part;
542 float sinSegmentAngleLeft = part;
544 float cosSegmentAngleRight = 1. - part;
545 float sinSegmentAngleRight = part;
547 bool advanceLeft =
true;
552 for (
int iLeft = 0, iRight = 0; iLeft <=
segments[part][0] || iRight <=
segments[part][1]; ) {
557 float outerXLeft, outerYLeft,
558 outerXRight, outerYRight;
560 float sinAngleLeft, cosAngleLeft,
561 sinAngleRight, cosAngleRight;
564 xLeft = innerXCenter[part][0] - innerRadius[part][0] * cosSegmentAngleLeft;
565 xRight = innerXCenter[part][1] - innerRadius[part][1] * cosSegmentAngleRight;
568 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinSegmentAngleLeft;
569 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinSegmentAngleRight;
575 if ((iLeft <=
segments[part][0] && xLeft <= xRight) || iRight >
segments[part][1]) {
584 if (innerRadius[part][0] == innerRadius[part][1]) {
589 if (outerRadius[part][0] == 0) {
591 cosAngleLeft = part ? -1. : 1.;
593 sinAngleLeft = sinSegmentAngleLeft;
594 cosAngleLeft = cosSegmentAngleLeft;
596 if (outerRadius[part][1] == 0) {
598 cosAngleRight = part ? -1. : 1.;
600 sinAngleRight = sinSegmentAngleLeft;
601 cosAngleRight = cosSegmentAngleLeft;
604 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
606 if (outerRadius[part][0] == 0) {
608 cosAngleLeft = part ? -1. : 1.;
610 sinAngleLeft = sinSegmentAngleRight;
611 cosAngleLeft = cosSegmentAngleRight;
613 if (outerRadius[part][1] == 0) {
615 cosAngleRight = part ? -1. : 1.;
617 sinAngleRight = sinSegmentAngleRight;
618 cosAngleRight = cosSegmentAngleRight;
621 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
623 }
else if (advanceLeft) {
624 if (outerRadius[part][0] == 0) {
626 cosAngleLeft = part ? -1. : 1.;
628 sinAngleLeft = sinSegmentAngleLeft;
629 cosAngleLeft = cosSegmentAngleLeft;
631 if (outerRadius[part][1] == 0) {
636 cosAngleRight = part ? -1. : 1.;
638 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
639 }
else if (xLeft >= innerXCenter[0][1] && xLeft <= innerXCenter[1][1]) {
646 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
653 if (xRight != innerXPrev) {
654 float t = (xLeft - innerXPrev) / (xRight - innerXPrev);
655 yRight = innerYRightPrev * (1. -
t) + yRight *
t;
660 sinAngleRight = (yRight - innerYCenter[part][1]) / innerRadius[part][1];
661 cosAngleRight = -(xRight - innerXCenter[part][1]) / innerRadius[part][1];
665 if (outerRadius[part][1] == 0) {
667 cosAngleRight = part ? -1. : 1.;
669 sinAngleRight = sinSegmentAngleRight;
670 cosAngleRight = cosSegmentAngleRight;
672 if (outerRadius[part][0] == 0) {
674 cosAngleLeft = part ? -1. : 1.;
676 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
677 }
else if (xRight >= innerXCenter[0][0] && xRight <= innerXCenter[1][0]) {
681 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
683 if (xLeft != innerXPrev) {
684 float t = (xRight - innerXPrev) / (xLeft - innerXPrev);
685 yLeft = innerYLeftPrev * (1. -
t) + yLeft *
t;
688 sinAngleLeft = -(yLeft - innerYCenter[part][0]) / innerRadius[part][0];
689 cosAngleLeft = -(xLeft - innerXCenter[part][0]) / innerRadius[part][0];
693 gradientPos = (xLeft - gradientStart) / gradientLength;
696 outerXLeft = outerXCenter[part][0] - outerRadius[part][0] * cosAngleLeft;
697 outerYLeft = outerYCenter[part][0] - outerRadius[part][0] * sinAngleLeft;
698 outerXRight = outerXCenter[part][1] - outerRadius[part][1] * cosAngleRight;
699 outerYRight = outerYCenter[part][1] + outerRadius[part][1] * sinAngleRight;
702 while (nextGradientStop <= lastGradientStop && stops.
at(nextGradientStop).first <= gradientPos) {
705 float gradientYRight;
708 gradientX = gradientStart + stops.
at(nextGradientStop).first * gradientLength;
710 float t = (gradientX - innerXPrev) / (xLeft - innerXPrev);
711 gradientYLeft = innerYLeftPrev * (1. -
t) +
t * yLeft;
712 gradientYRight = innerYRightPrev * (1. -
t) +
t * yRight;
714 fillColor = fillColorFromX(gradientX);
736 bool lower = stops.
at(nextGradientStop).first > 0.5f;
737 float dp = lower ?
qMin(0.0f, gradientLength - gradientX - delta) :
qMax(0.0f, delta - gradientX);
738 smoothVertices[
index++].set(gradientX, gradientYRight, fillColor, dp, secondaryLength - gradientYRight - delta,
m_gradient_is_vertical);
741 smoothVertices[
index++].set(gradientX, gradientYRight, borderColor, -0.49f * penWidth * cosAngleRight, 0.49f * penWidth * sinAngleRight,
m_gradient_is_vertical);
742 smoothVertices[
index++].set(gradientX, gradientYLeft, borderColor, -0.49f * penWidth * cosAngleLeft, -0.49f * penWidth * sinAngleLeft,
m_gradient_is_vertical);
744 dp = lower ? delta : -delta;
757 innerXPrev = gradientX;
758 innerYLeftPrev = gradientYLeft;
759 innerYRightPrev = gradientYRight;
765 fillColor = fillColorFromX(xLeft);
786 float dp = part ?
qMin(0.0f, gradientLength - xRight - delta) :
qMax(0.0f, delta - xRight);
790 dp = part ? delta : -delta;
792 smoothVertices[
index++].set(xRight, yRight, borderColor, -0.49f * penWidth * cosAngleRight, 0.49f * penWidth * sinAngleRight,
m_gradient_is_vertical);
793 smoothVertices[
index++].set(xLeft, yLeft, borderColor, -0.49f * penWidth * cosAngleLeft, -0.49f * penWidth * sinAngleLeft,
m_gradient_is_vertical);
794 smoothVertices[
index++].set(outerXRight, outerYRight, borderColor, 0.49f * penWidth * cosAngleRight, -0.49f * penWidth * sinAngleRight,
m_gradient_is_vertical);
795 smoothVertices[
index++].set(outerXLeft, outerYLeft, borderColor, 0.49f * penWidth * cosAngleLeft, 0.49f * penWidth * sinAngleLeft,
m_gradient_is_vertical);
819 innerYLeftPrev = yLeft;
820 innerYRightPrev = yRight;
825 qreal tmp = cosSegmentAngleLeft;
826 cosSegmentAngleLeft = cosSegmentAngleLeft * cosStep[part][0] - sinSegmentAngleLeft * sinStep[part][0];
827 sinSegmentAngleLeft = sinSegmentAngleLeft * cosStep[part][0] + tmp * sinStep[part][0];
830 qreal tmp = cosSegmentAngleRight;
831 cosSegmentAngleRight = cosSegmentAngleRight * cosStep[part][1] - sinSegmentAngleRight * sinStep[part][1];
832 sinSegmentAngleRight = sinSegmentAngleRight * cosStep[part][1] + tmp * sinStep[part][1];
843 Q_ASSERT(innerAATail <= indexCount);
853 Q_ASSERT(outerAATail == indexCount);
861 innerRect.
adjust(1.0f * penWidth, 1.0f * penWidth, -1.0f * penWidth, -1.0f * penWidth);
864 int innerVertexCount = 4 + gradientIntersections * 2;
865 int outerVertexCount = 4;
866 int vertexCount = innerVertexCount;
868 vertexCount += innerVertexCount;
870 vertexCount += outerVertexCount;
872 vertexCount += outerVertexCount;
874 int fillIndexCount = innerVertexCount;
875 int innerAAIndexCount = innerVertexCount * 2 + 2;
876 int borderIndexCount = innerVertexCount * 2 + 2;
877 int outerAAIndexCount = outerVertexCount * 2 + 2;
888 indexCount += fillIndexCount;
890 innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1;
891 indexCount += innerAAIndexCount;
894 borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1;
895 indexCount += borderIndexCount;
898 outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1;
899 indexCount += outerAAIndexCount;
902 g->allocate(vertexCount, indexCount);
903 vertices =
reinterpret_cast<Vertex *
>(
g->vertexData());
904 memset(vertices, 0, vertexCount * vertexStride);
918 for (
int part = -1; part <= 1; part += 2) {
919 float innerEdge = (part == 1 ? innerEnd : innerStart);
920 float outerEdge = (part == 1 ? outerEnd : outerStart);
921 gradientPos = (innerEdge - innerStart + penWidth) / gradientLength;
923 while (nextGradientStop <= lastGradientStop && stops.
at(nextGradientStop).first <= gradientPos) {
925 float gp = (innerStart - penWidth) + stops.
at(nextGradientStop).first * gradientLength;
949 bool lower = stops.
at(nextGradientStop).first > 0.5f;
950 float dp = lower ?
qMin(0.0f, gradientLength -
gp - delta) :
qMax(0.0f, delta -
gp);
954 smoothVertices[
index++].set(
gp, innerSecondaryEnd, borderColor, (lower ? 0.49f : -0.49f) * penWidth, 0.49f * penWidth,
m_gradient_is_vertical);
955 smoothVertices[
index++].set(
gp, innerSecondaryStart, borderColor, (lower ? 0.49f : -0.49f) * penWidth, -0.49f * penWidth,
m_gradient_is_vertical);
972 if (nextGradientStop == 0) {
974 }
else if (nextGradientStop == stops.
size()) {
979 float t = (gradientPos - prev.first) / (
next.first - prev.first);
1002 float dp = part == 1 ?
qMin(0.0f, gradientLength - innerEdge - delta) :
qMax(0.0f, delta - innerEdge);
1003 smoothVertices[
index++].set(innerEdge, innerSecondaryEnd, fillColor, dp, secondaryLength - innerSecondaryEnd - delta,
m_gradient_is_vertical);
1007 smoothVertices[
index++].set(innerEdge, innerSecondaryEnd, borderColor, 0.49f * penWidth * part, 0.49f * penWidth,
m_gradient_is_vertical);
1008 smoothVertices[
index++].set(innerEdge, innerSecondaryStart, borderColor, 0.49f * penWidth * part, -0.49f * penWidth,
m_gradient_is_vertical);
1009 smoothVertices[
index++].set(outerEdge, outerSecondaryEnd, borderColor, -0.49f * penWidth * part, -0.49f * penWidth,
m_gradient_is_vertical);
1010 smoothVertices[
index++].set(outerEdge, outerSecondaryStart, borderColor, -0.49f * penWidth * part, 0.49f * penWidth,
m_gradient_is_vertical);
1039 Q_ASSERT(innerAATail <= indexCount);
1044 Q_ASSERT(borderTail <= indexCount);
1049 Q_ASSERT(outerAATail == indexCount);
The QColor class provides colors based on RGB, HSV or CMYK values.
int alpha() const noexcept
Returns the alpha color component of this color.
qsizetype size() const noexcept
const_pointer constData() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
\inmodule QtCore\reentrant
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr void adjust(qreal x1, qreal y1, qreal x2, qreal y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
const QSGGeometry * geometry() const
Returns this node's geometry.
void setGeometry(QSGGeometry *geometry)
Sets the geometry of this node to geometry.
virtual void updateMaterialAntialiasing()=0
QSGBasicInternalRectangleNode()
void setRadius(qreal radius) override
void setBottomLeftRadius(qreal radius) override
void setGradientVertical(bool vertical) override
void setPenWidth(qreal width) override
void setTopRightRadius(qreal radius) override
float m_bottomRightRadius
QGradientStops m_gradient_stops
void setTopLeftRadius(qreal radius) override
uint m_gradient_is_opaque
void setAligned(bool aligned) override
void setPenColor(const QColor &color) override
void setColor(const QColor &color) override
virtual void updateMaterialBlending(QSGNode::DirtyState *state)=0
void setRect(const QRectF &rect) override
uint m_gradient_is_vertical
void setAntialiasing(bool antialiasing) override
virtual bool supportsAntialiasing() const
void setBottomRightRadius(qreal radius) override
void setGradientStops(const QGradientStops &stops) override
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
void markDirty(DirtyState bits)
Notifies all connected renderers that the node has dirty bits.
void setFlag(Flag, bool=true)
Sets the flag f on this node if enabled is true; otherwise clears the flag.
Combined button and popup list for selecting options.
const QSGGeometry::AttributeSet & smoothAttributeSet()
QPair< qreal, QColor > QGradientStop
constexpr timespec operator+(const timespec &t1, const timespec &t2)
constexpr timespec operator*(const timespec &t1, int mul)
static struct AttrInfo attrs[]
int qRound(qfloat16 d) noexcept
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei GLenum const void * indices
static QQuickShapeGenericRenderer::Color4ub colorToColor4ub(const QColor &c)
Int aligned(Int v, Int byteAlign)
void qsgnode_set_description(QSGNode *node, const QString &description)
QLatin1StringView QLatin1String
The QSGGeometry::AttributeSet describes how the vertices in a QSGGeometry are built up.
The QSGGeometry::Attribute describes a single vertex attribute in a QSGGeometry.
static Attribute createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType)
Creates a new QSGGeometry::Attribute for attribute register pos with tupleSize.
void set(float primary, float secondary, Color4ub ncolor, float dPrimary, float dSecondary, bool vertical)
void set(float primary, float secondary, Color4ub ncolor, bool vertical)
\qmltype MapCircle \instantiates QDeclarativeCircleMapItem \inqmlmodule QtLocation