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 test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31
32#include <qpolygon.h>
33#include <qpainterpath.h>
34#include <math.h>
35
36#include <qpainter.h>
37
38class tst_QPolygon : public QObject
39{
40 Q_OBJECT
41
42public:
43 tst_QPolygon();
44
45private slots:
46 void boundingRect_data();
47 void boundingRect();
48 void boundingRectF_data();
49 void boundingRectF();
50 void makeEllipse();
51 void swap();
52 void intersections_data();
53 void intersections();
54};
55
56tst_QPolygon::tst_QPolygon()
57{
58}
59
60void tst_QPolygon::boundingRect_data()
61{
62 QTest::addColumn<QPolygon>(name: "poly");
63 QTest::addColumn<QRect>(name: "brect");
64
65#define ROW(args, rect) \
66 do { \
67 QPolygon poly; \
68 poly.setPoints args; \
69 QTest::newRow(#args) << poly << QRect rect; \
70 } while (0)
71
72 QTest::newRow(dataTag: "empty") << QPolygon() << QRect(0, 0, 0, 0);
73 ROW((1, 0,1), ( 0, 1, 1, 1));
74 ROW((2, 0,1, 1,0), ( 0, 0, 2, 2));
75 ROW((3, -1,1, -1,-1, 1,0), (-1,-1, 3, 3));
76#undef ROW
77}
78
79void tst_QPolygon::boundingRect()
80{
81 QFETCH(QPolygon, poly);
82 QFETCH(QRect, brect);
83
84 QCOMPARE(poly.boundingRect(), brect);
85}
86
87namespace {
88struct MyPolygonF : QPolygonF
89{
90 // QPolygonF doesn't have setPoints...
91 void setPoints(int nPoints, int firstx, int firsty, ...) {
92 va_list ap;
93 reserve(asize: nPoints);
94 *this << QPointF(firstx, firsty);
95 va_start(ap, firsty);
96 while (--nPoints) {
97 const int x = va_arg(ap, int);
98 const int y = va_arg(ap, int);
99 *this << QPointF(x, y);
100 }
101 va_end(ap);
102 }
103};
104}
105
106void tst_QPolygon::boundingRectF_data()
107{
108 QTest::addColumn<QPolygonF>(name: "poly");
109 QTest::addColumn<QRectF>(name: "brect");
110
111#define ROW(args, rect) \
112 do { \
113 MyPolygonF poly; \
114 poly.setPoints args; \
115 QTest::newRow(#args) << QPolygonF(poly) << QRectF rect; \
116 } while (0)
117
118 QTest::newRow(dataTag: "empty") << QPolygonF() << QRectF(0, 0, 0, 0);
119 ROW((1, 0,1), ( 0, 1, 0, 0));
120 ROW((2, 0,1, 1,0), ( 0, 0, 1, 1));
121 ROW((3, -1,1, -1,-1, 1,0), (-1,-1, 2, 2));
122#undef ROW
123}
124
125void tst_QPolygon::boundingRectF()
126{
127 QFETCH(QPolygonF, poly);
128 QFETCH(QRectF, brect);
129
130 QCOMPARE(poly.boundingRect(), brect);
131}
132
133void tst_QPolygon::makeEllipse()
134{
135 // create an ellipse with R1 = R2 = R, i.e. a circle
136 QPolygon pa;
137 const int R = 50; // radius
138 QPainterPath path;
139 path.addEllipse(x: 0, y: 0, w: 2*R, h: 2*R);
140 pa = path.toSubpathPolygons().at(i: 0).toPolygon();
141
142 int i;
143 // make sure that all points are R+-1 away from the center
144 bool err = false;
145 for (i = 1; i < pa.size(); i++) {
146 QPoint p = pa.at(i);
147 double r = sqrt(x: pow(x: double(p.x() - R), y: 2.0) + pow(x: double(p.y() - R), y: 2.0));
148 // ### too strict ? at least from visual inspection it looks
149 // quite odd around the main axes. 2.0 passes easily.
150 err |= (qAbs(t: r - double(R)) > 2.0);
151 }
152 QVERIFY( !err );
153}
154
155void tst_QPolygon::swap()
156{
157 QPolygon p1(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10));
158 QPolygon p2(QVector<QPoint>() << QPoint(0,0) << QPoint( 0,10) << QPoint( 10,10) << QPoint(10,0));
159 p1.swap(other&: p2);
160 QCOMPARE(p1.count(),4);
161 QCOMPARE(p2.count(),3);
162}
163
164void tst_QPolygon::intersections_data()
165{
166 QTest::addColumn<QPolygon>(name: "poly1");
167 QTest::addColumn<QPolygon>(name: "poly2");
168 QTest::addColumn<bool>(name: "result");
169
170 QTest::newRow(dataTag: "empty intersects nothing")
171 << QPolygon()
172 << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
173 << false;
174 QTest::newRow(dataTag: "identical triangles")
175 << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
176 << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
177 << true;
178 QTest::newRow(dataTag: "not intersecting")
179 << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
180 << QPolygon(QVector<QPoint>() << QPoint(0,20) << QPoint(10,12) << QPoint(-10,12))
181 << false;
182 QTest::newRow(dataTag: "clean intersection of squares")
183 << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(0,10) << QPoint(10,10) << QPoint(10,0))
184 << QPolygon(QVector<QPoint>() << QPoint(5,5) << QPoint(5,15) << QPoint(15,15) << QPoint(15,5))
185 << true;
186 QTest::newRow(dataTag: "clean contains of squares")
187 << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(0,10) << QPoint(10,10) << QPoint(10,0))
188 << QPolygon(QVector<QPoint>() << QPoint(5,5) << QPoint(5,8) << QPoint(8,8) << QPoint(8,5))
189 << true;
190}
191
192void tst_QPolygon::intersections()
193{
194 QFETCH(QPolygon, poly1);
195 QFETCH(QPolygon, poly2);
196 QFETCH(bool, result);
197
198 QCOMPARE(poly2.intersects(poly1), poly1.intersects(poly2));
199 QCOMPARE(poly2.intersected(poly1).isEmpty(), poly1.intersected(poly2).isEmpty());
200 QCOMPARE(!poly1.intersected(poly2).isEmpty(), poly1.intersects(poly2));
201 QCOMPARE(poly1.intersects(poly2), result);
202}
203
204QTEST_APPLESS_MAIN(tst_QPolygon)
205#include "tst_qpolygon.moc"
206

source code of qtbase/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp