225void QSGBasicInternalRectangleNode::updateGeometry()
227 float width =
float(m_rect.width());
228 float height =
float(m_rect.height());
229 float penWidth = qMin(qMin(width, height) * 0.5f,
float(m_pen_width));
232 penWidth = qRound(penWidth);
234 QSGGeometry *g = geometry();
235 g->setDrawingMode(QSGGeometry::DrawTriangleStrip);
236 int vertexStride = g->sizeOfVertex();
240 SmoothVertex *smoothVertices;
243 Color4ub fillColor = colorToColor4ub(m_color);
244 Color4ub borderColor = colorToColor4ub(m_border_color);
245 Color4ub transparent = { 0, 0, 0, 0 };
246 const QGradientStops &stops = m_gradient_stops;
248 float gradientStart = (m_gradient_is_vertical ? m_rect.top() : m_rect.left());
249 float gradientLength = (m_gradient_is_vertical ? height : width);
250 float secondaryLength = (m_gradient_is_vertical ? width : height);
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);
263 || m_topLeftRadius > 0
264 || m_topRightRadius > 0
265 || m_bottomLeftRadius > 0
266 || m_bottomRightRadius > 0) {
270 float radiusTL = qMin(qMin(width, height) * 0.4999f,
float(m_topLeftRadius < 0 ? m_radius : m_topLeftRadius));
271 float radiusTR = qMin(qMin(width, height) * 0.4999f,
float(m_topRightRadius < 0 ? m_radius : m_topRightRadius));
272 float radiusBL = qMin(qMin(width, height) * 0.4999f,
float(m_bottomLeftRadius < 0 ? m_radius : m_bottomLeftRadius));
273 float radiusBR = qMin(qMin(width, height) * 0.4999f,
float(m_bottomRightRadius < 0 ? m_radius : m_bottomRightRadius));
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;
296 const float delta = qMin(width, height) * 0.5f;
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);
306 if (m_gradient_is_vertical) {
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;
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
356 const int innerVertexCount = (sumSegments + 4) * 2 + gradientIntersections * 2;
357 const int outerVertexCount = (sumSegments + 4) * 2;
358 int vertexCount = innerVertexCount;
359 if (m_antialiasing || penWidth)
360 vertexCount += innerVertexCount;
362 vertexCount += outerVertexCount;
363 if (m_antialiasing && penWidth)
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;
379 bool hasFill = m_color.alpha() > 0 || !stops.isEmpty();
381 indexCount += fillIndexCount;
382 if (m_antialiasing) {
383 innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1;
384 indexCount += innerAAIndexCount;
387 borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1;
388 indexCount += borderIndexCount;
390 if (m_antialiasing && penWidth) {
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);
398 quint16 *indices = g->indexDataAsUShort();
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] = {{
450 float(m_gradient_is_vertical ? m_rect.top() + radiusTL : m_rect.left() + radiusTL),
451 float(m_gradient_is_vertical ? m_rect.top() + radiusTR : m_rect.left() + radiusBL)
453 float(m_gradient_is_vertical ? m_rect.bottom() - radiusBL : m_rect.right() - radiusTR),
454 float(m_gradient_is_vertical ? m_rect.bottom() - radiusBR : m_rect.right() - radiusBR)
457 const float outerYCenter[][2] = {{
458 float(!m_gradient_is_vertical ? m_rect.top() + outerRadiusTL : m_rect.left() + outerRadiusTL),
459 float(!m_gradient_is_vertical ? m_rect.bottom() - outerRadiusBL : m_rect.right() - outerRadiusTR)
461 float(!m_gradient_is_vertical ? m_rect.top() + outerRadiusTR : m_rect.left() + outerRadiusBL),
462 float(!m_gradient_is_vertical ? m_rect.bottom() - outerRadiusBR : m_rect.right() - outerRadiusBR)
465 const float innerXCenter[][2] = { {
466 float(m_gradient_is_vertical ? m_rect.top() + innerRadiusTL + penWidth : m_rect.left() + innerRadiusTL + penWidth),
467 float(m_gradient_is_vertical ? m_rect.top() + innerRadiusTR + penWidth: m_rect.left() + innerRadiusBL + penWidth)
469 float(m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBL - penWidth: m_rect.right() - innerRadiusTR - penWidth),
470 float(m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBR - penWidth: m_rect.right() - innerRadiusBR - penWidth)
473 const float innerYCenter[][2] = { {
474 float(!m_gradient_is_vertical ? m_rect.top() + innerRadiusTL + penWidth : m_rect.left() + innerRadiusTL + penWidth),
475 float(!m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBL - penWidth : m_rect.right() - innerRadiusTR - penWidth)
477 float(!m_gradient_is_vertical ? m_rect.top() + innerRadiusTR + penWidth : m_rect.left() + innerRadiusBL + penWidth),
478 float(!m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBR - penWidth : m_rect.right() - innerRadiusBR - penWidth)
481 const float innerRadius[][2] = {{
483 !m_gradient_is_vertical ? innerRadiusBL : innerRadiusTR
485 !m_gradient_is_vertical ? innerRadiusTR : innerRadiusBL,
489 const float outerRadius[][2] = {{
491 !m_gradient_is_vertical ? outerRadiusBL : outerRadiusTR
493 !m_gradient_is_vertical ? outerRadiusTR : outerRadiusBL,
497 const int segments[][2] = {{
499 !m_gradient_is_vertical ? segmentsBL : segmentsTR
501 !m_gradient_is_vertical ? segmentsTR : segmentsBL,
505 const float cosStep[][2] = {{
507 !m_gradient_is_vertical ? cosStepBL : cosStepTR
509 !m_gradient_is_vertical ? cosStepTR : cosStepBL,
513 const float sinStep[][2] = {{
515 !m_gradient_is_vertical ? sinStepBL : sinStepTR
517 !m_gradient_is_vertical ? sinStepTR : sinStepBL,
521 auto fillColorFromX = [&](
float x) {
523 float t = (x - gradientStart) / gradientLength;
524 t = qBound(0.0, t, 1.0);
527 if (t < stops.first().first)
528 return colorToColor4ub(stops.first().second);
529 while (i < stops.size()) {
530 const QGradientStop &prev = stops.at(i - 1);
531 const QGradientStop &next = stops.at(i);
532 if (prev.first <= t && next.first > t) {
533 t = (t - prev.first) / (next.first - prev.first);
534 return colorToColor4ub(prev.second) * (1. - t) + colorToColor4ub(next.second) * t; }
537 return colorToColor4ub(stops.last().second);
540 for (
int part = 0; part < 2; ++part) {
542 float cosSegmentAngleLeft = 1. - part;
544 float sinSegmentAngleLeft = part;
546 float cosSegmentAngleRight = 1. - part;
547 float sinSegmentAngleRight = part;
549 bool advanceLeft =
true;
554 for (
int iLeft = 0, iRight = 0; iLeft <= segments[part][0] || iRight <= segments[part][1]; ) {
559 float outerXLeft, outerYLeft,
560 outerXRight, outerYRight;
562 float sinAngleLeft, cosAngleLeft,
563 sinAngleRight, cosAngleRight;
566 xLeft = innerXCenter[part][0] - innerRadius[part][0] * cosSegmentAngleLeft;
567 xRight = innerXCenter[part][1] - innerRadius[part][1] * cosSegmentAngleRight;
570 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinSegmentAngleLeft;
571 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinSegmentAngleRight;
577 if ((iLeft <= segments[part][0] && xLeft <= xRight) || iRight > segments[part][1]) {
586 if (innerRadius[part][0] == innerRadius[part][1]) {
591 if (outerRadius[part][0] == 0) {
593 cosAngleLeft = part ? -1. : 1.;
595 sinAngleLeft = sinSegmentAngleLeft;
596 cosAngleLeft = cosSegmentAngleLeft;
598 if (outerRadius[part][1] == 0) {
600 cosAngleRight = part ? -1. : 1.;
602 sinAngleRight = sinSegmentAngleLeft;
603 cosAngleRight = cosSegmentAngleLeft;
606 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
608 if (outerRadius[part][0] == 0) {
610 cosAngleLeft = part ? -1. : 1.;
612 sinAngleLeft = sinSegmentAngleRight;
613 cosAngleLeft = cosSegmentAngleRight;
615 if (outerRadius[part][1] == 0) {
617 cosAngleRight = part ? -1. : 1.;
619 sinAngleRight = sinSegmentAngleRight;
620 cosAngleRight = cosSegmentAngleRight;
623 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
625 }
else if (advanceLeft) {
626 if (outerRadius[part][0] == 0) {
628 cosAngleLeft = part ? -1. : 1.;
630 sinAngleLeft = sinSegmentAngleLeft;
631 cosAngleLeft = cosSegmentAngleLeft;
633 if (outerRadius[part][1] == 0) {
638 cosAngleRight = part ? -1. : 1.;
640 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
641 }
else if (xLeft >= innerXCenter[0][1] && xLeft <= innerXCenter[1][1]) {
648 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
655 if (xRight != innerXPrev) {
656 float t = (xLeft - innerXPrev) / (xRight - innerXPrev);
657 yRight = innerYRightPrev * (1. - t) + yRight * t;
662 sinAngleRight = (yRight - innerYCenter[part][1]) / innerRadius[part][1];
663 cosAngleRight = -(xRight - innerXCenter[part][1]) / innerRadius[part][1];
667 if (outerRadius[part][1] == 0) {
669 cosAngleRight = part ? -1. : 1.;
671 sinAngleRight = sinSegmentAngleRight;
672 cosAngleRight = cosSegmentAngleRight;
674 if (outerRadius[part][0] == 0) {
676 cosAngleLeft = part ? -1. : 1.;
678 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
679 }
else if (xRight >= innerXCenter[0][0] && xRight <= innerXCenter[1][0]) {
683 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
685 if (xLeft != innerXPrev) {
686 float t = (xRight - innerXPrev) / (xLeft - innerXPrev);
687 yLeft = innerYLeftPrev * (1. - t) + yLeft * t;
690 sinAngleLeft = -(yLeft - innerYCenter[part][0]) / innerRadius[part][0];
691 cosAngleLeft = -(xLeft - innerXCenter[part][0]) / innerRadius[part][0];
695 gradientPos = (xLeft - gradientStart) / gradientLength;
698 outerXLeft = outerXCenter[part][0] - outerRadius[part][0] * cosAngleLeft;
699 outerYLeft = outerYCenter[part][0] - outerRadius[part][0] * sinAngleLeft;
700 outerXRight = outerXCenter[part][1] - outerRadius[part][1] * cosAngleRight;
701 outerYRight = outerYCenter[part][1] + outerRadius[part][1] * sinAngleRight;
704 while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) {
707 float gradientYRight;
710 gradientX = gradientStart + stops.at(nextGradientStop).first * gradientLength;
712 float t = (gradientX - innerXPrev) / (xLeft - innerXPrev);
713 gradientYLeft = innerYLeftPrev * (1. - t) + t * yLeft;
714 gradientYRight = innerYRightPrev * (1. - t) + t * yRight;
716 fillColor = fillColorFromX(gradientX);
719 indices[fillHead++] = index;
720 indices[fillHead++] = index + 1;
725 indices[borderHead] = indices[borderHead + 2];
726 indices[--borderHead] = index + 2;
727 indices[borderTail++] = index + 3;
728 indices[borderTail] = indices[borderTail - 2];
732 if (m_antialiasing) {
733 indices[--innerAAHead] = index + 2;
734 indices[--innerAAHead] = index;
735 indices[innerAATail++] = index + 1;
736 indices[innerAATail++] = index + 3;
738 bool lower = stops.at(nextGradientStop).first > 0.5f;
739 float dp = lower ? qMin(0.0f, gradientLength - gradientX - delta) : qMax(0.0f, delta - gradientX);
740 smoothVertices[index++].set(gradientX, gradientYRight, fillColor, dp, secondaryLength - gradientYRight - delta, m_gradient_is_vertical);
741 smoothVertices[index++].set(gradientX, gradientYLeft, fillColor, dp, delta - gradientYLeft, m_gradient_is_vertical);
743 smoothVertices[index++].set(gradientX, gradientYRight, borderColor, -0.49f * penWidth * cosAngleRight, 0.49f * penWidth * sinAngleRight, m_gradient_is_vertical);
744 smoothVertices[index++].set(gradientX, gradientYLeft, borderColor, -0.49f * penWidth * cosAngleLeft, -0.49f * penWidth * sinAngleLeft, m_gradient_is_vertical);
746 dp = lower ? delta : -delta;
747 smoothVertices[index++].set(gradientX, gradientYRight, transparent, dp, delta, m_gradient_is_vertical);
748 smoothVertices[index++].set(gradientX, gradientYLeft, transparent, dp, -delta, m_gradient_is_vertical);
751 vertices[index++].set(gradientX, gradientYRight, fillColor, m_gradient_is_vertical);
752 vertices[index++].set(gradientX, gradientYLeft, fillColor, m_gradient_is_vertical);
754 vertices[index++].set(gradientX, gradientYRight, borderColor, m_gradient_is_vertical);
755 vertices[index++].set(gradientX, gradientYLeft, borderColor, m_gradient_is_vertical);
759 innerXPrev = gradientX;
760 innerYLeftPrev = gradientYLeft;
761 innerYRightPrev = gradientYRight;
766 if (!stops.isEmpty()) {
767 fillColor = fillColorFromX(xLeft);
771 indices[fillHead++] = index;
772 indices[fillHead++] = index + 1;
776 indices[--borderHead] = index + 4;
777 indices[--borderHead] = index + 2;
778 indices[borderTail++] = index + 3;
779 indices[borderTail++] = index + 5;
782 if (m_antialiasing) {
783 indices[--innerAAHead] = index + 2;
784 indices[--innerAAHead] = index;
785 indices[innerAATail++] = index + 1;
786 indices[innerAATail++] = index + 3;
788 float dp = part ? qMin(0.0f, gradientLength - xRight - delta) : qMax(0.0f, delta - xRight);
789 smoothVertices[index++].set(xRight, yRight, fillColor, dp, secondaryLength - yRight - delta, m_gradient_is_vertical);
790 smoothVertices[index++].set(xLeft, yLeft, fillColor, dp, delta - yLeft, m_gradient_is_vertical);
792 dp = part ? delta : -delta;
794 smoothVertices[index++].set(xRight, yRight, borderColor, -0.49f * penWidth * cosAngleRight, 0.49f * penWidth * sinAngleRight, m_gradient_is_vertical);
795 smoothVertices[index++].set(xLeft, yLeft, borderColor, -0.49f * penWidth * cosAngleLeft, -0.49f * penWidth * sinAngleLeft, m_gradient_is_vertical);
796 smoothVertices[index++].set(outerXRight, outerYRight, borderColor, 0.49f * penWidth * cosAngleRight, -0.49f * penWidth * sinAngleRight, m_gradient_is_vertical);
797 smoothVertices[index++].set(outerXLeft, outerYLeft, borderColor, 0.49f * penWidth * cosAngleLeft, 0.49f * penWidth * sinAngleLeft, m_gradient_is_vertical);
798 smoothVertices[index++].set(outerXRight, outerYRight, transparent, dp, delta, m_gradient_is_vertical);
799 smoothVertices[index++].set(outerXLeft, outerYLeft, transparent, dp, -delta, m_gradient_is_vertical);
801 indices[--outerAAHead] = index - 2;
802 indices[--outerAAHead] = index - 4;
803 indices[outerAATail++] = index - 3;
804 indices[outerAATail++] = index - 1;
806 smoothVertices[index++].set(xRight, yRight, transparent, dp, delta, m_gradient_is_vertical);
807 smoothVertices[index++].set(xLeft, yLeft, transparent, dp, -delta, m_gradient_is_vertical);
810 vertices[index++].set(xRight, yRight, fillColor, m_gradient_is_vertical);
811 vertices[index++].set(xLeft, yLeft, fillColor, m_gradient_is_vertical);
813 vertices[index++].set(xRight, yRight, borderColor, m_gradient_is_vertical);
814 vertices[index++].set(xLeft, yLeft, borderColor, m_gradient_is_vertical);
815 vertices[index++].set(outerXRight, outerYRight, borderColor, m_gradient_is_vertical);
816 vertices[index++].set(outerXLeft, outerYLeft, borderColor, m_gradient_is_vertical);
821 innerYLeftPrev = yLeft;
822 innerYRightPrev = yRight;
827 qreal tmp = cosSegmentAngleLeft;
828 cosSegmentAngleLeft = cosSegmentAngleLeft * cosStep[part][0] - sinSegmentAngleLeft * sinStep[part][0];
829 sinSegmentAngleLeft = sinSegmentAngleLeft * cosStep[part][0] + tmp * sinStep[part][0];
832 qreal tmp = cosSegmentAngleRight;
833 cosSegmentAngleRight = cosSegmentAngleRight * cosStep[part][1] - sinSegmentAngleRight * sinStep[part][1];
834 sinSegmentAngleRight = sinSegmentAngleRight * cosStep[part][1] + tmp * sinStep[part][1];
839 Q_ASSERT(index == vertexCount);
842 if (m_antialiasing) {
843 indices[--innerAAHead] = indices[innerAATail - 1];
844 indices[--innerAAHead] = indices[innerAATail - 2];
845 Q_ASSERT(innerAATail <= indexCount);
848 indices[--borderHead] = indices[borderTail - 1];
849 indices[--borderHead] = indices[borderTail - 2];
850 Q_ASSERT(borderTail <= indexCount);
852 if (m_antialiasing && penWidth) {
853 indices[--outerAAHead] = indices[outerAATail - 1];
854 indices[--outerAAHead] = indices[outerAATail - 2];
855 Q_ASSERT(outerAATail == indexCount);
859 QRectF innerRect = m_rect;
860 QRectF outerRect = m_rect;
863 innerRect.adjust(1.0f * penWidth, 1.0f * penWidth, -1.0f * penWidth, -1.0f * penWidth);
865 float delta = qMin(width, height) * 0.5f;
866 int innerVertexCount = 4 + gradientIntersections * 2;
867 int outerVertexCount = 4;
868 int vertexCount = innerVertexCount;
869 if (m_antialiasing || penWidth)
870 vertexCount += innerVertexCount;
872 vertexCount += outerVertexCount;
873 if (m_antialiasing && penWidth)
874 vertexCount += outerVertexCount;
876 int fillIndexCount = innerVertexCount;
877 int innerAAIndexCount = innerVertexCount * 2 + 2;
878 int borderIndexCount = innerVertexCount * 2 + 2;
879 int outerAAIndexCount = outerVertexCount * 2 + 2;
888 bool hasFill = m_color.alpha() > 0 || !stops.isEmpty();
890 indexCount += fillIndexCount;
891 if (m_antialiasing) {
892 innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1;
893 indexCount += innerAAIndexCount;
896 borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1;
897 indexCount += borderIndexCount;
899 if (m_antialiasing && penWidth) {
900 outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1;
901 indexCount += outerAAIndexCount;
904 g->allocate(vertexCount, indexCount);
905 vertices =
reinterpret_cast<Vertex *>(g->vertexData());
906 memset(vertices, 0, vertexCount * vertexStride);
907 quint16 *indices = g->indexDataAsUShort();
910 float innerStart = (m_gradient_is_vertical ? innerRect.top() : innerRect.left());
911 float innerEnd = (m_gradient_is_vertical ? innerRect.bottom() : innerRect.right());
912 float outerStart = (m_gradient_is_vertical ? outerRect.top() : outerRect.left());
913 float outerEnd = (m_gradient_is_vertical ? outerRect.bottom() : outerRect.right());
915 float innerSecondaryStart = (m_gradient_is_vertical ? innerRect.left() : innerRect.top());
916 float innerSecondaryEnd = (m_gradient_is_vertical ? innerRect.right() : innerRect.bottom());
917 float outerSecondaryStart = (m_gradient_is_vertical ? outerRect.left() : outerRect.top());
918 float outerSecondaryEnd = (m_gradient_is_vertical ? outerRect.right() : outerRect.bottom());
920 for (
int part = -1; part <= 1; part += 2) {
921 float innerEdge = (part == 1 ? innerEnd : innerStart);
922 float outerEdge = (part == 1 ? outerEnd : outerStart);
923 gradientPos = (innerEdge - innerStart + penWidth) / gradientLength;
925 while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) {
927 float gp = (innerStart - penWidth) + stops.at(nextGradientStop).first * gradientLength;
929 fillColor = colorToColor4ub(stops.at(nextGradientStop).second);
932 indices[fillHead++] = index;
933 indices[fillHead++] = index + 1;
938 indices[borderHead] = indices[borderHead + 2];
939 indices[--borderHead] = index + 2;
940 indices[borderTail++] = index + 3;
941 indices[borderTail] = indices[borderTail - 2];
945 if (m_antialiasing) {
946 indices[--innerAAHead] = index + 2;
947 indices[--innerAAHead] = index;
948 indices[innerAATail++] = index + 1;
949 indices[innerAATail++] = index + 3;
951 bool lower = stops.at(nextGradientStop).first > 0.5f;
952 float dp = lower ? qMin(0.0f, gradientLength - gp - delta) : qMax(0.0f, delta - gp);
953 smoothVertices[index++].set(gp, innerSecondaryEnd, fillColor, dp, secondaryLength - innerSecondaryEnd - delta, m_gradient_is_vertical);
954 smoothVertices[index++].set(gp, innerSecondaryStart, fillColor, dp, delta - innerSecondaryStart, m_gradient_is_vertical);
956 smoothVertices[index++].set(gp, innerSecondaryEnd, borderColor, (lower ? 0.49f : -0.49f) * penWidth, 0.49f * penWidth, m_gradient_is_vertical);
957 smoothVertices[index++].set(gp, innerSecondaryStart, borderColor, (lower ? 0.49f : -0.49f) * penWidth, -0.49f * penWidth, m_gradient_is_vertical);
959 smoothVertices[index++].set(gp, innerSecondaryEnd, transparent, lower ? delta : -delta, delta, m_gradient_is_vertical);
960 smoothVertices[index++].set(gp, innerSecondaryStart, transparent, lower ? delta : -delta, -delta, m_gradient_is_vertical);
963 vertices[index++].set(gp, innerSecondaryEnd, fillColor, m_gradient_is_vertical);
964 vertices[index++].set(gp, innerSecondaryStart, fillColor, m_gradient_is_vertical);
966 vertices[index++].set(gp, innerSecondaryEnd, borderColor, m_gradient_is_vertical);
967 vertices[index++].set(gp, innerSecondaryStart, borderColor, m_gradient_is_vertical);
973 if (!stops.isEmpty()) {
974 if (nextGradientStop == 0) {
975 fillColor = colorToColor4ub(stops.at(0).second);
976 }
else if (nextGradientStop == stops.size()) {
977 fillColor = colorToColor4ub(stops.last().second);
979 const QGradientStop &prev = stops.at(nextGradientStop - 1);
980 const QGradientStop &next = stops.at(nextGradientStop);
981 float t = (gradientPos - prev.first) / (next.first - prev.first);
982 fillColor = colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t;
987 indices[fillHead++] = index;
988 indices[fillHead++] = index + 1;
992 indices[--borderHead] = index + 4;
993 indices[--borderHead] = index + 2;
994 indices[borderTail++] = index + 3;
995 indices[borderTail++] = index + 5;
998 if (m_antialiasing) {
999 indices[--innerAAHead] = index + 2;
1000 indices[--innerAAHead] = index;
1001 indices[innerAATail++] = index + 1;
1002 indices[innerAATail++] = index + 3;
1004 float dp = part == 1 ? qMin(0.0f, gradientLength - innerEdge - delta) : qMax(0.0f, delta - innerEdge);
1005 smoothVertices[index++].set(innerEdge, innerSecondaryEnd, fillColor, dp, secondaryLength - innerSecondaryEnd - delta, m_gradient_is_vertical);
1006 smoothVertices[index++].set(innerEdge, innerSecondaryStart, fillColor, dp, delta - innerSecondaryStart, m_gradient_is_vertical);
1009 smoothVertices[index++].set(innerEdge, innerSecondaryEnd, borderColor, 0.49f * penWidth * part, 0.49f * penWidth, m_gradient_is_vertical);
1010 smoothVertices[index++].set(innerEdge, innerSecondaryStart, borderColor, 0.49f * penWidth * part, -0.49f * penWidth, m_gradient_is_vertical);
1011 smoothVertices[index++].set(outerEdge, outerSecondaryEnd, borderColor, -0.49f * penWidth * part, -0.49f * penWidth, m_gradient_is_vertical);
1012 smoothVertices[index++].set(outerEdge, outerSecondaryStart, borderColor, -0.49f * penWidth * part, 0.49f * penWidth, m_gradient_is_vertical);
1013 smoothVertices[index++].set(outerEdge, outerSecondaryEnd, transparent, delta * part, delta, m_gradient_is_vertical);
1014 smoothVertices[index++].set(outerEdge, outerSecondaryStart, transparent, delta * part, -delta, m_gradient_is_vertical);
1016 indices[--outerAAHead] = index - 2;
1017 indices[--outerAAHead] = index - 4;
1018 indices[outerAATail++] = index - 3;
1019 indices[outerAATail++] = index - 1;
1021 smoothVertices[index++].set(innerEdge, innerSecondaryEnd, transparent, delta * part, delta, m_gradient_is_vertical);
1022 smoothVertices[index++].set(innerEdge, innerSecondaryStart, transparent, delta * part, -delta, m_gradient_is_vertical);
1025 vertices[index++].set(innerEdge, innerSecondaryEnd, fillColor, m_gradient_is_vertical);
1026 vertices[index++].set(innerEdge, innerSecondaryStart, fillColor, m_gradient_is_vertical);
1028 vertices[index++].set(innerEdge, innerSecondaryEnd, borderColor, m_gradient_is_vertical);
1029 vertices[index++].set(innerEdge, innerSecondaryStart, borderColor, m_gradient_is_vertical);
1030 vertices[index++].set(outerEdge, outerSecondaryEnd, borderColor, m_gradient_is_vertical);
1031 vertices[index++].set(outerEdge, outerSecondaryStart, borderColor, m_gradient_is_vertical);
1035 Q_ASSERT(index == vertexCount);
1038 if (m_antialiasing) {
1039 indices[--innerAAHead] = indices[innerAATail - 1];
1040 indices[--innerAAHead] = indices[innerAATail - 2];
1041 Q_ASSERT(innerAATail <= indexCount);
1044 indices[--borderHead] = indices[borderTail - 1];
1045 indices[--borderHead] = indices[borderTail - 2];
1046 Q_ASSERT(borderTail <= indexCount);
1048 if (m_antialiasing && penWidth) {
1049 indices[--outerAAHead] = indices[outerAATail - 1];
1050 indices[--outerAAHead] = indices[outerAATail - 2];
1051 Q_ASSERT(outerAATail == indexCount);