291 if (dataStr.isEmpty())
295 const int maxElementCount = 0x7fff;
296 qreal x0 = 0, y0 = 0;
302 while (!dataStr.isEmpty() && !done) {
303 while (dataStr.first().isSpace() && dataStr.length() > 1)
305 QChar pathElem = dataStr.first();
307 const char *pattern =
nullptr;
308 if (pathElem == QLatin1Char(
'a') || pathElem == QLatin1Char(
'A'))
310 QVarLengthArray<qreal, 8> arg;
312 if (pathElem == QLatin1Char(
'z') || pathElem == QLatin1Char(
'Z'))
314 const qreal *num = arg.constData();
315 int count = arg.size();
319 switch (pathElem.unicode()) {
326 x = x0 = num[0] + offsetX;
327 y = y0 = num[1] + offsetY;
335 pathElem = QLatin1Char(
'l');
354 pathElem = QLatin1Char(
'L');
373 x = num[0] + offsetX;
374 y = num[1] + offsetY;
396 x = num[0] + offsetX;
410 y = num[0] + offsetY;
430 QPointF c1(num[0] + offsetX, num[1] + offsetY);
431 QPointF c2(num[2] + offsetX, num[3] + offsetY);
432 QPointF e(num[4] + offsetX, num[5] + offsetY);
435 path.cubicTo(c1, c2, e);
448 QPointF c1(num[0], num[1]);
449 QPointF c2(num[2], num[3]);
450 QPointF e(num[4], num[5]);
453 path.cubicTo(c1, c2, e);
467 if (lastMode ==
'c' || lastMode ==
'C' ||
468 lastMode ==
's' || lastMode ==
'S')
469 c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
472 QPointF c2(num[0] + offsetX, num[1] + offsetY);
473 QPointF e(num[2] + offsetX, num[3] + offsetY);
476 path.cubicTo(c1, c2, e);
490 if (lastMode ==
'c' || lastMode ==
'C' ||
491 lastMode ==
's' || lastMode ==
'S')
492 c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
495 QPointF c2(num[0], num[1]);
496 QPointF e(num[2], num[3]);
499 path.cubicTo(c1, c2, e);
512 QPointF c(num[0] + offsetX, num[1] + offsetY);
513 QPointF e(num[2] + offsetX, num[3] + offsetY);
529 QPointF c(num[0], num[1]);
530 QPointF e(num[2], num[3]);
546 QPointF e(num[0] + offsetX, num[1] + offsetY);
550 if (lastMode ==
'q' || lastMode ==
'Q' ||
551 lastMode ==
't' || lastMode ==
'T')
552 c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
568 QPointF e(num[0], num[1]);
572 if (lastMode ==
'q' || lastMode ==
'Q' ||
573 lastMode ==
't' || lastMode ==
'T')
574 c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
592 qreal xAxisRotation = (*num++);
593 qreal largeArcFlag = (*num++);
594 qreal sweepFlag = (*num++);
595 qreal ex = (*num++) + offsetX;
596 qreal ey = (*num++) + offsetY;
600 pathArc(path, rx, ry, xAxisRotation,
int(largeArcFlag),
601 int(sweepFlag), ex, ey, curx, cury);
616 qreal xAxisRotation = (*num++);
617 qreal largeArcFlag = (*num++);
618 qreal sweepFlag = (*num++);
624 pathArc(path, rx, ry, xAxisRotation,
int(largeArcFlag),
625 int(sweepFlag), ex, ey, curx, cury);
634 lastMode = pathElem.toLatin1();
635 if (limitLength && path.elementCount() > maxElementCount)
669void pathArc(QPainterPath &path, qreal rx, qreal ry,
670 qreal x_axis_rotation,
int large_arc_flag,
671 int sweep_flag, qreal x, qreal y,
672 qreal curx, qreal cury)
675 if (QPointF(curx, cury) == QPointF(x, y))
678 const qreal Pr1 = rx * rx;
679 const qreal Pr2 = ry * ry;
682 if (qFuzzyIsNull(Pr1) || qFuzzyIsNull(Pr2)) {
690 qreal sin_th, cos_th;
691 qreal a00, a01, a10, a11;
692 qreal x0, y0, x1, y1, xc, yc;
693 qreal d, sfactor, sfactor_sq;
694 qreal th0, th1, th_arc;
696 qreal dx, dy, dx1, dy1, Px, Py, check;
701 sin_th = qSin(x_axis_rotation * (Q_PI / 180.0));
702 cos_th = qCos(x_axis_rotation * (Q_PI / 180.0));
704 dx = (curx - x) / 2.0;
705 dy = (cury - y) / 2.0;
706 dx1 = cos_th * dx + sin_th * dy;
707 dy1 = -sin_th * dx + cos_th * dy;
711 check = Px / Pr1 + Py / Pr2;
713 rx = rx * qSqrt(check);
714 ry = ry * qSqrt(check);
721 x0 = a00 * curx + a01 * cury;
722 y0 = a10 * curx + a11 * cury;
723 x1 = a00 * x + a01 * y;
724 y1 = a10 * x + a11 * y;
726
727
728
729
730 d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
733 sfactor_sq = 1.0 / d - 0.25;
734 if (sfactor_sq < 0) sfactor_sq = 0;
735 sfactor = qSqrt(sfactor_sq);
736 if (sweep_flag == large_arc_flag) sfactor = -sfactor;
737 xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
738 yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
741 th0 = qAtan2(y0 - yc, x0 - xc);
742 th1 = qAtan2(y1 - yc, x1 - xc);
745 if (th_arc < 0 && sweep_flag)
747 else if (th_arc > 0 && !sweep_flag)
750 n_segs = qCeil(qAbs(th_arc / (Q_PI * 0.5 + 0.001)));
752 for (i = 0; i < n_segs; i++) {
753 pathArcSegment(path, xc, yc,
754 th0 + i * th_arc / n_segs,
755 th0 + (i + 1) * th_arc / n_segs,
756 rx, ry, x_axis_rotation);