1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtQuick module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QQUICKPATH_H 41 #define QQUICKPATH_H 42 43 // 44 // W A R N I N G 45 // ------------- 46 // 47 // This file is not part of the Qt API. It exists purely as an 48 // implementation detail. This header file may change from version to 49 // version without notice, or even be removed. 50 // 51 // We mean it. 52 // 53 54 #include <private/qtquickglobal_p.h> 55 56 QT_REQUIRE_CONFIG(quick_path); 57 58 #include <qqml.h> 59 60 #include <private/qqmlnullablevalue_p.h> 61 #include <private/qbezier_p.h> 62 #include <private/qtquickglobal_p.h> 63 64 #include <QtCore/QObject> 65 #include <QtGui/QPainterPath> 66 #include <QtGui/QFont> 67 68 QT_BEGIN_NAMESPACE 69 70 class QQuickCurve; 71 struct QQuickPathData 72 { 73 int index; 74 QPointF endPoint; 75 QList<QQuickCurve*> curves; 76 }; 77 78 class Q_QUICK_PRIVATE_EXPORT QQuickPathElement : public QObject 79 { 80 Q_OBJECT 81 QML_ANONYMOUS 82 public: QObject(parent)83 QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {} 84 Q_SIGNALS: 85 void changed(); 86 }; 87 88 class Q_QUICK_PRIVATE_EXPORT QQuickPathAttribute : public QQuickPathElement 89 { 90 Q_OBJECT 91 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)92 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) 93 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged) 94 QML_NAMED_ELEMENT(PathAttribute) 95 public: 96 QQuickPathAttribute(QObject *parent=nullptr) : QQuickPathElement(parent) {} 97 98 99 QString name() const; 100 void setName(const QString &name); 101 102 qreal value() const; 103 void setValue(qreal value); 104 105 Q_SIGNALS: 106 void nameChanged(); 107 void valueChanged(); 108 109 private: 110 QString _name; 111 qreal _value = 0; 112 }; 113 114 class Q_QUICK_PRIVATE_EXPORT QQuickCurve : public QQuickPathElement 115 { 116 Q_OBJECT 117 Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)118 Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) 119 Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) 120 Q_PROPERTY(qreal relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged) 121 Q_PROPERTY(qreal relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged) 122 QML_ANONYMOUS 123 public: 124 QQuickCurve(QObject *parent=nullptr) : QQuickPathElement(parent) {} 125 126 qreal x() const; 127 void setX(qreal x); 128 bool hasX(); 129 130 qreal y() const; 131 void setY(qreal y); 132 bool hasY(); 133 134 qreal relativeX() const; 135 void setRelativeX(qreal x); 136 bool hasRelativeX(); 137 138 qreal relativeY() const; 139 void setRelativeY(qreal y); 140 bool hasRelativeY(); 141 addToPath(QPainterPath &,const QQuickPathData &)142 virtual void addToPath(QPainterPath &, const QQuickPathData &) {} 143 144 Q_SIGNALS: 145 void xChanged(); 146 void yChanged(); 147 void relativeXChanged(); 148 void relativeYChanged(); 149 150 private: 151 QQmlNullableValue<qreal> _x; 152 QQmlNullableValue<qreal> _y; 153 QQmlNullableValue<qreal> _relativeX; 154 QQmlNullableValue<qreal> _relativeY; 155 }; 156 157 class Q_QUICK_PRIVATE_EXPORT QQuickPathLine : public QQuickCurve 158 { 159 Q_OBJECT QML_NAMED_ELEMENT(PathLine)160 QML_NAMED_ELEMENT(PathLine) 161 public: 162 QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {} 163 164 void addToPath(QPainterPath &path, const QQuickPathData &) override; 165 }; 166 167 class Q_QUICK_PRIVATE_EXPORT QQuickPathMove : public QQuickCurve 168 { 169 Q_OBJECT QML_NAMED_ELEMENT(PathMove)170 QML_NAMED_ELEMENT(PathMove) 171 QML_ADDED_IN_MINOR_VERSION(9) 172 public: 173 QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {} 174 175 void addToPath(QPainterPath &path, const QQuickPathData &) override; 176 }; 177 178 class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve 179 { 180 Q_OBJECT 181 Q_PROPERTY(qreal controlX READ controlX WRITE setControlX NOTIFY controlXChanged)182 Q_PROPERTY(qreal controlX READ controlX WRITE setControlX NOTIFY controlXChanged) 183 Q_PROPERTY(qreal controlY READ controlY WRITE setControlY NOTIFY controlYChanged) 184 Q_PROPERTY(qreal relativeControlX READ relativeControlX WRITE setRelativeControlX NOTIFY relativeControlXChanged) 185 Q_PROPERTY(qreal relativeControlY READ relativeControlY WRITE setRelativeControlY NOTIFY relativeControlYChanged) 186 187 QML_NAMED_ELEMENT(PathQuad) 188 public: 189 QQuickPathQuad(QObject *parent=nullptr) : QQuickCurve(parent) {} 190 191 qreal controlX() const; 192 void setControlX(qreal x); 193 194 qreal controlY() const; 195 void setControlY(qreal y); 196 197 qreal relativeControlX() const; 198 void setRelativeControlX(qreal x); 199 bool hasRelativeControlX(); 200 201 qreal relativeControlY() const; 202 void setRelativeControlY(qreal y); 203 bool hasRelativeControlY(); 204 205 void addToPath(QPainterPath &path, const QQuickPathData &) override; 206 207 Q_SIGNALS: 208 void controlXChanged(); 209 void controlYChanged(); 210 void relativeControlXChanged(); 211 void relativeControlYChanged(); 212 213 private: 214 qreal _controlX = 0; 215 qreal _controlY = 0; 216 QQmlNullableValue<qreal> _relativeControlX; 217 QQmlNullableValue<qreal> _relativeControlY; 218 }; 219 220 class Q_QUICK_PRIVATE_EXPORT QQuickPathCubic : public QQuickCurve 221 { 222 Q_OBJECT 223 Q_PROPERTY(qreal control1X READ control1X WRITE setControl1X NOTIFY control1XChanged)224 Q_PROPERTY(qreal control1X READ control1X WRITE setControl1X NOTIFY control1XChanged) 225 Q_PROPERTY(qreal control1Y READ control1Y WRITE setControl1Y NOTIFY control1YChanged) 226 Q_PROPERTY(qreal control2X READ control2X WRITE setControl2X NOTIFY control2XChanged) 227 Q_PROPERTY(qreal control2Y READ control2Y WRITE setControl2Y NOTIFY control2YChanged) 228 Q_PROPERTY(qreal relativeControl1X READ relativeControl1X WRITE setRelativeControl1X NOTIFY relativeControl1XChanged) 229 Q_PROPERTY(qreal relativeControl1Y READ relativeControl1Y WRITE setRelativeControl1Y NOTIFY relativeControl1YChanged) 230 Q_PROPERTY(qreal relativeControl2X READ relativeControl2X WRITE setRelativeControl2X NOTIFY relativeControl2XChanged) 231 Q_PROPERTY(qreal relativeControl2Y READ relativeControl2Y WRITE setRelativeControl2Y NOTIFY relativeControl2YChanged) 232 QML_NAMED_ELEMENT(PathCubic) 233 public: 234 QQuickPathCubic(QObject *parent=nullptr) : QQuickCurve(parent) {} 235 236 qreal control1X() const; 237 void setControl1X(qreal x); 238 239 qreal control1Y() const; 240 void setControl1Y(qreal y); 241 242 qreal control2X() const; 243 void setControl2X(qreal x); 244 245 qreal control2Y() const; 246 void setControl2Y(qreal y); 247 248 qreal relativeControl1X() const; 249 void setRelativeControl1X(qreal x); 250 bool hasRelativeControl1X(); 251 252 qreal relativeControl1Y() const; 253 void setRelativeControl1Y(qreal y); 254 bool hasRelativeControl1Y(); 255 256 qreal relativeControl2X() const; 257 void setRelativeControl2X(qreal x); 258 bool hasRelativeControl2X(); 259 260 qreal relativeControl2Y() const; 261 void setRelativeControl2Y(qreal y); 262 bool hasRelativeControl2Y(); 263 264 void addToPath(QPainterPath &path, const QQuickPathData &) override; 265 266 Q_SIGNALS: 267 void control1XChanged(); 268 void control1YChanged(); 269 void control2XChanged(); 270 void control2YChanged(); 271 void relativeControl1XChanged(); 272 void relativeControl1YChanged(); 273 void relativeControl2XChanged(); 274 void relativeControl2YChanged(); 275 276 private: 277 qreal _control1X = 0; 278 qreal _control1Y = 0; 279 qreal _control2X = 0; 280 qreal _control2Y = 0; 281 QQmlNullableValue<qreal> _relativeControl1X; 282 QQmlNullableValue<qreal> _relativeControl1Y; 283 QQmlNullableValue<qreal> _relativeControl2X; 284 QQmlNullableValue<qreal> _relativeControl2Y; 285 }; 286 287 class Q_QUICK_PRIVATE_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve 288 { 289 Q_OBJECT QML_NAMED_ELEMENT(PathCurve)290 QML_NAMED_ELEMENT(PathCurve) 291 public: 292 QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {} 293 294 void addToPath(QPainterPath &path, const QQuickPathData &) override; 295 }; 296 297 class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve 298 { 299 Q_OBJECT Q_PROPERTY(qreal radiusX READ radiusX WRITE setRadiusX NOTIFY radiusXChanged)300 Q_PROPERTY(qreal radiusX READ radiusX WRITE setRadiusX NOTIFY radiusXChanged) 301 Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged) 302 Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged) 303 Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged) 304 Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 9) 305 QML_NAMED_ELEMENT(PathArc) 306 307 public: 308 QQuickPathArc(QObject *parent=nullptr) 309 : QQuickCurve(parent) {} 310 311 enum ArcDirection { Clockwise, Counterclockwise }; 312 Q_ENUM(ArcDirection) 313 314 qreal radiusX() const; 315 void setRadiusX(qreal); 316 317 qreal radiusY() const; 318 void setRadiusY(qreal); 319 320 bool useLargeArc() const; 321 void setUseLargeArc(bool); 322 323 ArcDirection direction() const; 324 void setDirection(ArcDirection direction); 325 326 qreal xAxisRotation() const; 327 void setXAxisRotation(qreal rotation); 328 329 void addToPath(QPainterPath &path, const QQuickPathData &) override; 330 331 Q_SIGNALS: 332 void radiusXChanged(); 333 void radiusYChanged(); 334 void useLargeArcChanged(); 335 void directionChanged(); 336 Q_REVISION(9) void xAxisRotationChanged(); 337 338 private: 339 qreal _radiusX = 0; 340 qreal _radiusY = 0; 341 bool _useLargeArc = false; 342 ArcDirection _direction = Clockwise; 343 qreal _xAxisRotation = 0; 344 }; 345 346 class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve 347 { 348 Q_OBJECT Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX NOTIFY centerXChanged)349 Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX NOTIFY centerXChanged) 350 Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY NOTIFY centerYChanged) 351 Q_PROPERTY(qreal radiusX READ radiusX WRITE setRadiusX NOTIFY radiusXChanged) 352 Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged) 353 Q_PROPERTY(qreal startAngle READ startAngle WRITE setStartAngle NOTIFY startAngleChanged) 354 Q_PROPERTY(qreal sweepAngle READ sweepAngle WRITE setSweepAngle NOTIFY sweepAngleChanged) 355 Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged) 356 357 QML_NAMED_ELEMENT(PathAngleArc) 358 QML_ADDED_IN_MINOR_VERSION(11) 359 360 public: 361 QQuickPathAngleArc(QObject *parent=nullptr) 362 : QQuickCurve(parent) {} 363 364 qreal centerX() const; 365 void setCenterX(qreal); 366 367 qreal centerY() const; 368 void setCenterY(qreal); 369 370 qreal radiusX() const; 371 void setRadiusX(qreal); 372 373 qreal radiusY() const; 374 void setRadiusY(qreal); 375 376 qreal startAngle() const; 377 void setStartAngle(qreal); 378 379 qreal sweepAngle() const; 380 void setSweepAngle(qreal); 381 382 bool moveToStart() const; 383 void setMoveToStart(bool); 384 385 void addToPath(QPainterPath &path, const QQuickPathData &) override; 386 387 Q_SIGNALS: 388 void centerXChanged(); 389 void centerYChanged(); 390 void radiusXChanged(); 391 void radiusYChanged(); 392 void startAngleChanged(); 393 void sweepAngleChanged(); 394 void moveToStartChanged(); 395 396 private: 397 qreal _centerX = 0; 398 qreal _centerY = 0; 399 qreal _radiusX = 0; 400 qreal _radiusY = 0; 401 qreal _startAngle = 0; 402 qreal _sweepAngle = 0; 403 bool _moveToStart = true; 404 }; 405 406 class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve 407 { 408 Q_OBJECT Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)409 Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) 410 QML_NAMED_ELEMENT(PathSvg) 411 public: 412 QQuickPathSvg(QObject *parent=nullptr) : QQuickCurve(parent) {} 413 414 QString path() const; 415 void setPath(const QString &path); 416 417 void addToPath(QPainterPath &path, const QQuickPathData &) override; 418 419 Q_SIGNALS: 420 void pathChanged(); 421 422 private: 423 QString _path; 424 }; 425 426 class Q_QUICK_PRIVATE_EXPORT QQuickPathPercent : public QQuickPathElement 427 { 428 Q_OBJECT Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)429 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged) 430 QML_NAMED_ELEMENT(PathPercent) 431 public: 432 QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {} 433 434 qreal value() const; 435 void setValue(qreal value); 436 437 Q_SIGNALS: 438 void valueChanged(); 439 440 private: 441 qreal _value = 0; 442 }; 443 444 class Q_QUICK_PRIVATE_EXPORT QQuickPathPolyline : public QQuickCurve 445 { 446 Q_OBJECT 447 Q_PROPERTY(QPointF start READ start NOTIFY startChanged) 448 Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged) 449 QML_NAMED_ELEMENT(PathPolyline) 450 QML_ADDED_IN_MINOR_VERSION(14) 451 public: 452 QQuickPathPolyline(QObject *parent=nullptr); 453 454 QVariant path() const; 455 void setPath(const QVariant &path); 456 void setPath(const QVector<QPointF> &path); 457 QPointF start() const; 458 void addToPath(QPainterPath &path, const QQuickPathData &data) override; 459 460 Q_SIGNALS: 461 void pathChanged(); 462 void startChanged(); 463 464 private: 465 QVector<QPointF> m_path; 466 }; 467 468 class Q_QUICK_PRIVATE_EXPORT QQuickPathMultiline : public QQuickCurve 469 { 470 Q_OBJECT 471 Q_PROPERTY(QPointF start READ start NOTIFY startChanged) 472 Q_PROPERTY(QVariant paths READ paths WRITE setPaths NOTIFY pathsChanged) 473 QML_NAMED_ELEMENT(PathMultiline) 474 QML_ADDED_IN_MINOR_VERSION(14) 475 public: 476 QQuickPathMultiline(QObject *parent=nullptr); 477 478 QVariant paths() const; 479 void setPaths(const QVariant &paths); 480 void setPaths(const QVector<QVector<QPointF>> &paths); 481 QPointF start() const; 482 void addToPath(QPainterPath &path, const QQuickPathData &) override; 483 484 Q_SIGNALS: 485 void pathsChanged(); 486 void startChanged(); 487 488 private: 489 QPointF absolute(const QPointF &relative) const; 490 491 QVector<QVector<QPointF>> m_paths; 492 }; 493 494 struct QQuickCachedBezier 495 { QQuickCachedBezierQQuickCachedBezier496 QQuickCachedBezier() {} 497 QBezier bezier; 498 int element; 499 qreal bezLength; 500 qreal currLength; 501 qreal p; 502 bool isValid = false; 503 }; 504 505 class QQuickPathPrivate; 506 class Q_QUICK_PRIVATE_EXPORT QQuickPath : public QObject, public QQmlParserStatus 507 { 508 Q_OBJECT 509 510 Q_INTERFACES(QQmlParserStatus) 511 Q_PROPERTY(QQmlListProperty<QQuickPathElement> pathElements READ pathElements) 512 Q_PROPERTY(qreal startX READ startX WRITE setStartX NOTIFY startXChanged) 513 Q_PROPERTY(qreal startY READ startY WRITE setStartY NOTIFY startYChanged) 514 Q_PROPERTY(bool closed READ isClosed NOTIFY changed) 515 Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14) 516 Q_CLASSINFO("DefaultProperty", "pathElements") 517 QML_NAMED_ELEMENT(Path) 518 Q_INTERFACES(QQmlParserStatus) 519 public: 520 QQuickPath(QObject *parent=nullptr); 521 ~QQuickPath() override; 522 523 QQmlListProperty<QQuickPathElement> pathElements(); 524 525 qreal startX() const; 526 void setStartX(qreal x); 527 bool hasStartX() const; 528 529 qreal startY() const; 530 void setStartY(qreal y); 531 bool hasStartY() const; 532 533 bool isClosed() const; 534 535 QPainterPath path() const; 536 QStringList attributes() const; 537 qreal attributeAt(const QString &, qreal) const; 538 Q_REVISION(14) Q_INVOKABLE QPointF pointAtPercent(qreal t) const; 539 QPointF sequentialPointAt(qreal p, qreal *angle = nullptr) const; 540 void invalidateSequentialHistory() const; 541 542 QSizeF scale() const; 543 void setScale(const QSizeF &scale); 544 545 Q_SIGNALS: 546 void changed(); 547 void startXChanged(); 548 void startYChanged(); 549 Q_REVISION(14) void scaleChanged(); 550 551 protected: 552 QQuickPath(QQuickPathPrivate &dd, QObject *parent = nullptr); 553 void componentComplete() override; 554 void classBegin() override; 555 void disconnectPathElements(); 556 void connectPathElements(); 557 void gatherAttributes(); 558 559 // pathElements property 560 static QQuickPathElement *pathElements_at(QQmlListProperty<QQuickPathElement> *, int); 561 static void pathElements_append(QQmlListProperty<QQuickPathElement> *, QQuickPathElement *); 562 static int pathElements_count(QQmlListProperty<QQuickPathElement> *); 563 static void pathElements_clear(QQmlListProperty<QQuickPathElement> *); 564 565 private Q_SLOTS: 566 void processPath(); 567 568 private: 569 struct AttributePoint { AttributePointAttributePoint570 AttributePoint() {} AttributePointAttributePoint571 AttributePoint(const AttributePoint &other) 572 : percent(other.percent), scale(other.scale), origpercent(other.origpercent), values(other.values) {} 573 AttributePoint &operator=(const AttributePoint &other) { 574 percent = other.percent; scale = other.scale; origpercent = other.origpercent; values = other.values; return *this; 575 } 576 qreal percent = 0; //massaged percent along the painter path 577 qreal scale = 1; 578 qreal origpercent = 0; //'real' percent along the painter path 579 QHash<QString, qreal> values; 580 }; 581 582 void interpolate(int idx, const QString &name, qreal value); 583 void endpoint(const QString &name); 584 void createPointCache() const; 585 586 static void interpolate(QList<AttributePoint> &points, int idx, const QString &name, qreal value); 587 static void endpoint(QList<AttributePoint> &attributePoints, const QString &name); 588 static QPointF forwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr); 589 static QPointF backwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr); 590 591 private: 592 Q_DISABLE_COPY(QQuickPath) 593 Q_DECLARE_PRIVATE(QQuickPath) 594 friend class QQuickPathAnimationUpdater; 595 596 public: 597 QPainterPath createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed = nullptr); 598 QPainterPath createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed = nullptr); 599 static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr); 600 }; 601 602 class Q_QUICK_PRIVATE_EXPORT QQuickPathText : public QQuickPathElement 603 { 604 Q_OBJECT Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)605 Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) 606 Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) 607 Q_PROPERTY(qreal width READ width NOTIFY changed) 608 Q_PROPERTY(qreal height READ height NOTIFY changed) 609 Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) 610 Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) 611 QML_NAMED_ELEMENT(PathText) 612 QML_ADDED_IN_MINOR_VERSION(15) 613 public: 614 QQuickPathText(QObject *parent=nullptr) : QQuickPathElement(parent) 615 { 616 connect(this, &QQuickPathText::xChanged, this, &QQuickPathElement::changed); 617 connect(this, &QQuickPathText::yChanged, this, &QQuickPathElement::changed); 618 connect(this, &QQuickPathText::textChanged, this, &QQuickPathElement::changed); 619 connect(this, &QQuickPathText::fontChanged, this, &QQuickPathElement::changed); 620 621 connect(this, &QQuickPathElement::changed, this, &QQuickPathText::invalidate); 622 } 623 624 void addToPath(QPainterPath &path); 625 x()626 qreal x() const { return _x; } y()627 qreal y() const { return _y; } text()628 QString text() const { return _text; } font()629 QFont font() const { return _font; } 630 setX(qreal x)631 void setX(qreal x) 632 { 633 if (qFuzzyCompare(_x, x)) 634 return; 635 636 _x = x; 637 Q_EMIT xChanged(); 638 } 639 setY(qreal y)640 void setY(qreal y) 641 { 642 if (qFuzzyCompare(_y, y)) 643 return; 644 645 _y = y; 646 Q_EMIT yChanged(); 647 } 648 setText(const QString & text)649 void setText(const QString &text) 650 { 651 if (text == _text) 652 return; 653 654 _text = text; 655 Q_EMIT textChanged(); 656 } 657 setFont(const QFont & font)658 void setFont(const QFont &font) 659 { 660 if (font == _font) 661 return; 662 663 _font = font; 664 Q_EMIT fontChanged(); 665 } 666 width()667 qreal width() const 668 { 669 updatePath(); 670 return _path.boundingRect().width(); 671 } 672 height()673 qreal height() const 674 { 675 updatePath(); 676 return _path.boundingRect().height(); 677 } 678 679 Q_SIGNALS: 680 void xChanged(); 681 void yChanged(); 682 void textChanged(); 683 void fontChanged(); 684 685 private Q_SLOTS: invalidate()686 void invalidate() 687 { 688 _path.clear(); 689 } 690 691 private: 692 void updatePath() const; 693 694 QString _text; 695 qreal _x = qreal(0.0); 696 qreal _y = qreal(0.0); 697 QFont _font; 698 699 mutable QPainterPath _path; 700 }; 701 702 QT_END_NAMESPACE 703 704 QML_DECLARE_TYPE(QQuickPathElement) 705 QML_DECLARE_TYPE(QQuickPathAttribute) 706 QML_DECLARE_TYPE(QQuickCurve) 707 QML_DECLARE_TYPE(QQuickPathLine) 708 QML_DECLARE_TYPE(QQuickPathMove) 709 QML_DECLARE_TYPE(QQuickPathQuad) 710 QML_DECLARE_TYPE(QQuickPathCubic) 711 QML_DECLARE_TYPE(QQuickPathCatmullRomCurve) 712 QML_DECLARE_TYPE(QQuickPathArc) 713 QML_DECLARE_TYPE(QQuickPathAngleArc) 714 QML_DECLARE_TYPE(QQuickPathSvg) 715 QML_DECLARE_TYPE(QQuickPathPercent) 716 QML_DECLARE_TYPE(QQuickPathPolyline) 717 QML_DECLARE_TYPE(QQuickPath) 718 QML_DECLARE_TYPE(QQuickPathText) 719 720 #endif // QQUICKPATH_H 721