266void QSGBasicInternalRectangleNode::updateGeometry()
268 float width =
float(m_rect.width());
269 float height =
float(m_rect.height());
270 float penWidth = qMin(qMin(width, height) * 0.5f,
float(m_pen_width));
273 penWidth = qRound(penWidth);
275 QSGGeometry *g = geometry();
276 g->setDrawingMode(QSGGeometry::DrawTriangleStrip);
277 int vertexStride = g->sizeOfVertex();
281 SmoothVertex *smoothVertices;
284 Color4ub fillColor = colorToColor4ub(m_color);
285 Color4ub borderColor = colorToColor4ub(m_border_color);
286 Color4ub transparent = { 0, 0, 0, 0 };
287 const QGradientStops &stops = m_gradient_stops;
289 float gradientStart = (m_gradient_is_vertical ? m_rect.top() : m_rect.left());
290 float gradientLength = (m_gradient_is_vertical ? height : width);
291 float secondaryLength = (m_gradient_is_vertical ? width : height);
293 int nextGradientStop = 0;
294 float gradientPos = penWidth / gradientLength;
295 while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos)
297 int lastGradientStop = stops.size() - 1;
298 float lastGradientPos = 1.0f - penWidth / gradientLength;
299 while (lastGradientStop >= nextGradientStop && stops.at(lastGradientStop).first >= lastGradientPos)
301 int gradientIntersections = (lastGradientStop - nextGradientStop + 1);
304 || m_isTopLeftRadiusSet
305 || m_isTopRightRadiusSet
306 || m_isBottomLeftRadiusSet
307 || m_isBottomRightRadiusSet) {
311 float radiusTL = qMin(qMin(width, height) * 0.4999f,
312 float(m_isTopLeftRadiusSet ? m_topLeftRadius : m_radius));
313 float radiusTR = qMin(qMin(width, height) * 0.4999f,
314 float(m_isTopRightRadiusSet ? m_topRightRadius : m_radius));
315 float radiusBL = qMin(qMin(width, height) * 0.4999f,
316 float(m_isBottomLeftRadiusSet ? m_bottomLeftRadius : m_radius));
317 float radiusBR = qMin(qMin(width, height) * 0.4999f,
318 float(m_isBottomRightRadiusSet ? m_bottomRightRadius : m_radius));
333 const float innerRadiusTL = qMax(radiusTL - penWidth * 1.0f, 0.01);
334 const float innerRadiusTR = qMax(radiusTR - penWidth * 1.0f, 0.01);
335 const float innerRadiusBL = qMax(radiusBL - penWidth * 1.0f, 0.01);
336 const float innerRadiusBR = qMax(radiusBR - penWidth * 1.0f, 0.01);
337 const float outerRadiusTL = radiusTL;
338 const float outerRadiusTR = radiusTR;
339 const float outerRadiusBL = radiusBL;
340 const float outerRadiusBR = radiusBR;
341 const float delta = qMin(width, height) * 0.5f;
343 int segmentsTL = radiusTL == 0 ? 0 : qBound(3, qCeil(radiusTL * (M_PI / 6)), 18);
344 int segmentsTR = radiusTR == 0 ? 0 : qBound(3, qCeil(radiusTR * (M_PI / 6)), 18);
345 int segmentsBL = radiusBL == 0 ? 0 : qBound(3, qCeil(radiusBL * (M_PI / 6)), 18);
346 int segmentsBR = radiusBR == 0 ? 0 : qBound(3, qCeil(radiusBR * (M_PI / 6)), 18);
351 if (m_gradient_is_vertical) {
352 if (innerRadiusTL == innerRadiusTR) {
353 if (segmentsTL <= segmentsTR)
358 if (innerRadiusBL == innerRadiusBR){
359 if (segmentsBL <= segmentsBR)
365 if (innerRadiusTL == innerRadiusBL) {
366 if (segmentsTL <= segmentsBL)
371 if (innerRadiusTR == innerRadiusBR) {
372 if (segmentsTR <= segmentsBR)
379 const int sumSegments = segmentsTL + segmentsTR + segmentsBL + segmentsBR;
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
401 const int innerVertexCount = (sumSegments + 4) * 2 + gradientIntersections * 2;
402 const int outerVertexCount = (sumSegments + 4) * 2;
403 int vertexCount = innerVertexCount;
404 if (m_antialiasing || penWidth)
405 vertexCount += innerVertexCount;
407 vertexCount += outerVertexCount;
408 if (m_antialiasing && penWidth)
409 vertexCount += outerVertexCount;
412 const int fillIndexCount = innerVertexCount;
413 const int innerAAIndexCount = innerVertexCount * 2 + 2;
414 const int borderIndexCount = innerVertexCount * 2 + 2;
415 const int outerAAIndexCount = outerVertexCount * 2 + 2;
424 bool hasFill = m_color.alpha() > 0 || !stops.isEmpty();
426 indexCount += fillIndexCount;
427 if (m_antialiasing) {
428 innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1;
429 indexCount += innerAAIndexCount;
432 borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1;
433 indexCount += borderIndexCount;
435 if (m_antialiasing && penWidth) {
436 outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1;
437 indexCount += outerAAIndexCount;
440 g->allocate(vertexCount, indexCount);
441 vertices =
reinterpret_cast<Vertex *>(g->vertexData());
442 memset(vertices, 0, vertexCount * vertexStride);
443 quint16 *indices = g->indexDataAsUShort();
447 float innerXPrev = 0.;
448 float innerYLeftPrev = 0.;
449 float innerYRightPrev = 0.;
451 const float angleTL = 0.5f *
float(M_PI) / segmentsTL;
452 const float cosStepTL = qFastCos(angleTL);
453 const float sinStepTL = qFastSin(angleTL);
454 const float angleTR = 0.5f *
float(M_PI) / segmentsTR;
455 const float cosStepTR = qFastCos(angleTR);
456 const float sinStepTR = qFastSin(angleTR);
457 const float angleBL = 0.5f *
float(M_PI) / segmentsBL;
458 const float cosStepBL = qFastCos(angleBL);
459 const float sinStepBL = qFastSin(angleBL);
460 const float angleBR = 0.5f *
float(M_PI) / segmentsBR;
461 const float cosStepBR = qFastCos(angleBR);
462 const float sinStepBR = qFastSin(angleBR);
494 const float outerXCenter[][2] = {{
495 float(m_gradient_is_vertical ? m_rect.top() + radiusTL : m_rect.left() + radiusTL),
496 float(m_gradient_is_vertical ? m_rect.top() + radiusTR : m_rect.left() + radiusBL)
498 float(m_gradient_is_vertical ? m_rect.bottom() - radiusBL : m_rect.right() - radiusTR),
499 float(m_gradient_is_vertical ? m_rect.bottom() - radiusBR : m_rect.right() - radiusBR)
502 const float outerYCenter[][2] = {{
503 float(!m_gradient_is_vertical ? m_rect.top() + outerRadiusTL : m_rect.left() + outerRadiusTL),
504 float(!m_gradient_is_vertical ? m_rect.bottom() - outerRadiusBL : m_rect.right() - outerRadiusTR)
506 float(!m_gradient_is_vertical ? m_rect.top() + outerRadiusTR : m_rect.left() + outerRadiusBL),
507 float(!m_gradient_is_vertical ? m_rect.bottom() - outerRadiusBR : m_rect.right() - outerRadiusBR)
510 const float innerXCenter[][2] = { {
511 float(m_gradient_is_vertical ? m_rect.top() + innerRadiusTL + penWidth : m_rect.left() + innerRadiusTL + penWidth),
512 float(m_gradient_is_vertical ? m_rect.top() + innerRadiusTR + penWidth: m_rect.left() + innerRadiusBL + penWidth)
514 float(m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBL - penWidth: m_rect.right() - innerRadiusTR - penWidth),
515 float(m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBR - penWidth: m_rect.right() - innerRadiusBR - penWidth)
518 const float innerYCenter[][2] = { {
519 float(!m_gradient_is_vertical ? m_rect.top() + innerRadiusTL + penWidth : m_rect.left() + innerRadiusTL + penWidth),
520 float(!m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBL - penWidth : m_rect.right() - innerRadiusTR - penWidth)
522 float(!m_gradient_is_vertical ? m_rect.top() + innerRadiusTR + penWidth : m_rect.left() + innerRadiusBL + penWidth),
523 float(!m_gradient_is_vertical ? m_rect.bottom() - innerRadiusBR - penWidth : m_rect.right() - innerRadiusBR - penWidth)
526 const float innerRadius[][2] = {{
528 !m_gradient_is_vertical ? innerRadiusBL : innerRadiusTR
530 !m_gradient_is_vertical ? innerRadiusTR : innerRadiusBL,
534 const float outerRadius[][2] = {{
536 !m_gradient_is_vertical ? outerRadiusBL : outerRadiusTR
538 !m_gradient_is_vertical ? outerRadiusTR : outerRadiusBL,
542 const int segments[][2] = {{
544 !m_gradient_is_vertical ? segmentsBL : segmentsTR
546 !m_gradient_is_vertical ? segmentsTR : segmentsBL,
550 const float cosStep[][2] = {{
552 !m_gradient_is_vertical ? cosStepBL : cosStepTR
554 !m_gradient_is_vertical ? cosStepTR : cosStepBL,
558 const float sinStep[][2] = {{
560 !m_gradient_is_vertical ? sinStepBL : sinStepTR
562 !m_gradient_is_vertical ? sinStepTR : sinStepBL,
566 auto fillColorFromX = [&](
float x) {
568 float t = (x - gradientStart) / gradientLength;
569 t = qBound(0.0, t, 1.0);
572 if (t < stops.first().first)
573 return colorToColor4ub(stops.first().second);
574 while (i < stops.size()) {
575 const QGradientStop &prev = stops.at(i - 1);
576 const QGradientStop &next = stops.at(i);
577 if (prev.first <= t && next.first > t) {
578 t = (t - prev.first) / (next.first - prev.first);
579 return colorToColor4ub(prev.second) * (1. - t) + colorToColor4ub(next.second) * t; }
582 return colorToColor4ub(stops.last().second);
585 for (
int part = 0; part < 2; ++part) {
587 float cosSegmentAngleLeft = 1. - part;
589 float sinSegmentAngleLeft = part;
591 float cosSegmentAngleRight = 1. - part;
592 float sinSegmentAngleRight = part;
594 bool advanceLeft =
true;
599 for (
int iLeft = 0, iRight = 0; iLeft <= segments[part][0] || iRight <= segments[part][1]; ) {
604 float outerXLeft, outerYLeft,
605 outerXRight, outerYRight;
607 float sinAngleLeft, cosAngleLeft,
608 sinAngleRight, cosAngleRight;
611 xLeft = innerXCenter[part][0] - innerRadius[part][0] * cosSegmentAngleLeft;
612 xRight = innerXCenter[part][1] - innerRadius[part][1] * cosSegmentAngleRight;
615 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinSegmentAngleLeft;
616 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinSegmentAngleRight;
622 if ((iLeft <= segments[part][0] && xLeft <= xRight) || iRight > segments[part][1]) {
631 if (innerRadius[part][0] == innerRadius[part][1]) {
636 if (outerRadius[part][0] == 0) {
638 cosAngleLeft = part ? -1. : 1.;
640 sinAngleLeft = sinSegmentAngleLeft;
641 cosAngleLeft = cosSegmentAngleLeft;
643 if (outerRadius[part][1] == 0) {
645 cosAngleRight = part ? -1. : 1.;
647 sinAngleRight = sinSegmentAngleLeft;
648 cosAngleRight = cosSegmentAngleLeft;
651 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
653 if (outerRadius[part][0] == 0) {
655 cosAngleLeft = part ? -1. : 1.;
657 sinAngleLeft = sinSegmentAngleRight;
658 cosAngleLeft = cosSegmentAngleRight;
660 if (outerRadius[part][1] == 0) {
662 cosAngleRight = part ? -1. : 1.;
664 sinAngleRight = sinSegmentAngleRight;
665 cosAngleRight = cosSegmentAngleRight;
668 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
670 }
else if (advanceLeft) {
671 if (outerRadius[part][0] == 0) {
673 cosAngleLeft = part ? -1. : 1.;
675 sinAngleLeft = sinSegmentAngleLeft;
676 cosAngleLeft = cosSegmentAngleLeft;
678 if (outerRadius[part][1] == 0) {
683 cosAngleRight = part ? -1. : 1.;
685 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
686 }
else if (xLeft >= innerXCenter[0][1] && xLeft <= innerXCenter[1][1]) {
693 yRight = innerYCenter[part][1] + innerRadius[part][1] * sinAngleRight;
700 if (xRight != innerXPrev) {
701 float t = (xLeft - innerXPrev) / (xRight - innerXPrev);
702 yRight = innerYRightPrev * (1. - t) + yRight * t;
707 sinAngleRight = (yRight - innerYCenter[part][1]) / innerRadius[part][1];
708 cosAngleRight = -(xRight - innerXCenter[part][1]) / innerRadius[part][1];
712 if (outerRadius[part][1] == 0) {
714 cosAngleRight = part ? -1. : 1.;
716 sinAngleRight = sinSegmentAngleRight;
717 cosAngleRight = cosSegmentAngleRight;
719 if (outerRadius[part][0] == 0) {
721 cosAngleLeft = part ? -1. : 1.;
723 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
724 }
else if (xRight >= innerXCenter[0][0] && xRight <= innerXCenter[1][0]) {
728 yLeft = innerYCenter[part][0] - innerRadius[part][0] * sinAngleLeft;
730 if (xLeft != innerXPrev) {
731 float t = (xRight - innerXPrev) / (xLeft - innerXPrev);
732 yLeft = innerYLeftPrev * (1. - t) + yLeft * t;
735 sinAngleLeft = -(yLeft - innerYCenter[part][0]) / innerRadius[part][0];
736 cosAngleLeft = -(xLeft - innerXCenter[part][0]) / innerRadius[part][0];
740 gradientPos = (xLeft - gradientStart) / gradientLength;
743 outerXLeft = outerXCenter[part][0] - outerRadius[part][0] * cosAngleLeft;
744 outerYLeft = outerYCenter[part][0] - outerRadius[part][0] * sinAngleLeft;
745 outerXRight = outerXCenter[part][1] - outerRadius[part][1] * cosAngleRight;
746 outerYRight = outerYCenter[part][1] + outerRadius[part][1] * sinAngleRight;
749 while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) {
752 float gradientYRight;
755 gradientX = gradientStart + stops.at(nextGradientStop).first * gradientLength;
757 float t = (gradientX - innerXPrev) / (xLeft - innerXPrev);
758 gradientYLeft = innerYLeftPrev * (1. - t) + t * yLeft;
759 gradientYRight = innerYRightPrev * (1. - t) + t * yRight;
761 fillColor = fillColorFromX(gradientX);
764 indices[fillHead++] = index;
765 indices[fillHead++] = index + 1;
770 indices[borderHead] = indices[borderHead + 2];
771 indices[--borderHead] = index + 2;
772 indices[borderTail++] = index + 3;
773 indices[borderTail] = indices[borderTail - 2];
777 if (m_antialiasing) {
778 indices[--innerAAHead] = index + 2;
779 indices[--innerAAHead] = index;
780 indices[innerAATail++] = index + 1;
781 indices[innerAATail++] = index + 3;
783 bool lower = stops.at(nextGradientStop).first > 0.5f;
784 float dp = lower ? qMin(0.0f, gradientLength - gradientX - delta) : qMax(0.0f, delta - gradientX);
785 smoothVertices[index++].set(gradientX, gradientYRight, fillColor, dp, secondaryLength - gradientYRight - delta, m_gradient_is_vertical);
786 smoothVertices[index++].set(gradientX, gradientYLeft, fillColor, dp, delta - gradientYLeft, m_gradient_is_vertical);
788 smoothVertices[index++].set(gradientX, gradientYRight, borderColor, -0.49f * penWidth * cosAngleRight, 0.49f * penWidth * sinAngleRight, m_gradient_is_vertical);
789 smoothVertices[index++].set(gradientX, gradientYLeft, borderColor, -0.49f * penWidth * cosAngleLeft, -0.49f * penWidth * sinAngleLeft, m_gradient_is_vertical);
791 dp = lower ? delta : -delta;
792 smoothVertices[index++].set(gradientX, gradientYRight, transparent, dp, delta, m_gradient_is_vertical);
793 smoothVertices[index++].set(gradientX, gradientYLeft, transparent, dp, -delta, m_gradient_is_vertical);
796 vertices[index++].set(gradientX, gradientYRight, fillColor, m_gradient_is_vertical);
797 vertices[index++].set(gradientX, gradientYLeft, fillColor, m_gradient_is_vertical);
799 vertices[index++].set(gradientX, gradientYRight, borderColor, m_gradient_is_vertical);
800 vertices[index++].set(gradientX, gradientYLeft, borderColor, m_gradient_is_vertical);
804 innerXPrev = gradientX;
805 innerYLeftPrev = gradientYLeft;
806 innerYRightPrev = gradientYRight;
811 if (!stops.isEmpty()) {
812 fillColor = fillColorFromX(xLeft);
816 indices[fillHead++] = index;
817 indices[fillHead++] = index + 1;
821 indices[--borderHead] = index + 4;
822 indices[--borderHead] = index + 2;
823 indices[borderTail++] = index + 3;
824 indices[borderTail++] = index + 5;
827 if (m_antialiasing) {
828 indices[--innerAAHead] = index + 2;
829 indices[--innerAAHead] = index;
830 indices[innerAATail++] = index + 1;
831 indices[innerAATail++] = index + 3;
833 float dp = part ? qMin(0.0f, gradientLength - xRight - delta) : qMax(0.0f, delta - xRight);
834 smoothVertices[index++].set(xRight, yRight, fillColor, dp, secondaryLength - yRight - delta, m_gradient_is_vertical);
835 smoothVertices[index++].set(xLeft, yLeft, fillColor, dp, delta - yLeft, m_gradient_is_vertical);
837 dp = part ? delta : -delta;
839 smoothVertices[index++].set(xRight, yRight, borderColor, -0.49f * penWidth * cosAngleRight, 0.49f * penWidth * sinAngleRight, m_gradient_is_vertical);
840 smoothVertices[index++].set(xLeft, yLeft, borderColor, -0.49f * penWidth * cosAngleLeft, -0.49f * penWidth * sinAngleLeft, m_gradient_is_vertical);
841 smoothVertices[index++].set(outerXRight, outerYRight, borderColor, 0.49f * penWidth * cosAngleRight, -0.49f * penWidth * sinAngleRight, m_gradient_is_vertical);
842 smoothVertices[index++].set(outerXLeft, outerYLeft, borderColor, 0.49f * penWidth * cosAngleLeft, 0.49f * penWidth * sinAngleLeft, m_gradient_is_vertical);
843 smoothVertices[index++].set(outerXRight, outerYRight, transparent, dp, delta, m_gradient_is_vertical);
844 smoothVertices[index++].set(outerXLeft, outerYLeft, transparent, dp, -delta, m_gradient_is_vertical);
846 indices[--outerAAHead] = index - 2;
847 indices[--outerAAHead] = index - 4;
848 indices[outerAATail++] = index - 3;
849 indices[outerAATail++] = index - 1;
851 smoothVertices[index++].set(xRight, yRight, transparent, dp, delta, m_gradient_is_vertical);
852 smoothVertices[index++].set(xLeft, yLeft, transparent, dp, -delta, m_gradient_is_vertical);
855 vertices[index++].set(xRight, yRight, fillColor, m_gradient_is_vertical);
856 vertices[index++].set(xLeft, yLeft, fillColor, m_gradient_is_vertical);
858 vertices[index++].set(xRight, yRight, borderColor, m_gradient_is_vertical);
859 vertices[index++].set(xLeft, yLeft, borderColor, m_gradient_is_vertical);
860 vertices[index++].set(outerXRight, outerYRight, borderColor, m_gradient_is_vertical);
861 vertices[index++].set(outerXLeft, outerYLeft, borderColor, m_gradient_is_vertical);
866 innerYLeftPrev = yLeft;
867 innerYRightPrev = yRight;
872 qreal tmp = cosSegmentAngleLeft;
873 cosSegmentAngleLeft = cosSegmentAngleLeft * cosStep[part][0] - sinSegmentAngleLeft * sinStep[part][0];
874 sinSegmentAngleLeft = sinSegmentAngleLeft * cosStep[part][0] + tmp * sinStep[part][0];
877 qreal tmp = cosSegmentAngleRight;
878 cosSegmentAngleRight = cosSegmentAngleRight * cosStep[part][1] - sinSegmentAngleRight * sinStep[part][1];
879 sinSegmentAngleRight = sinSegmentAngleRight * cosStep[part][1] + tmp * sinStep[part][1];
884 Q_ASSERT(index == vertexCount);
887 if (m_antialiasing) {
888 indices[--innerAAHead] = indices[innerAATail - 1];
889 indices[--innerAAHead] = indices[innerAATail - 2];
890 Q_ASSERT(innerAATail <= indexCount);
893 indices[--borderHead] = indices[borderTail - 1];
894 indices[--borderHead] = indices[borderTail - 2];
895 Q_ASSERT(borderTail <= indexCount);
897 if (m_antialiasing && penWidth) {
898 indices[--outerAAHead] = indices[outerAATail - 1];
899 indices[--outerAAHead] = indices[outerAATail - 2];
900 Q_ASSERT(outerAATail == indexCount);
904 QRectF innerRect = m_rect;
905 QRectF outerRect = m_rect;
908 innerRect.adjust(1.0f * penWidth, 1.0f * penWidth, -1.0f * penWidth, -1.0f * penWidth);
910 float delta = qMin(width, height) * 0.5f;
911 int innerVertexCount = 4 + gradientIntersections * 2;
912 int outerVertexCount = 4;
913 int vertexCount = innerVertexCount;
914 if (m_antialiasing || penWidth)
915 vertexCount += innerVertexCount;
917 vertexCount += outerVertexCount;
918 if (m_antialiasing && penWidth)
919 vertexCount += outerVertexCount;
921 int fillIndexCount = innerVertexCount;
922 int innerAAIndexCount = innerVertexCount * 2 + 2;
923 int borderIndexCount = innerVertexCount * 2 + 2;
924 int outerAAIndexCount = outerVertexCount * 2 + 2;
933 bool hasFill = m_color.alpha() > 0 || !stops.isEmpty();
935 indexCount += fillIndexCount;
936 if (m_antialiasing) {
937 innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1;
938 indexCount += innerAAIndexCount;
941 borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1;
942 indexCount += borderIndexCount;
944 if (m_antialiasing && penWidth) {
945 outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1;
946 indexCount += outerAAIndexCount;
949 g->allocate(vertexCount, indexCount);
950 vertices =
reinterpret_cast<Vertex *>(g->vertexData());
951 memset(vertices, 0, vertexCount * vertexStride);
952 quint16 *indices = g->indexDataAsUShort();
955 float innerStart = (m_gradient_is_vertical ? innerRect.top() : innerRect.left());
956 float innerEnd = (m_gradient_is_vertical ? innerRect.bottom() : innerRect.right());
957 float outerStart = (m_gradient_is_vertical ? outerRect.top() : outerRect.left());
958 float outerEnd = (m_gradient_is_vertical ? outerRect.bottom() : outerRect.right());
960 float innerSecondaryStart = (m_gradient_is_vertical ? innerRect.left() : innerRect.top());
961 float innerSecondaryEnd = (m_gradient_is_vertical ? innerRect.right() : innerRect.bottom());
962 float outerSecondaryStart = (m_gradient_is_vertical ? outerRect.left() : outerRect.top());
963 float outerSecondaryEnd = (m_gradient_is_vertical ? outerRect.right() : outerRect.bottom());
965 for (
int part = -1; part <= 1; part += 2) {
966 float innerEdge = (part == 1 ? innerEnd : innerStart);
967 float outerEdge = (part == 1 ? outerEnd : outerStart);
968 gradientPos = (innerEdge - innerStart + penWidth) / gradientLength;
970 while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) {
972 float gp = (innerStart - penWidth) + stops.at(nextGradientStop).first * gradientLength;
974 fillColor = colorToColor4ub(stops.at(nextGradientStop).second);
977 indices[fillHead++] = index;
978 indices[fillHead++] = index + 1;
983 indices[borderHead] = indices[borderHead + 2];
984 indices[--borderHead] = index + 2;
985 indices[borderTail++] = index + 3;
986 indices[borderTail] = indices[borderTail - 2];
990 if (m_antialiasing) {
991 indices[--innerAAHead] = index + 2;
992 indices[--innerAAHead] = index;
993 indices[innerAATail++] = index + 1;
994 indices[innerAATail++] = index + 3;
996 bool lower = stops.at(nextGradientStop).first > 0.5f;
997 float dp = lower ? qMin(0.0f, gradientLength - gp - delta) : qMax(0.0f, delta - gp);
998 smoothVertices[index++].set(gp, innerSecondaryEnd, fillColor, dp, secondaryLength - innerSecondaryEnd - delta, m_gradient_is_vertical);
999 smoothVertices[index++].set(gp, innerSecondaryStart, fillColor, dp, delta - innerSecondaryStart, m_gradient_is_vertical);
1001 smoothVertices[index++].set(gp, innerSecondaryEnd, borderColor, (lower ? 0.49f : -0.49f) * penWidth, 0.49f * penWidth, m_gradient_is_vertical);
1002 smoothVertices[index++].set(gp, innerSecondaryStart, borderColor, (lower ? 0.49f : -0.49f) * penWidth, -0.49f * penWidth, m_gradient_is_vertical);
1004 smoothVertices[index++].set(gp, innerSecondaryEnd, transparent, lower ? delta : -delta, delta, m_gradient_is_vertical);
1005 smoothVertices[index++].set(gp, innerSecondaryStart, transparent, lower ? delta : -delta, -delta, m_gradient_is_vertical);
1008 vertices[index++].set(gp, innerSecondaryEnd, fillColor, m_gradient_is_vertical);
1009 vertices[index++].set(gp, innerSecondaryStart, fillColor, m_gradient_is_vertical);
1011 vertices[index++].set(gp, innerSecondaryEnd, borderColor, m_gradient_is_vertical);
1012 vertices[index++].set(gp, innerSecondaryStart, borderColor, m_gradient_is_vertical);
1018 if (!stops.isEmpty()) {
1019 if (nextGradientStop == 0) {
1020 fillColor = colorToColor4ub(stops.at(0).second);
1021 }
else if (nextGradientStop == stops.size()) {
1022 fillColor = colorToColor4ub(stops.last().second);
1024 const QGradientStop &prev = stops.at(nextGradientStop - 1);
1025 const QGradientStop &next = stops.at(nextGradientStop);
1026 float t = (gradientPos - prev.first) / (next.first - prev.first);
1027 fillColor = colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t;
1032 indices[fillHead++] = index;
1033 indices[fillHead++] = index + 1;
1037 indices[--borderHead] = index + 4;
1038 indices[--borderHead] = index + 2;
1039 indices[borderTail++] = index + 3;
1040 indices[borderTail++] = index + 5;
1043 if (m_antialiasing) {
1044 indices[--innerAAHead] = index + 2;
1045 indices[--innerAAHead] = index;
1046 indices[innerAATail++] = index + 1;
1047 indices[innerAATail++] = index + 3;
1049 float dp = part == 1 ? qMin(0.0f, gradientLength - innerEdge - delta) : qMax(0.0f, delta - innerEdge);
1050 smoothVertices[index++].set(innerEdge, innerSecondaryEnd, fillColor, dp, secondaryLength - innerSecondaryEnd - delta, m_gradient_is_vertical);
1051 smoothVertices[index++].set(innerEdge, innerSecondaryStart, fillColor, dp, delta - innerSecondaryStart, m_gradient_is_vertical);
1054 smoothVertices[index++].set(innerEdge, innerSecondaryEnd, borderColor, 0.49f * penWidth * part, 0.49f * penWidth, m_gradient_is_vertical);
1055 smoothVertices[index++].set(innerEdge, innerSecondaryStart, borderColor, 0.49f * penWidth * part, -0.49f * penWidth, m_gradient_is_vertical);
1056 smoothVertices[index++].set(outerEdge, outerSecondaryEnd, borderColor, -0.49f * penWidth * part, -0.49f * penWidth, m_gradient_is_vertical);
1057 smoothVertices[index++].set(outerEdge, outerSecondaryStart, borderColor, -0.49f * penWidth * part, 0.49f * penWidth, m_gradient_is_vertical);
1058 smoothVertices[index++].set(outerEdge, outerSecondaryEnd, transparent, delta * part, delta, m_gradient_is_vertical);
1059 smoothVertices[index++].set(outerEdge, outerSecondaryStart, transparent, delta * part, -delta, m_gradient_is_vertical);
1061 indices[--outerAAHead] = index - 2;
1062 indices[--outerAAHead] = index - 4;
1063 indices[outerAATail++] = index - 3;
1064 indices[outerAATail++] = index - 1;
1066 smoothVertices[index++].set(innerEdge, innerSecondaryEnd, transparent, delta * part, delta, m_gradient_is_vertical);
1067 smoothVertices[index++].set(innerEdge, innerSecondaryStart, transparent, delta * part, -delta, m_gradient_is_vertical);
1070 vertices[index++].set(innerEdge, innerSecondaryEnd, fillColor, m_gradient_is_vertical);
1071 vertices[index++].set(innerEdge, innerSecondaryStart, fillColor, m_gradient_is_vertical);
1073 vertices[index++].set(innerEdge, innerSecondaryEnd, borderColor, m_gradient_is_vertical);
1074 vertices[index++].set(innerEdge, innerSecondaryStart, borderColor, m_gradient_is_vertical);
1075 vertices[index++].set(outerEdge, outerSecondaryEnd, borderColor, m_gradient_is_vertical);
1076 vertices[index++].set(outerEdge, outerSecondaryStart, borderColor, m_gradient_is_vertical);
1080 Q_ASSERT(index == vertexCount);
1083 if (m_antialiasing) {
1084 indices[--innerAAHead] = indices[innerAATail - 1];
1085 indices[--innerAAHead] = indices[innerAATail - 2];
1086 Q_ASSERT(innerAATail <= indexCount);
1089 indices[--borderHead] = indices[borderTail - 1];
1090 indices[--borderHead] = indices[borderTail - 2];
1091 Q_ASSERT(borderTail <= indexCount);
1093 if (m_antialiasing && penWidth) {
1094 indices[--outerAAHead] = indices[outerAATail - 1];
1095 indices[--outerAAHead] = indices[outerAATail - 2];
1096 Q_ASSERT(outerAATail == indexCount);