blob: c89ce730a87cc35d6244bf083ad38de2c130f68e [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 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 <QtTest/QtTest>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuick/private/qquickpath_p.h>
#include "../../shared/util.h"
class tst_QuickPath : public QQmlDataTest
{
Q_OBJECT
public:
tst_QuickPath() {}
private slots:
void arc();
void angleArc();
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);
};
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.);
QQmlListReference list(obj, "pathElements");
QCOMPARE(list.count(), 1);
QQuickPathArc* arc = qobject_cast<QQuickPathArc*>(list.at(0));
QVERIFY(arc != nullptr);
QCOMPARE(arc->x(), 100.);
QCOMPARE(arc->y(), 100.);
QCOMPARE(arc->radiusX(), 100.);
QCOMPARE(arc->radiusY(), 100.);
QCOMPARE(arc->useLargeArc(), false);
QCOMPARE(arc->direction(), QQuickPathArc::Clockwise);
QPainterPath path = obj->path();
QVERIFY(path != QPainterPath());
QPointF pos = obj->pointAtPercent(0);
QCOMPARE(pos, QPointF(0,0));
pos = obj->pointAtPercent(.25);
compare(pos, scale, __LINE__, 38.9244897744, 7.85853964341);
pos = obj->pointAtPercent(.75);
compare(pos, scale, __LINE__, 92.141460356592, 61.07551022559);
pos = obj->pointAtPercent(1);
QCOMPARE(pos, QPointF(100 * scale.width(), 100 * scale.height()));
}
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);
QQuickPathAngleArc* arc = qobject_cast<QQuickPathAngleArc*>(list.at(0));
QVERIFY(arc != nullptr);
QCOMPARE(arc->centerX(), 100.);
QCOMPARE(arc->centerY(), 100.);
QCOMPARE(arc->radiusX(), 50.);
QCOMPARE(arc->radiusY(), 50.);
QCOMPARE(arc->startAngle(), 45.);
QCOMPARE(arc->sweepAngle(), 90.);
QCOMPARE(arc->moveToStart(), true);
QPainterPath path = obj->path();
QVERIFY(path != QPainterPath());
QPointF pos = obj->pointAtPercent(0);
compare(pos, scale, __LINE__, 135.35533905867, 135.35533905867);
pos = obj->pointAtPercent(.25);
compare(pos, scale, __LINE__, 119.46222180396, 146.07068621369);
pos = obj->pointAtPercent(.75);
compare(pos, scale, __LINE__, 80.537778196007, 146.07068621366);
pos = obj->pointAtPercent(1);
compare(pos, scale, __LINE__, 64.644660941173, 135.35533905867);
// if moveToStart is false, we should have a line starting from startX/Y
arc->setMoveToStart(false);
pos = obj->pointAtPercent(0);
QCOMPARE(pos, QPointF(0,0));
}
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.);
QQmlListReference list(obj, "pathElements");
QCOMPARE(list.count(), 3);
QQuickPathCatmullRomCurve* curve = qobject_cast<QQuickPathCatmullRomCurve*>(list.at(0));
QVERIFY(curve != nullptr);
QCOMPARE(curve->x(), 100.);
QCOMPARE(curve->y(), 50.);
curve = qobject_cast<QQuickPathCatmullRomCurve*>(list.at(2));
QVERIFY(curve != nullptr);
QCOMPARE(curve->x(), 100.);
QCOMPARE(curve->y(), 150.);
QPainterPath path = obj->path();
QVERIFY(path != QPainterPath());
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::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.);
QQmlListReference list(obj, "pathElements");
QCOMPARE(list.count(), 3);
QQuickPathCatmullRomCurve* curve = qobject_cast<QQuickPathCatmullRomCurve*>(list.at(2));
QVERIFY(curve != nullptr);
QCOMPARE(curve->x(), 50.);
QCOMPARE(curve->y(), 50.);
QVERIFY(obj->isClosed());
QPainterPath path = obj->path();
QVERIFY(path != QPainterPath());
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::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.);
QQmlListReference list(obj, "pathElements");
QCOMPARE(list.count(), 1);
QQuickPathSvg* svg = qobject_cast<QQuickPathSvg*>(list.at(0));
QVERIFY(svg != nullptr);
QCOMPARE(svg->path(), QLatin1String("M200,300 Q400,50 600,300 T1000,300"));
QPainterPath path = obj->path();
QVERIFY(path != QPainterPath());
QPointF pos = obj->pointAtPercent(0);
QCOMPARE(pos, QPointF(200 * scale.width(),300 * scale.height()));
pos = obj->pointAtPercent(.25);
QCOMPARE(pos.toPoint(), QPoint(400 * scale.width(),175 * scale.height())); //fuzzy compare
pos = obj->pointAtPercent(.75);
QCOMPARE(pos.toPoint(), QPoint(800 * scale.width(),425 * scale.height())); //fuzzy compare
pos = obj->pointAtPercent(1);
QCOMPARE(pos, QPointF(1000 * scale.width(),300 * scale.height()));
}
void tst_QuickPath::svg()
{
svg(QSizeF(1,1));
svg(QSizeF(5,3));
}
void tst_QuickPath::line(QSizeF scale)
{
QQmlEngine engine;
QQmlComponent c1(&engine);
c1.setData(
"import QtQuick 2.0\n"
"Path {\n"
"startX: 0; startY: 0\n"
"PathLine { x: 100; y: 100 }\n"
"}", QUrl());
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(
"import QtQuick 2.0\n"
"Path {\n"
"startX: 0; startY: 0\n"
"PathLine { x: 50; y: 50 }\n"
"PathLine { x: 100; y: 100 }\n"
"}", QUrl());
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;
QPointF p1 = path1->pointAtPercent(t);
QCOMPARE(p1.x(), p1.y());
QPointF p2 = path2->pointAtPercent(t);
QCOMPARE(p1.toPoint(), p2.toPoint());
}
}
void tst_QuickPath::line()
{
line(QSizeF(1,1));
line(QSizeF(7.23,7.23));
}
QTEST_MAIN(tst_QuickPath)
#include "tst_qquickpath.moc"