diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2019-05-06 20:37:42 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-06-04 20:52:01 +0200 |
commit | 3961cf124af9d811da4bbe72bb28508aef71c7df (patch) | |
tree | 221298e19225250c3b53c80d05693c4398ee7854 | |
parent | 00b317a19eed629d041d27596e40c1cf24fdf1a6 (diff) |
Add scale property to QQuickPath
With this property, Paths and ShapePaths become scalable.
[ChangeLog][QQuick][Path] Added scale property to scale
a path before sending it in to PathView/Shape.
Change-Id: Id9ce7d1247d55e2cdb0d27a19c86fe0970e66268
Fixes: QTBUG-74456
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r-- | src/imports/shapes/plugin.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/qquickitemsmodule.cpp | 1 | ||||
-rw-r--r-- | src/quick/util/qquickpath.cpp | 45 | ||||
-rw-r--r-- | src/quick/util/qquickpath_p.h | 5 | ||||
-rw-r--r-- | src/quick/util/qquickpath_p_p.h | 1 | ||||
-rw-r--r-- | src/quickshapes/qquickshape_p.h | 1 | ||||
-rw-r--r-- | tests/auto/quick/qquickpath/qquickpath.pro | 1 | ||||
-rw-r--r-- | tests/auto/quick/qquickpath/tst_qquickpath.cpp | 156 | ||||
-rw-r--r-- | tests/auto/quick/qquickshape/qquickshape.pro | 1 | ||||
-rw-r--r-- | tests/auto/quick/qquickshape/tst_qquickshape.cpp | 2 | ||||
-rw-r--r-- | tests/manual/scalablepath/ShapeTestScale.qml | 287 | ||||
-rw-r--r-- | tests/manual/scalablepath/main.cpp | 42 | ||||
-rw-r--r-- | tests/manual/scalablepath/main.qml | 42 | ||||
-rw-r--r-- | tests/manual/scalablepath/qml.qrc | 6 | ||||
-rw-r--r-- | tests/manual/scalablepath/scalablepath.pro | 5 |
15 files changed, 559 insertions, 39 deletions
diff --git a/src/imports/shapes/plugin.cpp b/src/imports/shapes/plugin.cpp index e3a9017681..0679a70630 100644 --- a/src/imports/shapes/plugin.cpp +++ b/src/imports/shapes/plugin.cpp @@ -69,6 +69,9 @@ public: // revision in Qt 5.11: added containsMode property qmlRegisterType<QQuickShape, 11>(uri, 1, 11, "Shape"); + + // revision in Qt 5.14: added scale property + qmlRegisterType<QQuickShapePath, 14>(uri, 1, 14, "ShapePath"); // QTBUG-61942 } }; diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index eaad06e0c4..4649e33070 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -226,6 +226,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickPathCatmullRomCurve>("QtQuick",2,0,"PathCurve"); qmlRegisterType<QQuickPathArc>("QtQuick",2,0,"PathArc"); qmlRegisterType<QQuickPathSvg>("QtQuick",2,0,"PathSvg"); + qmlRegisterType<QQuickPath, 14>(uri, 2, 14, "Path"); #endif #if QT_CONFIG(quick_pathview) qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView"); diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index 16723b997e..a0f3749552 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -407,6 +407,19 @@ void QQuickPath::processPath() emit changed(); } +inline static void scalePath(QPainterPath &path, const QSizeF &scale) +{ + const qreal xscale = scale.width(); + const qreal yscale = scale.height(); + if (xscale == 1 && yscale == 1) + return; + + for (int i = 0; i < path.elementCount(); ++i) { + const QPainterPath::Element &element = path.elementAt(i); + path.setElementPositionAt(i, element.x * xscale, element.y * yscale); + } +} + QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed) { Q_D(QQuickPath); @@ -465,7 +478,7 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en d->_attributePoints.last().values[percentString] = 1; interpolate(d->_attributePoints.count() - 1, percentString, 1); } - + scalePath(path, d->scale); // Adjust percent qreal length = path.length(); @@ -491,7 +504,7 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en if (closed) { QPointF end = path.currentPosition(); - *closed = length > 0 && startX == end.x() && startY == end.y(); + *closed = length > 0 && startX * d->scale.width() == end.x() && startY * d->scale.height() == end.y(); } pathLength = length; @@ -525,6 +538,7 @@ QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPoint QPointF end = path.currentPosition(); *closed = startX == end.x() && startY == end.y(); } + scalePath(path, d->scale); // Note: Length of paths inside ShapePath is not used, so currently // length is always 0. This avoids potentially heavy path.length() @@ -723,6 +737,33 @@ void QQuickPath::invalidateSequentialHistory() const d->prevBez.isValid = false; } +/*! + \qmlproperty size QtQuick::Path::scale + + This property holds the scale factor for the path. + The width and height of \a scale can be different, to + achieve anisotropic scaling. + + \note Setting this property will not affect the border width. + + \since QtQuick 2.14 +*/ +QSizeF QQuickPath::scale() const +{ + Q_D(const QQuickPath); + return d->scale; +} + +void QQuickPath::setScale(const QSizeF &scale) +{ + Q_D(QQuickPath); + if (scale == d->scale) + return; + d->scale = scale; + emit scaleChanged(); + processPath(); +} + QPointF QQuickPath::sequentialPointAt(qreal p, qreal *angle) const { Q_D(const QQuickPath); diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index 6b9a40fe6d..01f60c34d2 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -445,6 +445,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPath : public QObject, public QQmlParserStatu Q_PROPERTY(qreal startX READ startX WRITE setStartX NOTIFY startXChanged) Q_PROPERTY(qreal startY READ startY WRITE setStartY NOTIFY startYChanged) Q_PROPERTY(bool closed READ isClosed NOTIFY changed) + Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14) Q_CLASSINFO("DefaultProperty", "pathElements") Q_INTERFACES(QQmlParserStatus) public: @@ -470,10 +471,14 @@ public: QPointF sequentialPointAt(qreal p, qreal *angle = nullptr) const; void invalidateSequentialHistory() const; + QSizeF scale() const; + void setScale(const QSizeF &scale); + Q_SIGNALS: void changed(); void startXChanged(); void startYChanged(); + Q_REVISION(14) void scaleChanged(); protected: QQuickPath(QQuickPathPrivate &dd, QObject *parent = nullptr); diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h index 9735d51264..e26001ec77 100644 --- a/src/quick/util/qquickpath_p_p.h +++ b/src/quick/util/qquickpath_p_p.h @@ -84,6 +84,7 @@ public: QQmlNullableValue<qreal> startX; QQmlNullableValue<qreal> startY; qreal pathLength = 0; + QSizeF scale = QSizeF(1, 1); bool closed = false; bool componentComplete = true; bool isShapePath = false; diff --git a/src/quickshapes/qquickshape_p.h b/src/quickshapes/qquickshape_p.h index cd242cafc3..7066ea0709 100644 --- a/src/quickshapes/qquickshape_p.h +++ b/src/quickshapes/qquickshape_p.h @@ -213,6 +213,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapePath : public QQuickPath Q_PROPERTY(qreal dashOffset READ dashOffset WRITE setDashOffset NOTIFY dashOffsetChanged) Q_PROPERTY(QVector<qreal> dashPattern READ dashPattern WRITE setDashPattern NOTIFY dashPatternChanged) Q_PROPERTY(QQuickShapeGradient *fillGradient READ fillGradient WRITE setFillGradient RESET resetFillGradient) + Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14) public: enum FillRule { diff --git a/tests/auto/quick/qquickpath/qquickpath.pro b/tests/auto/quick/qquickpath/qquickpath.pro index 492f82f53d..ef110a8331 100644 --- a/tests/auto/quick/qquickpath/qquickpath.pro +++ b/tests/auto/quick/qquickpath/qquickpath.pro @@ -7,5 +7,6 @@ SOURCES += tst_qquickpath.cpp include (../../shared/util.pri) TESTDATA = data/* +DISTFILES = data/* QT += core-private gui-private qml-private quick-private testlib diff --git a/tests/auto/quick/qquickpath/tst_qquickpath.cpp b/tests/auto/quick/qquickpath/tst_qquickpath.cpp index 12a8c673b0..bac1fc5861 100644 --- a/tests/auto/quick/qquickpath/tst_qquickpath.cpp +++ b/tests/auto/quick/qquickpath/tst_qquickpath.cpp @@ -42,18 +42,44 @@ public: private slots: void arc(); void angleArc(); - void catmullromCurve(); - void closedCatmullromCurve(); + void catmullRomCurve(); + void closedCatmullRomCurve(); void svg(); void line(); + +private: + void arc(QSizeF scale); + void angleArc(QSizeF scale); + void catmullRomCurve(QSizeF scale, const QVector<QPointF> &points); + void closedCatmullRomCurve(QSizeF scale, const QVector<QPointF> &points); + void svg(QSizeF scale); + void line(QSizeF scale); }; -void tst_QuickPath::arc() +static void compare(const QPointF &point, const QSizeF &scale, int line, double x, double y) +{ + QVERIFY2(qFuzzyCompare(float(point.x()), float(x * scale.width())), + (QStringLiteral("Actual: ") + QString::number(point.x(),'g',14) + + QStringLiteral(" Expected: ") + QString::number(x * scale.width(),'g',14) + + QStringLiteral(" At: ") + QString::number(line)).toLatin1().data()); + QVERIFY2(qFuzzyCompare(float(point.y()), float(y * scale.height())), + (QStringLiteral("Actual: ") + QString::number(point.y(),'g',14) + + QStringLiteral(" Expected: ") + QString::number(y * scale.height(),'g',14) + + QStringLiteral(" At: ") + QString::number(line)).toLatin1().data()); +} +static void compare(const QPointF &point, int line, const QPointF &pt) +{ + return compare(point, QSizeF(1,1), line, pt.x(), pt.y()); +} + +void tst_QuickPath::arc(QSizeF scale) { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("arc.qml")); QQuickPath *obj = qobject_cast<QQuickPath*>(c.create()); QVERIFY(obj != nullptr); + if (scale != QSizeF(1,1)) + obj->setProperty("scale", scale); QCOMPARE(obj->startX(), 0.); QCOMPARE(obj->startY(), 0.); @@ -76,19 +102,27 @@ void tst_QuickPath::arc() QPointF pos = obj->pointAt(0); QCOMPARE(pos, QPointF(0,0)); pos = obj->pointAt(.25); - QCOMPARE(pos.toPoint(), QPoint(39,8)); //fuzzy compare + compare(pos, scale, __LINE__, 38.9244897744, 7.85853964341); pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(92,61)); //fuzzy compare + compare(pos, scale, __LINE__, 92.141460356592, 61.07551022559); pos = obj->pointAt(1); - QCOMPARE(pos, QPointF(100,100)); + QCOMPARE(pos, QPointF(100 * scale.width(), 100 * scale.height())); } -void tst_QuickPath::angleArc() +void tst_QuickPath::arc() +{ + arc(QSizeF(1,1)); + arc(QSizeF(2.2,3.4)); +} + +void tst_QuickPath::angleArc(QSizeF scale) { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("anglearc.qml")); QQuickPath *obj = qobject_cast<QQuickPath*>(c.create()); QVERIFY(obj != nullptr); + if (scale != QSizeF(1,1)) + obj->setProperty("scale", scale); QQmlListReference list(obj, "pathElements"); QCOMPARE(list.count(), 1); @@ -106,15 +140,14 @@ void tst_QuickPath::angleArc() QPainterPath path = obj->path(); QVERIFY(path != QPainterPath()); - // using QPoint to do fuzzy compare QPointF pos = obj->pointAt(0); - QCOMPARE(pos.toPoint(), QPoint(135,135)); + compare(pos, scale, __LINE__, 135.35533905867, 135.35533905867); pos = obj->pointAt(.25); - QCOMPARE(pos.toPoint(), QPoint(119,146)); + compare(pos, scale, __LINE__, 119.46222180396, 146.07068621369); pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(81,146)); + compare(pos, scale, __LINE__, 80.537778196007, 146.07068621366); pos = obj->pointAt(1); - QCOMPARE(pos.toPoint(), QPoint(65,135)); + compare(pos, scale, __LINE__, 64.644660941173, 135.35533905867); // if moveToStart is false, we should have a line starting from startX/Y arc->setMoveToStart(false); @@ -122,12 +155,20 @@ void tst_QuickPath::angleArc() QCOMPARE(pos, QPointF(0,0)); } -void tst_QuickPath::catmullromCurve() +void tst_QuickPath::angleArc() +{ + angleArc(QSizeF(1,1)); + angleArc(QSizeF(2.7,0.92)); +} + +void tst_QuickPath::catmullRomCurve(QSizeF scale, const QVector<QPointF> &points) { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("curve.qml")); QQuickPath *obj = qobject_cast<QQuickPath*>(c.create()); QVERIFY(obj != nullptr); + if (scale != QSizeF(1,1)) + obj->setProperty("scale", scale); QCOMPARE(obj->startX(), 0.); QCOMPARE(obj->startY(), 0.); @@ -148,22 +189,36 @@ void tst_QuickPath::catmullromCurve() QPainterPath path = obj->path(); QVERIFY(path != QPainterPath()); - QPointF pos = obj->pointAt(0); - QCOMPARE(pos, QPointF(0,0)); - pos = obj->pointAt(.25); - QCOMPARE(pos.toPoint(), QPoint(63,26)); //fuzzy compare - pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(51,105)); //fuzzy compare - pos = obj->pointAt(1); - QCOMPARE(pos.toPoint(), QPoint(100,150)); + QPointF pos = path.pointAtPercent(0); + QCOMPARE(pos, points.at(0)); + pos = path.pointAtPercent(.25); + compare(pos, __LINE__, points.at(1)); + pos = path.pointAtPercent(.75); + compare(pos, __LINE__, points.at(2)); + pos = path.pointAtPercent(1); + compare(pos, __LINE__, points.at(3)); } -void tst_QuickPath::closedCatmullromCurve() +void tst_QuickPath::catmullRomCurve() +{ + catmullRomCurve(QSizeF(1,1), { QPointF(0,0), + QPointF(62.917022919131, 26.175485291549), + QPointF(51.194527196674 , 105.27985623074), + QPointF(100, 150) }); + catmullRomCurve(QSizeF(2,5.3), { QPointF(0,0), + QPointF(150.80562419914, 170.34065984615), + QPointF(109.08400252853 , 588.35165918579), + QPointF(200, 795) }); +} + +void tst_QuickPath::closedCatmullRomCurve(QSizeF scale, const QVector<QPointF> &points) { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("closedcurve.qml")); QQuickPath *obj = qobject_cast<QQuickPath*>(c.create()); QVERIFY(obj != nullptr); + if (scale != QSizeF(1,1)) + obj->setProperty("scale", scale); QCOMPARE(obj->startX(), 50.); QCOMPARE(obj->startY(), 50.); @@ -181,22 +236,36 @@ void tst_QuickPath::closedCatmullromCurve() QPainterPath path = obj->path(); QVERIFY(path != QPainterPath()); - QPointF pos = obj->pointAt(0); - QCOMPARE(pos, QPointF(50,50)); - pos = obj->pointAt(.1); - QCOMPARE(pos.toPoint(), QPoint(67,56)); //fuzzy compare - pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(44,116)); //fuzzy compare - pos = obj->pointAt(1); - QCOMPARE(pos, QPointF(50,50)); + QPointF pos = path.pointAtPercent(0); + QCOMPARE(pos, points.at(0)); + pos = path.pointAtPercent(.1); + compare(pos, __LINE__, points.at(1)); + pos = path.pointAtPercent(.75); + compare(pos, __LINE__, points.at(2)); + pos = path.pointAtPercent(1); + compare(pos, __LINE__, points.at(3)); } -void tst_QuickPath::svg() +void tst_QuickPath::closedCatmullRomCurve() +{ + closedCatmullRomCurve(QSizeF(1,1), { QPointF(50,50), + QPointF(66.776225481812, 55.617435304145), + QPointF(44.10269379731 , 116.33512508175), + QPointF(50, 50) }); + closedCatmullRomCurve(QSizeF(2,3), { QPointF(100,150), + QPointF(136.49725836178, 170.25466686363), + QPointF(87.713232151943 , 328.29232737977), + QPointF(100, 150) }); +} + +void tst_QuickPath::svg(QSizeF scale) { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("svg.qml")); QQuickPath *obj = qobject_cast<QQuickPath*>(c.create()); QVERIFY(obj != nullptr); + if (scale != QSizeF(1,1)) + obj->setProperty("scale", scale); QCOMPARE(obj->startX(), 0.); QCOMPARE(obj->startY(), 0.); @@ -212,16 +281,22 @@ void tst_QuickPath::svg() QVERIFY(path != QPainterPath()); QPointF pos = obj->pointAt(0); - QCOMPARE(pos, QPointF(200,300)); + QCOMPARE(pos, QPointF(200 * scale.width(),300 * scale.height())); pos = obj->pointAt(.25); - QCOMPARE(pos.toPoint(), QPoint(400,175)); //fuzzy compare + QCOMPARE(pos.toPoint(), QPoint(400 * scale.width(),175 * scale.height())); //fuzzy compare pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(800,425)); //fuzzy compare + QCOMPARE(pos.toPoint(), QPoint(800 * scale.width(),425 * scale.height())); //fuzzy compare pos = obj->pointAt(1); - QCOMPARE(pos, QPointF(1000,300)); + QCOMPARE(pos, QPointF(1000 * scale.width(),300 * scale.height())); } -void tst_QuickPath::line() +void tst_QuickPath::svg() +{ + svg(QSizeF(1,1)); + svg(QSizeF(5,3)); +} + +void tst_QuickPath::line(QSizeF scale) { QQmlEngine engine; QQmlComponent c1(&engine); @@ -234,6 +309,8 @@ void tst_QuickPath::line() QScopedPointer<QObject> o1(c1.create()); QQuickPath *path1 = qobject_cast<QQuickPath *>(o1.data()); QVERIFY(path1); + if (scale != QSizeF(1,1)) + path1->setProperty("scale", scale); QQmlComponent c2(&engine); c2.setData( @@ -246,6 +323,8 @@ void tst_QuickPath::line() QScopedPointer<QObject> o2(c2.create()); QQuickPath *path2 = qobject_cast<QQuickPath *>(o2.data()); QVERIFY(path2); + if (scale != QSizeF(1,1)) + path2->setProperty("scale", scale); for (int i = 0; i < 167; ++i) { qreal t = i / 167.0; @@ -258,6 +337,11 @@ void tst_QuickPath::line() } } +void tst_QuickPath::line() +{ + line(QSizeF(1,1)); + line(QSizeF(7.23,7.23)); +} QTEST_MAIN(tst_QuickPath) diff --git a/tests/auto/quick/qquickshape/qquickshape.pro b/tests/auto/quick/qquickshape/qquickshape.pro index a0e5c002e0..3cf79426c5 100644 --- a/tests/auto/quick/qquickshape/qquickshape.pro +++ b/tests/auto/quick/qquickshape/qquickshape.pro @@ -8,6 +8,7 @@ include (../../shared/util.pri) include (../shared/util.pri) TESTDATA = data/* +DISTFILES = data/* QT += core-private gui-private qml-private quick-private testlib quickshapes-private qtHaveModule(widgets): QT += widgets diff --git a/tests/auto/quick/qquickshape/tst_qquickshape.cpp b/tests/auto/quick/qquickshape/tst_qquickshape.cpp index 61fb260612..eb98f849f8 100644 --- a/tests/auto/quick/qquickshape/tst_qquickshape.cpp +++ b/tests/auto/quick/qquickshape/tst_qquickshape.cpp @@ -66,7 +66,7 @@ tst_QQuickShape::tst_QQuickShape() const char *uri = "tst_qquickpathitem"; qmlRegisterType<QQuickShape>(uri, 1, 0, "Shape"); - qmlRegisterType<QQuickShapePath>(uri, 1, 0, "ShapePath"); + qmlRegisterType<QQuickShapePath, 14>(uri, 1, 0, "ShapePath"); qmlRegisterUncreatableType<QQuickShapeGradient>(uri, 1, 0, "ShapeGradient", QQuickShapeGradient::tr("ShapeGradient is an abstract base class")); qmlRegisterType<QQuickShapeLinearGradient>(uri, 1, 0, "LinearGradient"); qmlRegisterType<QQuickShapeRadialGradient>(uri, 1, 0, "RadialGradient"); diff --git a/tests/manual/scalablepath/ShapeTestScale.qml b/tests/manual/scalablepath/ShapeTestScale.qml new file mode 100644 index 0000000000..097ecf3a93 --- /dev/null +++ b/tests/manual/scalablepath/ShapeTestScale.qml @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.14 +import QtQuick.Shapes 1.14 + +Rectangle { + id: i + width: parent.width * 0.5 + height: parent.height * 0.5 + anchors.centerIn: parent + color: "transparent" + border.color: "red" + + Shape { + id: pathLineMove + vendorExtensionsEnabled: false + anchors { + left: parent.left + top: parent.top + bottom: parent.verticalCenter + right: parent.horizontalCenter + } + + visible: true + + ShapePath { + id: c_sp1 + strokeWidth: -1 + fillColor: Qt.rgba(1,0,1,1.0) + scale: Qt.size(pathLineMove.width - 1, pathLineMove.height - 1) + + startX: 0.5; + startY: 1 + + PathLine { + x: 0 + y: 1 + } + PathLine { + x: 0.5 + y: 0 + } + PathLine { + x: 1 + y: 1 + } + PathLine { + x: c_sp1.startX + y: c_sp1.startY + } + + // Inner shape + PathMove { + x: 0.5 + y: 0.25 + } + PathLine { + x: 0.8 + y: 0.8 + } + PathLine { + x: 0.2 + y: 0.8 + } + PathLine { + x: 0.5 + y: 0.25 + } + } + } + Shape { + id: pathCurveArcQuad + vendorExtensionsEnabled: false + anchors { + left: parent.horizontalCenter + top: parent.top + bottom: parent.verticalCenter + right: parent.right + } + + visible: true + + ShapePath { + strokeWidth: 1 + fillColor: "transparent" + strokeColor: "goldenrod" + scale: Qt.size(pathCurveArcQuad.width - 1, pathCurveArcQuad.height - 1) + + startX: 0/400; startY: 100/400 + + PathCurve { x: 75/400; y: 75/400 } + PathCurve { x: 200/400; y: 150/400 } + PathCurve { x: 325/400; y: 25/400 } + PathCurve { x: 400/400; y: 100/400 } + PathMove { x: 0.5; y: 0 } + PathArc { + x: 0; y: 100 / 200 + radiusX: 100 / 200; radiusY: 100 / 200 + useLargeArc: true + } + PathMove { x: 0; y: 0.5 } + PathQuad { x: 1; y: 0.5; controlX: 0.5; controlY: 1 } + } + } + + + Shape { + id: pathCubicAngleArc + vendorExtensionsEnabled: false + anchors { + left: parent.left + top: parent.verticalCenter + bottom: parent.bottom + right: parent.horizontalCenter + } + + visible: true + + ShapePath { + strokeWidth: 1 + fillColor: "transparent" + strokeColor: "deepskyblue" + scale: Qt.size(pathCubicAngleArc.width - 1, pathCubicAngleArc.height - 1) + + startX: 20/200; startY: 0 + + PathCubic { + x: 180/200; y: 0 + control1X: -10/200; control1Y: 90/200 + control2X: 210/200; control2Y: 90/200 + } + + PathAngleArc { + centerX: 0.5; centerY: 0.5 + radiusX: 0.45; radiusY: 0.45 + startAngle: -180 + sweepAngle: 234 + moveToStart: true + } + } + } + Shape { + id: pathSvg + vendorExtensionsEnabled: false + anchors { + left: parent.horizontalCenter + top: parent.verticalCenter + bottom: parent.bottom + right: parent.right + } + + visible: true + + ShapePath { + strokeWidth: 5 + fillColor: "transparent" + strokeColor: "coral" + scale: Qt.size((pathSvg.width - 1), (pathSvg.height - 1)) + startX: .25; startY: .25 + PathSvg { path: "L .75 .25 L .5 .75 z" } + } + + ShapePath { + strokeWidth: 1 + fillColor: "transparent" + strokeColor: "black" + scale: Qt.size((pathSvg.width - 1) / 200, (pathSvg.height - 1) / 200) + startX: 50; startY: 50 + PathSvg { path: "L 150 50 L 100 150 z" } + } + + ShapePath { + strokeColor: "red" + strokeWidth: 4 + fillColor: "transparent" + scale: Qt.size((pathSvg.width - 1) / 500, (pathSvg.height - 1) / 500) + PathSvg { + path: "m 325.03711,0.5 + c -26.61408,6.4494547 -49.95197,2.1018066 -76.21132,1.0771669 + -22.26577,7.6817151 -47.96405,9.3627181 -65.67832,25.8497861 + -15.74718,12.80008 -41.1564,19.605644 -45.74903,40.600391 + -12.46933,17.76181 -25.36105,35.720146 -29.20117,57.999996 + -18.709864,3.10961 -16.347355,30.83801 -22.385143,46.675 + -6.848711,11.2677 11.07278,24.69174 -8.514666,27.97383 + -10.266901,5.61543 -12.859313,28.96588 -13.732346,5.78143 + 0.940083,-11.53398 -13.486195,-38.30626 -16.81701,-34.20231 + 14.608079,7.8234 21.299281,50.52979 11.380052,48.14418 + -3.406456,-15.12428 -26.181106,-38.29457 -31.849471,-35.62945 + 16.851912,6.41472 35.569884,31.75215 28.172486,47.93115 + -7.906485,-15.42757 -37.758959,-35.53783 -44.275447,-31.28685 + 18.975831,1.7428 37.986009,20.68109 42.87115,37.14427 C + 42.279655,225.774 9.879724,213.57795 4.7080253,219.04989 + 20.780803,212.57418 55.055919,239.88547 49.602579,241.25683 + 38.186641,230.40078 6.6930104,222.77983 2.5752529,228.41774 c + 13.6045481,-8.33065 49.4437901,14.89041 43.5525671,14.2358 + -9.759981,-7.96123 -43.5842921,7.36937 -17.554974,-1.20248 + 9.464499,-3.73452 40.555672,12.80659 16.398749,5.14121 + -9.1987,-7.28225 -39.0013156,3.37352 -14.121965,-2.12828 + 13.244874,-0.0206 35.758428,14.62706 10.562447,6.42228 + -10.780465,-8.4873 -47.8282254,11.10651 -21.027329,-0.003 + 11.640859,-4.82877 52.615601,10.74471 24.234828,8.2659 + -10.695834,-7.03902 -42.9384162,8.93905 -34.227854,5.58373 + 9.077539,-8.56443 49.068801,-5.28097 43.06838,0.45546 + -10.900893,-0.7118 -27.449619,17.27258 -10.00187,3.46526 + 15.705191,-9.18198 18.344231,9.31645 1.10807,8.73907 + -9.908444,1.77856 -21.108189,20.66671 -7.974821,4.92019 + 15.750746,-14.10374 34.01348,2.07267 9.796961,8.69337 + -8.17128,5.49929 -12.642664,19.13654 -3.994573,4.19708 + 9.044753,-8.7077 23.850399,-13.64552 21.404959,4.02329 + 12.509737,17.12562 51.158782,11.0442 45.106112,43.34009 + -0.65006,10.05318 -3.79228,13.95389 1.62128,14.30064 + -4.30913,8.82737 -14.652714,37.9591 2.92144,17.46024 + 7.37972,-3.68333 -7.62399,16.24161 -7.98007,23.83761 + -9.336865,18.77418 19.74873,-18.55943 6.62229,5.46195 + 5.46464,-3.7389 36.23886,-19.41901 14.78167,0.58987 + -8.59505,4.55644 29.29441,-2.99423 8.95489,6.47134 -9.22562,5.54437 + -24.09765,26.79976 -11.73274,22.20385 -0.81685,5.4936 + -1.58629,21.47626 2.34158,9.14886 1.61237,14.67029 + -2.38384,25.22225 12.26908,15.1741 -4.40761,8.01039 + -8.23679,36.91214 5.12235,17.92578 1.53454,2.99551 9.37569,3.1726 + 7.15304,14.93579 3.51234,-11.31873 18.4607,-29.83809 + 12.36869,-6.48005 -0.22629,16.26174 5.44303,-7.24791 + 6.56926,10.49819 12.45412,28.9931 3.40908,-41.89883 + 17.52051,-9.19238 3.23093,11.1924 6.53006,29.46941 7.55984,5.1249 + 15.37236,-19.52583 4.09776,20.07416 12.64063,1.48215 + 18.11247,-24.55068 -8.92586,38.39355 6.73828,6.62225 + 4.55353,-6.91007 15.35028,-38.88977 12.55806,-13.78666 + 1.05309,27.02664 11.54743,-24.40259 12.40657,6.86306 + -1.72561,13.28253 11.85393,-24.15909 13.85568,-1.38002 + 3.12455,8.33539 8.76536,26.46432 8.73882,5.09231 3.57025,-10.37352 + -16.025,-37.75672 0.20707,-22.5788 -1.2458,-14.17213 + -2.38918,-16.90145 10.85489,-6.71468 -16.57629,-17.22152 + 0.19706,-26.08949 5.7751,-19.14889 -14.91681,-16.1674 + 19.74174,7.19334 2.31875,-9.86869 -4.32508,-15.23278 + 27.25228,29.12341 20.27514,18.81172 -11.97527,-18.92603 + -17.96305,-45.80333 11.70099,-51.52566 17.19069,-9.57351 + 31.17452,21.93154 38.50541,1.56304 16.26048,-4.6633 + 22.3749,38.26516 24.86349,9.11316 5.94153,-9.9731 30.14313,6.97379 + 36.34294,4.75012 7.07435,18.27732 8.06778,14.78971 11.04264,3.86016 + 2.73754,-15.85945 28.7269,10.06391 28.09146,25.96561 3.00672,2.4754 + 6.55025,-22.10264 11.23552,-14.43872 2.84155,-11.4823 + -3.28976,-27.88574 4.24895,-25.5189 -0.61494,-11.53957 + 22.83611,0.11011 10.64648,-15.28756 -6.5587,-21.38598 + 9.32959,-3.0159 13.5107,-4.69375 -1.38592,-16.74533 + -8.66673,-31.83316 -1.90087,-41.0875 2.39623,-15.14303 + -12.50533,-44.45478 -4.70573,-48.49375 15.08472,3.42779 + -20.39159,-42.17451 -1.69776,-40.85728 24.07272,21.63552 + -3.65989,-30.10299 2.27233,-33.17152 16.90643,17.53071 + -12.7383,-38.42821 6.79531,-21.57013 -4.50946,-21.08135 + -2.53357,-37.43561 -15.5535,-55.59527 -11.0035,-12.40086 + -1.87775,-7.12745 1.34831,-8.11755 C 468.27562,118.9774 + 451.40746,102.656 430.98897,92.119168 439.06192,78.203836 + 455.88012,60.123881 457.38638,40.337815 463.2373,23.183067 + 450.82861,4.7342783 435.04883,22.626367 409.5188,28.206712 + 386.3569,24.131269 365.63904,8.0954152 352.788,2.8857182 + 338.88892,0.40735091 325.03711,0.5 Z m -219.0625,357.04297 + -0.97656,0.88476 z" + } + } + } +} diff --git a/tests/manual/scalablepath/main.cpp b/tests/manual/scalablepath/main.cpp new file mode 100644 index 0000000000..d35c590020 --- /dev/null +++ b/tests/manual/scalablepath/main.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/tests/manual/scalablepath/main.qml b/tests/manual/scalablepath/main.qml new file mode 100644 index 0000000000..e549a753d7 --- /dev/null +++ b/tests/manual/scalablepath/main.qml @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.14 +import QtQuick.Window 2.14 + +Window { + visible: true + width: 512 + height: 512 + color: "black" + + ShapeTestScale { + anchors.centerIn: parent + + } +} diff --git a/tests/manual/scalablepath/qml.qrc b/tests/manual/scalablepath/qml.qrc new file mode 100644 index 0000000000..a7a14beed4 --- /dev/null +++ b/tests/manual/scalablepath/qml.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>ShapeTestScale.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/scalablepath/scalablepath.pro b/tests/manual/scalablepath/scalablepath.pro new file mode 100644 index 0000000000..b95ce1de44 --- /dev/null +++ b/tests/manual/scalablepath/scalablepath.pro @@ -0,0 +1,5 @@ +TEMPLATE = app +QT += quick qml +SOURCES += main.cpp +RESOURCES += qml.qrc +CONFIG += c++11 |