| 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 | #include "private/qpathclipper_p.h" | 
| 29 | #include "paths.h" | 
| 30 | #include "pathcompare.h" | 
| 31 |  | 
| 32 | #include <QtTest/QtTest> | 
| 33 |  | 
| 34 | #include <qpainterpath.h> | 
| 35 | #include <qpolygon.h> | 
| 36 | #include <qdebug.h> | 
| 37 | #include <qpainter.h> | 
| 38 | #include <qrandom.h> | 
| 39 |  | 
| 40 | #include <math.h> | 
| 41 |  | 
| 42 | class tst_QPathClipper : public QObject | 
| 43 | { | 
| 44 |     Q_OBJECT | 
| 45 |  | 
| 46 | public: | 
| 47 |     tst_QPathClipper(); | 
| 48 |     virtual ~tst_QPathClipper(); | 
| 49 |  | 
| 50 | private: | 
| 51 |     void clipTest(int subjectIndex, int clipIndex, QPathClipper::Operation op); | 
| 52 |  | 
| 53 |     QList<QPainterPath> paths; | 
| 54 |  | 
| 55 | public slots: | 
| 56 |     void initTestCase(); | 
| 57 |  | 
| 58 | private slots: | 
| 59 |     void testWingedEdge(); | 
| 60 |  | 
| 61 |     void testComparePaths(); | 
| 62 |  | 
| 63 |     void clip_data(); | 
| 64 |     void clip(); | 
| 65 |  | 
| 66 |     void clip2(); | 
| 67 |     void clip3(); | 
| 68 |  | 
| 69 |     void testIntersections(); | 
| 70 |     void testIntersections2(); | 
| 71 |     void testIntersections3(); | 
| 72 |     void testIntersections4(); | 
| 73 |     void testIntersections5(); | 
| 74 |     void testIntersections6(); | 
| 75 |     void testIntersections7(); | 
| 76 |     void testIntersections8(); | 
| 77 |     void testIntersections9(); | 
| 78 |  | 
| 79 |     void zeroDerivativeCurves(); | 
| 80 |  | 
| 81 |     void task204301_data(); | 
| 82 |     void task204301(); | 
| 83 |  | 
| 84 |     void task209056(); | 
| 85 |     void task251909(); | 
| 86 |  | 
| 87 |     void qtbug3778(); | 
| 88 |     void qtbug60024(); | 
| 89 | }; | 
| 90 |  | 
| 91 | Q_DECLARE_METATYPE(QPainterPath) | 
| 92 | Q_DECLARE_METATYPE(QPathClipper::Operation) | 
| 93 |  | 
| 94 | tst_QPathClipper::tst_QPathClipper() | 
| 95 | { | 
| 96 | } | 
| 97 |  | 
| 98 | tst_QPathClipper::~tst_QPathClipper() | 
| 99 | { | 
| 100 | } | 
| 101 |  | 
| 102 | void tst_QPathClipper::initTestCase() | 
| 103 | { | 
| 104 |     paths << Paths::rect(); | 
| 105 |     paths << Paths::heart(); | 
| 106 |     paths << Paths::body(); | 
| 107 |     paths << Paths::mailbox(); | 
| 108 |     paths << Paths::deer(); | 
| 109 |     paths << Paths::fire(); | 
| 110 |  | 
| 111 |     paths << Paths::random1(); | 
| 112 |     paths << Paths::random2(); | 
| 113 |  | 
| 114 |     paths << Paths::heart2(); | 
| 115 |     paths << Paths::rect2(); | 
| 116 |     paths << Paths::rect3(); | 
| 117 |     paths << Paths::rect4(); | 
| 118 |     paths << Paths::rect5(); | 
| 119 |     paths << Paths::rect6(); | 
| 120 |  | 
| 121 |     paths << Paths::frame1(); | 
| 122 |     paths << Paths::frame2(); | 
| 123 |     paths << Paths::frame3(); | 
| 124 |     paths << Paths::frame4(); | 
| 125 |  | 
| 126 |     paths << Paths::triangle1(); | 
| 127 |     paths << Paths::triangle2(); | 
| 128 |  | 
| 129 |     paths << Paths::node(); | 
| 130 |     paths << Paths::interRect(); | 
| 131 |  | 
| 132 |     paths << Paths::simpleCurve(); | 
| 133 |     paths << Paths::simpleCurve2(); | 
| 134 |     paths << Paths::simpleCurve3(); | 
| 135 |  | 
| 136 |     paths << Paths::bezier1(); | 
| 137 |     paths << Paths::bezier2(); | 
| 138 |     paths << Paths::bezier3(); | 
| 139 |     paths << Paths::bezier4(); | 
| 140 |  | 
| 141 |     paths << Paths::bezierFlower(); | 
| 142 |     paths << Paths::lips(); | 
| 143 |     paths << Paths::clover(); | 
| 144 |     paths << Paths::ellipses(); | 
| 145 |     paths << Paths::windingFill(); | 
| 146 |     paths << Paths::oddEvenFill(); | 
| 147 |     paths << Paths::squareWithHole(); | 
| 148 |     paths << Paths::circleWithHole(); | 
| 149 |     paths << Paths::bezierQuadrant(); | 
| 150 |  | 
| 151 |     // make sure all the bounding rects are centered at the origin | 
| 152 |     for (int i = 0; i < paths.size(); ++i) { | 
| 153 |         QRectF bounds = paths[i].boundingRect(); | 
| 154 |  | 
| 155 |         QTransform m(1, 0, | 
| 156 |                      0, 1, | 
| 157 |                      -bounds.center().x(), -bounds.center().y()); | 
| 158 |  | 
| 159 |         paths[i] = m.map(p: paths[i]); | 
| 160 |     } | 
| 161 | } | 
| 162 |  | 
| 163 | static QPainterPath samplePath1() | 
| 164 | { | 
| 165 |     QPainterPath path; | 
| 166 |     path.moveTo(p: QPointF(200, 246.64789)); | 
| 167 |     path.lineTo(p: QPointF(200, 206.64789)); | 
| 168 |     path.lineTo(p: QPointF(231.42858, 206.64789)); | 
| 169 |     path.lineTo(p: QPointF(231.42858, 246.64789)); | 
| 170 |     path.lineTo(p: QPointF(200, 246.64789)); | 
| 171 |     return path; | 
| 172 | } | 
| 173 |  | 
| 174 | static QPainterPath samplePath2() | 
| 175 | { | 
| 176 |     QPainterPath path; | 
| 177 |     path.moveTo(p: QPointF(200, 146.64789)); | 
| 178 |     path.lineTo(p: QPointF(200, 106.64789)); | 
| 179 |     path.lineTo(p: QPointF(231.42858, 106.64789)); | 
| 180 |     path.lineTo(p: QPointF(231.42858, 146.64789)); | 
| 181 |     path.lineTo(p: QPointF(200, 146.64789)); | 
| 182 |     return path; | 
| 183 | } | 
| 184 |  | 
| 185 | static QPainterPath samplePath3() | 
| 186 | { | 
| 187 |     QPainterPath path; | 
| 188 |     path.moveTo(p: QPointF(231.42858, 80.933609)); | 
| 189 |     path.lineTo(p: QPointF(200, 80.933609)); | 
| 190 |     path.lineTo(p: QPointF(200, 96.64788999999999)); | 
| 191 |     path.lineTo(p: QPointF(231.42858, 96.64788999999999)); | 
| 192 |     path.lineTo(p: QPointF(231.42858, 80.933609)); | 
| 193 |     return path; | 
| 194 | } | 
| 195 |  | 
| 196 | static QPainterPath samplePath4() | 
| 197 | { | 
| 198 |     QPainterPath path; | 
| 199 |     path.moveTo(p: QPointF(288.571434, 80.933609)); | 
| 200 |     path.lineTo(p: QPointF(431.42858, 80.933609)); | 
| 201 |     path.lineTo(p: QPointF(431.42858, 96.64788999999999)); | 
| 202 |     path.lineTo(p: QPointF(288.571434, 96.64788999999999)); | 
| 203 |     path.lineTo(p: QPointF(288.571434, 80.933609)); | 
| 204 |     return path; | 
| 205 | } | 
| 206 |  | 
| 207 | static QPainterPath samplePath5() | 
| 208 | { | 
| 209 |     QPainterPath path; | 
| 210 |     path.moveTo(p: QPointF(588.571434, 80.933609)); | 
| 211 |     path.lineTo(p: QPointF(682.85715, 80.933609)); | 
| 212 |     path.lineTo(p: QPointF(682.85715, 96.64788999999999)); | 
| 213 |     path.lineTo(p: QPointF(588.571434, 96.64788999999999)); | 
| 214 |     path.lineTo(p: QPointF(588.571434, 80.933609)); | 
| 215 |     return path; | 
| 216 | } | 
| 217 |  | 
| 218 | static QPainterPath samplePath6() | 
| 219 | { | 
| 220 |     QPainterPath path; | 
| 221 |     path.moveTo(p: QPointF(588.571434, 80.933609)); | 
| 222 |     path.lineTo(p: QPointF(200, 80.933609)); | 
| 223 |     path.lineTo(p: QPointF(200, 446.6479)); | 
| 224 |     path.lineTo(p: QPointF(682.85715, 446.6479)); | 
| 225 |     path.lineTo(p: QPointF(682.85715, 96.64788999999999)); | 
| 226 |     path.lineTo(p: QPointF(731.42858, 96.64788999999999)); | 
| 227 |     path.lineTo(p: QPointF(731.42858, 56.64788999999999)); | 
| 228 |     path.lineTo(p: QPointF(588.571434, 56.64788999999999)); | 
| 229 |     path.lineTo(p: QPointF(588.571434, 80.933609)); | 
| 230 |     return path; | 
| 231 | } | 
| 232 |  | 
| 233 | static QPainterPath samplePath7() | 
| 234 | { | 
| 235 |     QPainterPath path; | 
| 236 |     path.moveTo(p: QPointF(682.85715, 206.64789)); | 
| 237 |     path.lineTo(p: QPointF(682.85715, 246.64789)); | 
| 238 |     path.lineTo(p: QPointF(588.571434, 246.64789)); | 
| 239 |     path.lineTo(p: QPointF(588.571434, 206.64789)); | 
| 240 |     path.lineTo(p: QPointF(682.85715, 206.64789)); | 
| 241 |     return path; | 
| 242 | } | 
| 243 |  | 
| 244 | static QPainterPath samplePath8() | 
| 245 | { | 
| 246 |     QPainterPath path; | 
| 247 |     path.moveTo(p: QPointF(682.85715, 406.64789)); | 
| 248 |     path.lineTo(p: QPointF(682.85715, 446.64789)); | 
| 249 |     path.lineTo(p: QPointF(588.571434, 446.64789)); | 
| 250 |     path.lineTo(p: QPointF(588.571434, 406.64789)); | 
| 251 |     path.lineTo(p: QPointF(682.85715, 406.64789)); | 
| 252 |     return path; | 
| 253 | } | 
| 254 |  | 
| 255 | static QPainterPath samplePath9() | 
| 256 | { | 
| 257 |     QPainterPath path; | 
| 258 |     path.moveTo(p: QPointF(682.85715, 426.64789)); | 
| 259 |     path.lineTo(p: QPointF(682.85715, 446.6479)); | 
| 260 |     path.lineTo(p: QPointF(568.571434, 446.6479)); | 
| 261 |     path.lineTo(p: QPointF(568.571434, 426.64789)); | 
| 262 |     path.lineTo(p: QPointF(682.85715, 426.64789)); | 
| 263 |     return path; | 
| 264 | } | 
| 265 |  | 
| 266 | static QPainterPath samplePath10() | 
| 267 | { | 
| 268 |     QPainterPath path; | 
| 269 |     path.moveTo(p: QPointF(511.42858, 446.6479)); | 
| 270 |     path.lineTo(p: QPointF(368.571434, 446.6479)); | 
| 271 |     path.lineTo(p: QPointF(368.571434, 426.64789)); | 
| 272 |     path.lineTo(p: QPointF(511.42858, 426.64789)); | 
| 273 |     path.lineTo(p: QPointF(511.42858, 446.6479)); | 
| 274 |     return path; | 
| 275 | } | 
| 276 |  | 
| 277 | static QPainterPath samplePath13() | 
| 278 | { | 
| 279 |     QPainterPath path; | 
| 280 |     path.moveTo(p: QPointF(160, 200)); | 
| 281 |     path.lineTo(p: QPointF(100, 200)); | 
| 282 |     path.lineTo(p: QPointF(100, 130)); | 
| 283 |     path.lineTo(p: QPointF(160, 130)); | 
| 284 |     path.lineTo(p: QPointF(160, 200)); | 
| 285 |     return path; | 
| 286 | } | 
| 287 |  | 
| 288 | static QPainterPath samplePath14() | 
| 289 | { | 
| 290 |     QPainterPath path; | 
| 291 |  | 
| 292 |     path.moveTo(x: 160, y: 80); | 
| 293 |     path.lineTo(x: 160, y: 180); | 
| 294 |     path.lineTo(x: 100, y: 180); | 
| 295 |     path.lineTo(x: 100, y: 80); | 
| 296 |     path.lineTo(x: 160, y: 80); | 
| 297 |     path.moveTo(x: 160, y: 80); | 
| 298 |     path.lineTo(x: 160, y: 100); | 
| 299 |     path.lineTo(x: 120, y: 100); | 
| 300 |     path.lineTo(x: 120, y: 80); | 
| 301 |  | 
| 302 |     return path; | 
| 303 | } | 
| 304 |  | 
| 305 | void tst_QPathClipper::clip_data() | 
| 306 | { | 
| 307 |     //create the testtable instance and define the elements | 
| 308 |     QTest::addColumn<QPainterPath>(name: "subject" ); | 
| 309 |     QTest::addColumn<QPainterPath>(name: "clip" ); | 
| 310 |     QTest::addColumn<QPathClipper::Operation>(name: "op" ); | 
| 311 |     QTest::addColumn<QPainterPath>(name: "result" ); | 
| 312 |  | 
| 313 |     //next we fill it with data | 
| 314 |     QTest::newRow( dataTag: "simple1"  )  << Paths::frame3() | 
| 315 |                                 << Paths::frame4() | 
| 316 |                                 << QPathClipper::BoolAnd | 
| 317 |                                 << samplePath1(); | 
| 318 |  | 
| 319 |     QTest::newRow( dataTag: "simple2"  )  << Paths::frame3() | 
| 320 |                                 << Paths::frame4() * QTransform().translate(dx: 0, dy: -100) | 
| 321 |                                 << QPathClipper::BoolAnd | 
| 322 |                                 << samplePath2(); | 
| 323 |  | 
| 324 |     QTest::newRow( dataTag: "simple3"  )  << Paths::frame3() | 
| 325 |                                 << Paths::frame4() * QTransform().translate(dx: 0, dy: -150) | 
| 326 |                                 << QPathClipper::BoolAnd | 
| 327 |                                 << samplePath3(); | 
| 328 |  | 
| 329 |     QTest::newRow( dataTag: "simple4"  )  << Paths::frame3() | 
| 330 |                                 << Paths::frame4() * QTransform().translate(dx: 200, dy: -150) | 
| 331 |                                 << QPathClipper::BoolAnd | 
| 332 |                                 << samplePath4(); | 
| 333 |  | 
| 334 |     QTest::newRow( dataTag: "simple5"  )  << Paths::frame3() | 
| 335 |                                 << Paths::frame4() * QTransform().translate(dx: 500, dy: -150) | 
| 336 |                                 << QPathClipper::BoolAnd | 
| 337 |                                 << samplePath5(); | 
| 338 |  | 
| 339 |     QTest::newRow( dataTag: "simple6"  )  << Paths::frame3() | 
| 340 |                                 << Paths::frame4() * QTransform().translate(dx: 500, dy: -150) | 
| 341 |                                 << QPathClipper::BoolOr | 
| 342 |                                 << samplePath6(); | 
| 343 |  | 
| 344 |     QTest::newRow( dataTag: "simple7"  )  << Paths::frame3() | 
| 345 |                                 << Paths::frame4() * QTransform().translate(dx: 500, dy: 0) | 
| 346 |                                 << QPathClipper::BoolAnd | 
| 347 |                                 << samplePath7(); | 
| 348 |  | 
| 349 |     QTest::newRow( dataTag: "simple8"  )  << Paths::frame3() | 
| 350 |                                 << Paths::frame4() * QTransform().translate(dx: 500, dy: 200) | 
| 351 |                                 << QPathClipper::BoolAnd | 
| 352 |                                 << samplePath8(); | 
| 353 |  | 
| 354 |     QTest::newRow( dataTag: "simple9"  )  << Paths::frame3() | 
| 355 |                                 << Paths::frame4() * QTransform().translate(dx: 480, dy: 220) | 
| 356 |                                 << QPathClipper::BoolAnd | 
| 357 |                                 << samplePath9(); | 
| 358 |  | 
| 359 |     QTest::newRow( dataTag: "simple10"  )  << Paths::frame3() | 
| 360 |                                  << Paths::frame4() * QTransform().translate(dx: 280, dy: 220) | 
| 361 |                                  << QPathClipper::BoolAnd | 
| 362 |                                  << samplePath10(); | 
| 363 |  | 
| 364 |     QTest::newRow( dataTag: "simple_move_to1"  )  << Paths::rect4() | 
| 365 |                                        << Paths::rect2() * QTransform().translate(dx: -20, dy: 50) | 
| 366 |                                        << QPathClipper::BoolAnd | 
| 367 |                                        << samplePath13(); | 
| 368 |  | 
| 369 |     QTest::newRow( dataTag: "simple_move_to2"  )  << Paths::rect4() | 
| 370 |                                         << Paths::rect2() * QTransform().translate(dx: -20, dy: 0) | 
| 371 |                                         << QPathClipper::BoolAnd | 
| 372 |                                         << samplePath14(); | 
| 373 | } | 
| 374 |  | 
| 375 | // sanity check to make sure comparePaths declared above works | 
| 376 | void tst_QPathClipper::testComparePaths() | 
| 377 | { | 
| 378 |     QPainterPath a; | 
| 379 |     QPainterPath b; | 
| 380 |  | 
| 381 |     a.addRect(x: 0, y: 0, w: 10, h: 10); | 
| 382 |     b.addRect(x: 0, y: 0, w: 10.00001, h: 10.00001); | 
| 383 |  | 
| 384 |     QVERIFY(!QPathCompare::comparePaths(a, b)); | 
| 385 |  | 
| 386 |     b = QPainterPath(); | 
| 387 |     b.addRect(x: 0, y: 0, w: 10.00000000001, h: 10.00000000001); | 
| 388 |  | 
| 389 |     QVERIFY(QPathCompare::comparePaths(a, b)); | 
| 390 |  | 
| 391 |     b = QPainterPath(); | 
| 392 |     b.moveTo(x: 10, y: 0); | 
| 393 |     b.lineTo(x: 0, y: 0); | 
| 394 |     b.lineTo(x: 0, y: 10); | 
| 395 |     b.lineTo(x: 10, y: 10); | 
| 396 |  | 
| 397 |     QVERIFY(QPathCompare::comparePaths(a, b)); | 
| 398 |     b.lineTo(x: 10, y: 0); | 
| 399 |     QVERIFY(QPathCompare::comparePaths(a, b)); | 
| 400 |  | 
| 401 |     b = QPainterPath(); | 
| 402 |     b.moveTo(x: 10, y: 0); | 
| 403 |     b.lineTo(x: 0, y: 10); | 
| 404 |     b.lineTo(x: 0, y: 0); | 
| 405 |     b.lineTo(x: 10, y: 10); | 
| 406 |  | 
| 407 |     QVERIFY(!QPathCompare::comparePaths(a, b)); | 
| 408 | } | 
| 409 |  | 
| 410 | void tst_QPathClipper::clip() | 
| 411 | { | 
| 412 |     if (sizeof(double) != sizeof(qreal)) { | 
| 413 |         QSKIP("This test only works for qreal=double, otherwise ends in rounding errors" ); | 
| 414 |     } | 
| 415 |     QFETCH( QPainterPath, subject ); | 
| 416 |     QFETCH( QPainterPath, clip ); | 
| 417 |     QFETCH( QPathClipper::Operation, op ); | 
| 418 |     QFETCH( QPainterPath,  result); | 
| 419 |     QPathClipper clipper(subject, clip); | 
| 420 |     QPainterPath x = clipper.clip(op); | 
| 421 |  | 
| 422 |     QVERIFY(QPathCompare::comparePaths(x, result)); | 
| 423 | } | 
| 424 |  | 
| 425 | static inline QPointF randomPointInRect(const QRectF &rect) | 
| 426 | { | 
| 427 |     qreal rx = QRandomGenerator::global()->bounded(highest: 1.0); | 
| 428 |     qreal ry = QRandomGenerator::global()->bounded(highest: 1.0); | 
| 429 |  | 
| 430 |     return QPointF(rect.left() + rx * rect.width(), | 
| 431 |                    rect.top() + ry * rect.height()); | 
| 432 | } | 
| 433 |  | 
| 434 | void tst_QPathClipper::clipTest(int subjectIndex, int clipIndex, QPathClipper::Operation op) | 
| 435 | { | 
| 436 |     const QPainterPath &subject = paths[subjectIndex]; | 
| 437 |     const QPainterPath &clip = paths[clipIndex]; | 
| 438 |     const int count = 40; | 
| 439 |  | 
| 440 |     QRectF bounds = subject.boundingRect().united(r: clip.boundingRect()); | 
| 441 |  | 
| 442 |     const qreal adjustX = bounds.width() * 0.01; | 
| 443 |     const qreal adjustY = bounds.height() * 0.01; | 
| 444 |  | 
| 445 |     // make sure we test some points that are outside both paths as well | 
| 446 |     bounds = bounds.adjusted(xp1: -adjustX, yp1: -adjustY, xp2: adjustX, yp2: adjustY); | 
| 447 |  | 
| 448 |     const int dim = 256; | 
| 449 |     const qreal scale = qMin(a: dim / bounds.width(), b: dim / bounds.height()); | 
| 450 |  | 
| 451 |     QPathClipper clipper(subject, clip); | 
| 452 |     QPainterPath result = clipper.clip(op); | 
| 453 |  | 
| 454 |     // using the image here is a bit of a hacky way to make sure we don't test points that | 
| 455 |     // are too close to the path edges to avoid test fails that are due to numerical errors | 
| 456 |     QImage img(dim, dim, QImage::Format_ARGB32_Premultiplied); | 
| 457 |     img.fill(pixel: 0x0); | 
| 458 |     QPainter p(&img); | 
| 459 |     p.setRenderHint(hint: QPainter::Antialiasing); | 
| 460 |     p.scale(sx: scale, sy: scale); | 
| 461 |     p.translate(offset: -bounds.topLeft()); | 
| 462 |     p.setPen(QPen(Qt::black, 0)); | 
| 463 |     p.drawPath(path: subject); | 
| 464 |     p.setPen(QPen(Qt::red, 0)); | 
| 465 |     p.drawPath(path: clip); | 
| 466 |     p.end(); | 
| 467 |  | 
| 468 |     for (int i = 0; i < count; ++i) { | 
| 469 |         QPointF point; | 
| 470 |         QRgb pixel; | 
| 471 |         do { | 
| 472 |             point = randomPointInRect(rect: bounds); | 
| 473 |             const QPointF imagePoint = (point - bounds.topLeft()) * scale; | 
| 474 |  | 
| 475 |             pixel = img.pixel(x: int(imagePoint.x()), y: int(imagePoint.y())); | 
| 476 |         } while (qAlpha(rgb: pixel) > 0); | 
| 477 |  | 
| 478 |         const bool inSubject = subject.contains(pt: point); | 
| 479 |         const bool inClip = clip.contains(pt: point); | 
| 480 |  | 
| 481 |         const bool inResult = result.contains(pt: point); | 
| 482 |  | 
| 483 |         bool expected = false; | 
| 484 |         switch (op) { | 
| 485 |         case QPathClipper::BoolAnd: | 
| 486 |             expected = inSubject && inClip; | 
| 487 |             break; | 
| 488 |         case QPathClipper::BoolOr: | 
| 489 |             expected = inSubject || inClip; | 
| 490 |             break; | 
| 491 |         case QPathClipper::BoolSub: | 
| 492 |             expected = inSubject && !inClip; | 
| 493 |             break; | 
| 494 |         default: | 
| 495 |             break; | 
| 496 |         } | 
| 497 |  | 
| 498 |         if (expected != inResult) { | 
| 499 |             char str[256]; | 
| 500 |             const char *opStr = | 
| 501 |                  op == QPathClipper::BoolAnd ? "and"  : | 
| 502 |                  op == QPathClipper::BoolOr ? "or"  : "sub" ; | 
| 503 |             sprintf(s: str, format: "Expected: %d, actual: %d, subject: %d, clip: %d, op: %s\n" , | 
| 504 |                      int(expected), int(inResult), subjectIndex, clipIndex, opStr); | 
| 505 |             QFAIL(str); | 
| 506 |         } | 
| 507 |     } | 
| 508 | } | 
| 509 |  | 
| 510 | void tst_QPathClipper::clip2() | 
| 511 | { | 
| 512 |     if (sizeof(double) != sizeof(qreal)) | 
| 513 |         QSKIP("This test only works for qreal=double, otherwise ends in rounding errors" ); | 
| 514 |  | 
| 515 |     int operation = 0; | 
| 516 |  | 
| 517 |     for (int i = 0; i < paths.size(); ++i) { | 
| 518 |         for (int j = 0; j <= i; ++j) { | 
| 519 |             QPathClipper::Operation op = QPathClipper::Operation((operation++) % 3); | 
| 520 |             clipTest(subjectIndex: i, clipIndex: j, op); | 
| 521 |         } | 
| 522 |     } | 
| 523 | } | 
| 524 |  | 
| 525 | void tst_QPathClipper::clip3() | 
| 526 | { | 
| 527 |     int operation = 0; | 
| 528 |  | 
| 529 |     // this subset should work correctly for qreal = float | 
| 530 |     for (int i = 0; i < 20; ++i) { | 
| 531 |         for (int j = 0; j <= i; ++j) { | 
| 532 |             QPathClipper::Operation op = QPathClipper::Operation((operation++) % 3); | 
| 533 |             clipTest(subjectIndex: i, clipIndex: j, op); | 
| 534 |         } | 
| 535 |     } | 
| 536 | } | 
| 537 |  | 
| 538 | void tst_QPathClipper::testIntersections() | 
| 539 | { | 
| 540 |     QPainterPath path1; | 
| 541 |     QPainterPath path2; | 
| 542 |  | 
| 543 |     path1.addRect(x: 0, y: 0, w: 100, h: 100); | 
| 544 |     path2.addRect(x: 20, y: 20, w: 20, h: 20); | 
| 545 |     QVERIFY(path1.intersects(path2)); | 
| 546 |     QVERIFY(path2.intersects(path1)); | 
| 547 |     QVERIFY(path1.contains(path2)); | 
| 548 |     QVERIFY(!path2.contains(path1)); | 
| 549 |  | 
| 550 |     path1 = QPainterPath(); | 
| 551 |     path2 = QPainterPath(); | 
| 552 |     path1.addEllipse(x: 0, y: 0, w: 100, h: 100); | 
| 553 |     path2.addEllipse(x: 200, y: 200, w: 100, h: 100); | 
| 554 |     QVERIFY(!path1.intersects(path2)); | 
| 555 |     QVERIFY(!path2.intersects(path1)); | 
| 556 |     QVERIFY(!path1.contains(path2)); | 
| 557 |     QVERIFY(!path2.contains(path1)); | 
| 558 |  | 
| 559 |     path1 = QPainterPath(); | 
| 560 |     path2 = QPainterPath(); | 
| 561 |     path1.addEllipse(x: 0, y: 0, w: 100, h: 100); | 
| 562 |     path2.addEllipse(x: 50, y: 50, w: 100, h: 100); | 
| 563 |     QVERIFY(path1.intersects(path2)); | 
| 564 |     QVERIFY(path2.intersects(path1)); | 
| 565 |     QVERIFY(!path1.contains(path2)); | 
| 566 |     QVERIFY(!path2.contains(path1)); | 
| 567 |  | 
| 568 |     path1 = QPainterPath(); | 
| 569 |     path2 = QPainterPath(); | 
| 570 |     path1.addRect(x: 100, y: 100, w: 100, h: 100); | 
| 571 |     path2.addRect(x: 50, y: 100, w: 100, h: 20); | 
| 572 |     QVERIFY(path1.intersects(path2)); | 
| 573 |     QVERIFY(path2.intersects(path1)); | 
| 574 |     QVERIFY(!path1.contains(path2)); | 
| 575 |     QVERIFY(!path2.contains(path1)); | 
| 576 |  | 
| 577 |     path1 = QPainterPath(); | 
| 578 |     path2 = QPainterPath(); | 
| 579 |     path1.addRect(x: 100, y: 100, w: 100, h: 100); | 
| 580 |     path2.addRect(x: 110, y: 201, w: 100, h: 20); | 
| 581 |     QVERIFY(!path1.intersects(path2)); | 
| 582 |     QVERIFY(!path2.intersects(path1)); | 
| 583 |     QVERIFY(!path1.contains(path2)); | 
| 584 |     QVERIFY(!path2.contains(path1)); | 
| 585 |  | 
| 586 |     path1 = QPainterPath(); | 
| 587 |     path2 = QPainterPath(); | 
| 588 |     path1.addRect(x: 0, y: 0, w: 100, h: 100); | 
| 589 |     path2.addRect(x: 20, y: 20, w: 20, h: 20); | 
| 590 |     path2.addRect(x: 25, y: 25, w: 5, h: 5); | 
| 591 |     QVERIFY(path1.intersects(path2)); | 
| 592 |     QVERIFY(path2.intersects(path1)); | 
| 593 |     QVERIFY(path1.contains(path2)); | 
| 594 |     QVERIFY(!path2.contains(path1)); | 
| 595 | } | 
| 596 |  | 
| 597 | void tst_QPathClipper::testIntersections2() | 
| 598 | { | 
| 599 |     QPainterPath path1; | 
| 600 |     QPainterPath path2; | 
| 601 |  | 
| 602 |     path1 = QPainterPath(); | 
| 603 |     path2 = QPainterPath(); | 
| 604 |  | 
| 605 |     path1.moveTo(x: -8,y: -8); | 
| 606 |     path1.lineTo(x: 107,y: -8); | 
| 607 |     path1.lineTo(x: 107,y: 107); | 
| 608 |     path1.lineTo(x: -8,y: 107); | 
| 609 |  | 
| 610 |     path2.moveTo(x: 0,y: 0); | 
| 611 |     path2.lineTo(x: 100,y: 0); | 
| 612 |     path2.lineTo(x: 100,y: 100); | 
| 613 |     path2.lineTo(x: 0,y: 100); | 
| 614 |     path2.lineTo(x: 0,y: 0); | 
| 615 |  | 
| 616 |     QVERIFY(path1.intersects(path2)); | 
| 617 |     QVERIFY(path2.intersects(path1)); | 
| 618 |     QVERIFY(path1.contains(path2)); | 
| 619 |     QVERIFY(!path2.contains(path1)); | 
| 620 |  | 
| 621 |     path1.closeSubpath(); | 
| 622 |  | 
| 623 |     QVERIFY(path1.intersects(path2)); | 
| 624 |     QVERIFY(path2.intersects(path1)); | 
| 625 |     QVERIFY(path1.contains(path2)); | 
| 626 |     QVERIFY(!path2.contains(path1)); | 
| 627 | } | 
| 628 |  | 
| 629 | void tst_QPathClipper::testIntersections3() | 
| 630 | { | 
| 631 |     QPainterPath path1 = Paths::node(); | 
| 632 |     QPainterPath path2 = Paths::interRect(); | 
| 633 |  | 
| 634 |     QVERIFY(path1.intersects(path2)); | 
| 635 |     QVERIFY(path2.intersects(path1)); | 
| 636 | } | 
| 637 |  | 
| 638 | void tst_QPathClipper::testIntersections4() | 
| 639 | { | 
| 640 |     QPainterPath path1; | 
| 641 |     QPainterPath path2; | 
| 642 |  | 
| 643 |     path1.moveTo(x: -5, y: 0); | 
| 644 |     path1.lineTo(x: 5, y: 0); | 
| 645 |  | 
| 646 |     path2.moveTo(x: 0, y: -5); | 
| 647 |     path2.lineTo(x: 0, y: 5); | 
| 648 |  | 
| 649 |     QVERIFY(path1.intersects(path2)); | 
| 650 |     QVERIFY(path2.intersects(path1)); | 
| 651 | } | 
| 652 |  | 
| 653 | void tst_QPathClipper::testIntersections5() | 
| 654 | { | 
| 655 |     QPainterPath path1; | 
| 656 |     QPainterPath path2; | 
| 657 |  | 
| 658 |     path1.addRect(x: 0, y: 0, w: 4, h: 4); | 
| 659 |     path1.addRect(x: 2, y: 1, w: 1, h: 1); | 
| 660 |     path2.addRect(x: 0.5, y: 2, w: 1, h: 1); | 
| 661 |  | 
| 662 |     QVERIFY(path1.intersects(path2)); | 
| 663 |     QVERIFY(path2.intersects(path1)); | 
| 664 | } | 
| 665 |  | 
| 666 | void tst_QPathClipper::testIntersections6() | 
| 667 | { | 
| 668 |     QPainterPath path1; | 
| 669 |     QPainterPath path2; | 
| 670 |  | 
| 671 |     path1.moveTo(p: QPointF(-115.567, -98.3254)); | 
| 672 |     path1.lineTo(p: QPointF(-45.9007, -98.3254)); | 
| 673 |     path1.lineTo(p: QPointF(-45.9007, -28.6588)); | 
| 674 |     path1.lineTo(p: QPointF(-115.567, -28.6588)); | 
| 675 |  | 
| 676 |     path2.moveTo(p: QPointF(-110, -110)); | 
| 677 |     path2.lineTo(p: QPointF(110, -110)); | 
| 678 |     path2.lineTo(p: QPointF(110, 110)); | 
| 679 |     path2.lineTo(p: QPointF(-110, 110)); | 
| 680 |     path2.lineTo(p: QPointF(-110, -110)); | 
| 681 |  | 
| 682 |     QVERIFY(path1.intersects(path2)); | 
| 683 |     QVERIFY(path2.intersects(path1)); | 
| 684 | } | 
| 685 |  | 
| 686 |  | 
| 687 | void tst_QPathClipper::testIntersections7() | 
| 688 | { | 
| 689 |     QPainterPath path1; | 
| 690 |     QPainterPath path2; | 
| 691 |  | 
| 692 |     path1.addRect(x: 0, y: 0, w: 10, h: 10); | 
| 693 |     path2.addRect(x: 5, y: 0, w: 10, h: 10); | 
| 694 |  | 
| 695 |     QVERIFY(path1.intersects(path2)); | 
| 696 |     QVERIFY(path2.intersects(path1)); | 
| 697 |  | 
| 698 |     path1 = QPainterPath(); | 
| 699 |     path2 = QPainterPath(); | 
| 700 |     path1.addRect(x: 0, y: 0, w: 10, h: 10); | 
| 701 |     path2.addRect(x: 0, y: 5, w: 10, h: 10); | 
| 702 |  | 
| 703 |     QVERIFY(path1.intersects(path2)); | 
| 704 |     QVERIFY(path2.intersects(path1)); | 
| 705 |  | 
| 706 |     path1 = QPainterPath(); | 
| 707 |     path2 = QPainterPath(); | 
| 708 |     path1.addRect(x: 0, y: 0, w: 10, h: 10); | 
| 709 |     path2.addRect(x: 0, y: 0, w: 10, h: 10); | 
| 710 |  | 
| 711 |     QVERIFY(path1.intersects(path2)); | 
| 712 |     QVERIFY(path2.intersects(path1)); | 
| 713 |  | 
| 714 |     /// | 
| 715 |     path1 = QPainterPath(); | 
| 716 |     path2 = QPainterPath(); | 
| 717 |     path1.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 718 |     path2.addRect(x: 5, y: 1, w: 10, h: 10); | 
| 719 |  | 
| 720 |     QVERIFY(path1.intersects(path2)); | 
| 721 |     QVERIFY(path2.intersects(path1)); | 
| 722 |  | 
| 723 |     path1 = QPainterPath(); | 
| 724 |     path2 = QPainterPath(); | 
| 725 |     path1.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 726 |     path2.addRect(x: 1, y: 5, w: 10, h: 10); | 
| 727 |  | 
| 728 |     QVERIFY(path1.intersects(path2)); | 
| 729 |     QVERIFY(path2.intersects(path1)); | 
| 730 |  | 
| 731 |     path1 = QPainterPath(); | 
| 732 |     path2 = QPainterPath(); | 
| 733 |     path1.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 734 |     path2.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 735 |  | 
| 736 |     QVERIFY(path1.intersects(path2)); | 
| 737 |     QVERIFY(path2.intersects(path1)); | 
| 738 |  | 
| 739 |     path1 = QPainterPath(); | 
| 740 |     path2 = QPainterPath(); | 
| 741 |     path1.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 742 |     path2.addRect(x: 5, y: 5, w: 10, h: 10); | 
| 743 |  | 
| 744 |     QVERIFY(path1.intersects(path2)); | 
| 745 |     QVERIFY(path2.intersects(path1)); | 
| 746 |  | 
| 747 |     path1 = QPainterPath(); | 
| 748 |     path2 = QPainterPath(); | 
| 749 |     path1.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 750 |     path2.addRect(x: 9, y: 9, w: 10, h: 10); | 
| 751 |  | 
| 752 |     QVERIFY(path1.intersects(path2)); | 
| 753 |     QVERIFY(path2.intersects(path1)); | 
| 754 |  | 
| 755 |     path1 = QPainterPath(); | 
| 756 |     path2 = QPainterPath(); | 
| 757 |     path1.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 758 |     path2.addRect(x: 10, y: 10, w: 10, h: 10); | 
| 759 |  | 
| 760 |     QVERIFY(path1.intersects(path2)); | 
| 761 |     QVERIFY(path2.intersects(path1)); | 
| 762 |  | 
| 763 |     path1 = QPainterPath(); | 
| 764 |     path2 = QPainterPath(); | 
| 765 |     path1.addRect(x: 1, y: 1, w: 9, h: 9); | 
| 766 |     path2.addRect(x: 11, y: 11, w: 10, h: 10); | 
| 767 |  | 
| 768 |     QVERIFY(!path1.intersects(path2)); | 
| 769 |     QVERIFY(!path2.intersects(path1)); | 
| 770 |  | 
| 771 |     path1 = QPainterPath(); | 
| 772 |     path2 = QPainterPath(); | 
| 773 |     path1.addRect(x: 1, y: 1, w: 10, h: 10); | 
| 774 |     path2.addRect(x: 12, y: 12, w: 10, h: 10); | 
| 775 |  | 
| 776 |     QVERIFY(!path1.intersects(path2)); | 
| 777 |     QVERIFY(!path2.intersects(path1)); | 
| 778 |  | 
| 779 |     path1 = QPainterPath(); | 
| 780 |     path2 = QPainterPath(); | 
| 781 |     path1.addRect(x: 11, y: 11, w: 10, h: 10); | 
| 782 |     path2.addRect(x: 12, y: 12, w: 10, h: 10); | 
| 783 |  | 
| 784 |     QVERIFY(path1.intersects(path2)); | 
| 785 |     QVERIFY(path2.intersects(path1)); | 
| 786 |  | 
| 787 |     path1 = QPainterPath(); | 
| 788 |     path2 = QPainterPath(); | 
| 789 |     path1.addRect(x: 11, y: 11, w: 10, h: 10); | 
| 790 |     path2.addRect(x: 10, y: 10, w: 10, h: 10); | 
| 791 |  | 
| 792 |     QVERIFY(path1.intersects(path2)); | 
| 793 |     QVERIFY(path2.intersects(path1)); | 
| 794 | } | 
| 795 |  | 
| 796 |  | 
| 797 | void tst_QPathClipper::testIntersections8() | 
| 798 | { | 
| 799 |     QPainterPath path1 = Paths::node() * QTransform().translate(dx: 100, dy: 50); | 
| 800 |     QPainterPath path2 = Paths::node() * QTransform().translate(dx: 150, dy: 50);; | 
| 801 |  | 
| 802 |     QVERIFY(path1.intersects(path2)); | 
| 803 |     QVERIFY(path2.intersects(path1)); | 
| 804 |  | 
| 805 |     path1 = Paths::node(); | 
| 806 |     path2 = Paths::node(); | 
| 807 |  | 
| 808 |     QVERIFY(path1.intersects(path2)); | 
| 809 |     QVERIFY(path2.intersects(path1)); | 
| 810 |  | 
| 811 |     path1 = Paths::node(); | 
| 812 |     path2 = Paths::node() * QTransform().translate(dx: 0, dy: 30); | 
| 813 |  | 
| 814 |     QVERIFY(path1.intersects(path2)); | 
| 815 |     QVERIFY(path2.intersects(path1)); | 
| 816 |  | 
| 817 |     path1 = Paths::node(); | 
| 818 |     path2 = Paths::node() * QTransform().translate(dx: 30, dy: 0); | 
| 819 |  | 
| 820 |     QVERIFY(path1.intersects(path2)); | 
| 821 |     QVERIFY(path2.intersects(path1)); | 
| 822 |  | 
| 823 |     path1 = Paths::node(); | 
| 824 |     path2 = Paths::node() * QTransform().translate(dx: 30, dy: 30); | 
| 825 |  | 
| 826 |     QVERIFY(path1.intersects(path2)); | 
| 827 |     QVERIFY(path2.intersects(path1)); | 
| 828 |  | 
| 829 |     path1 = Paths::node(); | 
| 830 |     path2 = Paths::node() * QTransform().translate(dx: 1, dy: 1); | 
| 831 |  | 
| 832 |     QVERIFY(path1.intersects(path2)); | 
| 833 |     QVERIFY(path2.intersects(path1)); | 
| 834 | } | 
| 835 |  | 
| 836 |  | 
| 837 | void tst_QPathClipper::testIntersections9() | 
| 838 | { | 
| 839 |     QPainterPath path1; | 
| 840 |     QPainterPath path2; | 
| 841 |  | 
| 842 |     path1.addRect(rect: QRectF(-1,143, 146, 106)); | 
| 843 |     path2.addRect(rect: QRectF(-9,145, 150, 100)); | 
| 844 |  | 
| 845 |     QVERIFY(path1.intersects(path2)); | 
| 846 |     QVERIFY(path2.intersects(path1)); | 
| 847 |  | 
| 848 |     path1 = QPainterPath();; | 
| 849 |     path2 = QPainterPath(); | 
| 850 |  | 
| 851 |     path1.addRect(rect: QRectF(-1,191, 136, 106)); | 
| 852 |     path2.addRect(rect: QRectF(-19,194, 150, 100)); | 
| 853 |     QVERIFY(path1.intersects(path2)); | 
| 854 |     QVERIFY(path2.intersects(path1)); | 
| 855 |  | 
| 856 |     path1 = QPainterPath();; | 
| 857 |     path2 = QPainterPath(); | 
| 858 |  | 
| 859 |     path1.moveTo(x: -1 ,  y: 143); | 
| 860 |     path1.lineTo(x: 148 ,  y: 143); | 
| 861 |     path1.lineTo(x: 148 ,  y: 250); | 
| 862 |     path1.lineTo(x: -1 ,  y: 250); | 
| 863 |  | 
| 864 |     path2.moveTo(x: -5 ,  y: 146); | 
| 865 |     path2.lineTo(x: 145 ,  y: 146); | 
| 866 |     path2.lineTo(x: 145 ,  y: 246); | 
| 867 |     path2.lineTo(x: -5 ,  y: 246); | 
| 868 |     path2.lineTo(x: -5 ,  y: 146); | 
| 869 |  | 
| 870 |     QVERIFY(path1.intersects(path2)); | 
| 871 |     QVERIFY(path2.intersects(path1)); | 
| 872 | } | 
| 873 |  | 
| 874 | QPainterPath pathFromRect(qreal x, qreal y, qreal w, qreal h) | 
| 875 | { | 
| 876 |     QPainterPath path; | 
| 877 |     path.addRect(rect: QRectF(x, y, w, h)); | 
| 878 |     return path; | 
| 879 | } | 
| 880 |  | 
| 881 | QPainterPath pathFromLine(qreal x1, qreal y1, qreal x2, qreal y2) | 
| 882 | { | 
| 883 |     QPainterPath path; | 
| 884 |     path.moveTo(x: x1, y: y1); | 
| 885 |     path.lineTo(x: x2, y: y2); | 
| 886 |     return path; | 
| 887 | } | 
| 888 |  | 
| 889 | static int loopLength(const QWingedEdge &list, QWingedEdge::TraversalStatus status) | 
| 890 | { | 
| 891 |     int start = status.edge; | 
| 892 |  | 
| 893 |     int length = 0; | 
| 894 |     do { | 
| 895 |         ++length; | 
| 896 |         status = list.next(status); | 
| 897 |     } while (status.edge != start); | 
| 898 |  | 
| 899 |     return length; | 
| 900 | } | 
| 901 |  | 
| 902 | void tst_QPathClipper::testWingedEdge() | 
| 903 | { | 
| 904 |     { | 
| 905 |         QWingedEdge list; | 
| 906 |         int e1 = list.addEdge(a: QPointF(0, 0), b: QPointF(10, 0)); | 
| 907 |         int e2 = list.addEdge(a: QPointF(0, 0), b: QPointF(0, 10)); | 
| 908 |         int e3 = list.addEdge(a: QPointF(0, 0), b: QPointF(-10, 0)); | 
| 909 |         int e4 = list.addEdge(a: QPointF(0, 0), b: QPointF(0, -10)); | 
| 910 |  | 
| 911 |         QCOMPARE(list.edgeCount(), 4); | 
| 912 |         QCOMPARE(list.vertexCount(), 5); | 
| 913 |  | 
| 914 |         QWingedEdge::TraversalStatus status = { .edge: e1, .traversal: QPathEdge::RightTraversal, .direction: QPathEdge::Forward }; | 
| 915 |  | 
| 916 |         status = list.next(status); | 
| 917 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 918 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 919 |         QCOMPARE(status.edge, e1); | 
| 920 |  | 
| 921 |         status = list.next(status); | 
| 922 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 923 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 924 |         QCOMPARE(status.edge, e4); | 
| 925 |  | 
| 926 |         status = list.next(status); | 
| 927 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 928 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 929 |         QCOMPARE(status.edge, e4); | 
| 930 |  | 
| 931 |         status = list.next(status); | 
| 932 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 933 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 934 |         QCOMPARE(status.edge, e3); | 
| 935 |  | 
| 936 |         status = list.next(status); | 
| 937 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 938 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 939 |         QCOMPARE(status.edge, e3); | 
| 940 |  | 
| 941 |         status = list.next(status); | 
| 942 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 943 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 944 |         QCOMPARE(status.edge, e2); | 
| 945 |  | 
| 946 |         status = list.next(status); | 
| 947 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 948 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 949 |         QCOMPARE(status.edge, e2); | 
| 950 |  | 
| 951 |         status = list.next(status); | 
| 952 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 953 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 954 |         QCOMPARE(status.edge, e1); | 
| 955 |     } | 
| 956 |     { | 
| 957 |         QWingedEdge list; | 
| 958 |         int e1 = list.addEdge(a: QPointF(5, 0), b: QPointF(5, 10)); | 
| 959 |         int e2 = list.addEdge(a: QPointF(5, 0), b: QPointF(10, 5)); | 
| 960 |         int e3 = list.addEdge(a: QPointF(10, 5), b: QPointF(5, 10)); | 
| 961 |         int e4 = list.addEdge(a: QPointF(5, 0), b: QPointF(0, 5)); | 
| 962 |         int e5 = list.addEdge(a: QPointF(0, 5), b: QPointF(5, 10)); | 
| 963 |  | 
| 964 |         QCOMPARE(list.edgeCount(), 5); | 
| 965 |         QCOMPARE(list.vertexCount(), 4); | 
| 966 |  | 
| 967 |         QWingedEdge::TraversalStatus status = { .edge: e1, .traversal: QPathEdge::RightTraversal, .direction: QPathEdge::Forward }; | 
| 968 |  | 
| 969 |         status = list.next(status); | 
| 970 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 971 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 972 |         QCOMPARE(status.edge, e5); | 
| 973 |  | 
| 974 |         status = list.next(status); | 
| 975 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 976 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 977 |         QCOMPARE(status.edge, e4); | 
| 978 |  | 
| 979 |         status = list.next(status); | 
| 980 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 981 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 982 |         QCOMPARE(status.edge, e1); | 
| 983 |  | 
| 984 |         QCOMPARE(loopLength(list, status), 3); | 
| 985 |  | 
| 986 |         status.flip(); | 
| 987 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 988 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 989 |         QCOMPARE(loopLength(list, status), 3); | 
| 990 |  | 
| 991 |         status = list.next(status); | 
| 992 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 993 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 994 |         QCOMPARE(status.edge, e2); | 
| 995 |  | 
| 996 |         status = list.next(status); | 
| 997 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 998 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 999 |         QCOMPARE(status.edge, e3); | 
| 1000 |  | 
| 1001 |         status = list.next(status); | 
| 1002 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 1003 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 1004 |         QCOMPARE(status.edge, e1); | 
| 1005 |  | 
| 1006 |         status = list.next(status); | 
| 1007 |         status.flip(); | 
| 1008 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 1009 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 1010 |         QCOMPARE(status.edge, e2); | 
| 1011 |         QCOMPARE(loopLength(list, status), 4); | 
| 1012 |  | 
| 1013 |         status = list.next(status); | 
| 1014 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 1015 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 1016 |         QCOMPARE(status.edge, e4); | 
| 1017 |  | 
| 1018 |         status = list.next(status); | 
| 1019 |         QCOMPARE(status.direction, QPathEdge::Forward); | 
| 1020 |         QCOMPARE(status.traversal, QPathEdge::RightTraversal); | 
| 1021 |         QCOMPARE(status.edge, e5); | 
| 1022 |  | 
| 1023 |         status = list.next(status); | 
| 1024 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 1025 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 1026 |         QCOMPARE(status.edge, e3); | 
| 1027 |  | 
| 1028 |         status = list.next(status); | 
| 1029 |         QCOMPARE(status.direction, QPathEdge::Backward); | 
| 1030 |         QCOMPARE(status.traversal, QPathEdge::LeftTraversal); | 
| 1031 |         QCOMPARE(status.edge, e2); | 
| 1032 |     } | 
| 1033 |     { | 
| 1034 |         QPainterPath path = pathFromRect(x: 0, y: 0, w: 20, h: 20); | 
| 1035 |         QWingedEdge list(path, QPainterPath()); | 
| 1036 |  | 
| 1037 |         QCOMPARE(list.edgeCount(), 4); | 
| 1038 |         QCOMPARE(list.vertexCount(), 4); | 
| 1039 |  | 
| 1040 |         QWingedEdge::TraversalStatus status = { .edge: 0, .traversal: QPathEdge::RightTraversal, .direction: QPathEdge::Forward }; | 
| 1041 |  | 
| 1042 |         QPathEdge *edge = list.edge(edge: status.edge); | 
| 1043 |         QCOMPARE(QPointF(*list.vertex(edge->first)), QPointF(0, 0)); | 
| 1044 |         QCOMPARE(QPointF(*list.vertex(edge->second)), QPointF(20, 0)); | 
| 1045 |  | 
| 1046 |         status = list.next(status); | 
| 1047 |         QCOMPARE(status.edge, 1); | 
| 1048 |  | 
| 1049 |         status = list.next(status); | 
| 1050 |         QCOMPARE(status.edge, 2); | 
| 1051 |  | 
| 1052 |         status = list.next(status); | 
| 1053 |         QCOMPARE(status.edge, 3); | 
| 1054 |  | 
| 1055 |         status = list.next(status); | 
| 1056 |         QCOMPARE(status.edge, 0); | 
| 1057 |  | 
| 1058 |         status.flipDirection(); | 
| 1059 |         status = list.next(status); | 
| 1060 |         QCOMPARE(status.edge, 3); | 
| 1061 |  | 
| 1062 |         status = list.next(status); | 
| 1063 |         QCOMPARE(status.edge, 2); | 
| 1064 |  | 
| 1065 |         status = list.next(status); | 
| 1066 |         QCOMPARE(status.edge, 1); | 
| 1067 |  | 
| 1068 |         status = list.next(status); | 
| 1069 |         QCOMPARE(status.edge, 0); | 
| 1070 |  | 
| 1071 |         QWingedEdge list2(path, pathFromRect(x: 10, y: 5, w: 20, h: 10)); | 
| 1072 |  | 
| 1073 |         QCOMPARE(list2.edgeCount(), 12); | 
| 1074 |         QCOMPARE(list2.vertexCount(), 10); | 
| 1075 |  | 
| 1076 |         status.flipDirection(); | 
| 1077 |         QCOMPARE(loopLength(list2, status), 8); | 
| 1078 |  | 
| 1079 |         status = list2.next(status); | 
| 1080 |         edge = list2.edge(edge: status.edge); | 
| 1081 |         QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(20, 0)); | 
| 1082 |         QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(20, 5)); | 
| 1083 |  | 
| 1084 |         status = list2.next(status); | 
| 1085 |         status.flipTraversal(); | 
| 1086 |  | 
| 1087 |         edge = list2.edge(edge: status.edge); | 
| 1088 |         QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(10, 5)); | 
| 1089 |         QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(20, 5)); | 
| 1090 |  | 
| 1091 |         QCOMPARE(loopLength(list2, status), 4); | 
| 1092 |  | 
| 1093 |         status.flipDirection(); | 
| 1094 |         status = list2.next(status); | 
| 1095 |         status.flipTraversal(); | 
| 1096 |  | 
| 1097 |         edge = list2.edge(edge: status.edge); | 
| 1098 |         QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(20, 5)); | 
| 1099 |         QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(20, 15)); | 
| 1100 |  | 
| 1101 |         QCOMPARE(loopLength(list2, status), 4); | 
| 1102 |         status = list2.next(status); | 
| 1103 |         status = list2.next(status); | 
| 1104 |  | 
| 1105 |         edge = list2.edge(edge: status.edge); | 
| 1106 |         QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(30, 5)); | 
| 1107 |         QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(30, 15)); | 
| 1108 |     } | 
| 1109 | } | 
| 1110 |  | 
| 1111 | void tst_QPathClipper::zeroDerivativeCurves() | 
| 1112 | { | 
| 1113 |     // zero derivative at end | 
| 1114 |     { | 
| 1115 |         QPainterPath a; | 
| 1116 |         a.cubicTo(ctrlPt1x: 100, ctrlPt1y: 0, ctrlPt2x: 100, ctrlPt2y: 100, endPtx: 100, endPty: 100); | 
| 1117 |         a.lineTo(x: 100, y: 200); | 
| 1118 |         a.lineTo(x: 0, y: 200); | 
| 1119 |  | 
| 1120 |         QPainterPath b; | 
| 1121 |         b.moveTo(x: 50, y: 100); | 
| 1122 |         b.lineTo(x: 150, y: 100); | 
| 1123 |         b.lineTo(x: 150, y: 150); | 
| 1124 |         b.lineTo(x: 50, y: 150); | 
| 1125 |  | 
| 1126 |         QPainterPath c = a.united(r: b); | 
| 1127 |         QVERIFY(c.contains(QPointF(25, 125))); | 
| 1128 |         QVERIFY(c.contains(QPointF(75, 125))); | 
| 1129 |         QVERIFY(c.contains(QPointF(125, 125))); | 
| 1130 |     } | 
| 1131 |  | 
| 1132 |     // zero derivative at start | 
| 1133 |     { | 
| 1134 |         QPainterPath a; | 
| 1135 |         a.cubicTo(ctrlPt1x: 100, ctrlPt1y: 0, ctrlPt2x: 100, ctrlPt2y: 100, endPtx: 100, endPty: 100); | 
| 1136 |         a.lineTo(x: 100, y: 200); | 
| 1137 |         a.lineTo(x: 0, y: 200); | 
| 1138 |  | 
| 1139 |         QPainterPath b; | 
| 1140 |         b.moveTo(x: 50, y: 100); | 
| 1141 |         b.lineTo(x: 150, y: 100); | 
| 1142 |         b.lineTo(x: 150, y: 150); | 
| 1143 |         b.lineTo(x: 50, y: 150); | 
| 1144 |  | 
| 1145 |         QPainterPath c = a.united(r: b); | 
| 1146 |         QVERIFY(c.contains(QPointF(25, 125))); | 
| 1147 |         QVERIFY(c.contains(QPointF(75, 125))); | 
| 1148 |         QVERIFY(c.contains(QPointF(125, 125))); | 
| 1149 |     } | 
| 1150 | } | 
| 1151 |  | 
| 1152 | static bool strictContains(const QPainterPath &a, const QPainterPath &b) | 
| 1153 | { | 
| 1154 |     return b.subtracted(r: a) == QPainterPath(); | 
| 1155 | } | 
| 1156 |  | 
| 1157 |  | 
| 1158 | void tst_QPathClipper::task204301_data() | 
| 1159 | { | 
| 1160 |     QTest::addColumn<QPolygonF>(name: "points" ); | 
| 1161 |  | 
| 1162 |     { | 
| 1163 |         QPointF a(51.09013255685567855835, 31.30814891308546066284); | 
| 1164 |         QPointF b(98.39898971840739250183, 11.02079074829816818237); | 
| 1165 |         QPointF c(91.23911846894770860672, 45.86981737054884433746); | 
| 1166 |         QPointF d(66.58616356085985898972, 63.10526528395712375641); | 
| 1167 |         QPointF e(82.08219456479714892794, 94.90238165489137145414); | 
| 1168 |         QPointF f(16.09013040543221251255, 105.66263409332729850121); | 
| 1169 |         QPointF g(10.62811442650854587555, 65.09154842235147953033); | 
| 1170 |         QPointF h(5.16609844751656055450, 24.52046275138854980469); | 
| 1171 |         QPolygonF v; | 
| 1172 |         v << a << b << c << d << e << f << g << h; | 
| 1173 |         QTest::newRow(dataTag: "failed_on_linux" ) << v; | 
| 1174 |     } | 
| 1175 |  | 
| 1176 |     { | 
| 1177 |         QPointF a(50.014648437500000, 24.392089843750000); | 
| 1178 |         QPointF b(92.836303710937500, 5.548706054687500); | 
| 1179 |         QPointF c(92.145690917968750, 54.390258789062500); | 
| 1180 |         QPointF d(65.402221679687500, 74.345092773437500); | 
| 1181 |         QPointF e(80.789794921787347, 124.298095703129690); | 
| 1182 |         QPointF f(34.961242675812954, 87.621459960852135); | 
| 1183 |         QPointF g(18.305969238281250, 57.426757812500000); | 
| 1184 |         QPointF h(1.650695800781250, 27.232055664062500); | 
| 1185 |         QPolygonF v; | 
| 1186 |         v << a << b << c << d << e << f << g << h; | 
| 1187 |         QTest::newRow(dataTag: "failed_on_windows" ) << v; | 
| 1188 |     } | 
| 1189 | } | 
| 1190 |  | 
| 1191 | void tst_QPathClipper::task204301() | 
| 1192 | { | 
| 1193 |     QFETCH(QPolygonF, points); | 
| 1194 |  | 
| 1195 |     QPointF a = points[0]; | 
| 1196 |     QPointF b = points[1]; | 
| 1197 |     QPointF c = points[2]; | 
| 1198 |     QPointF d = points[3]; | 
| 1199 |     QPointF e = points[4]; | 
| 1200 |     QPointF f = points[5]; | 
| 1201 |     QPointF g = points[6]; | 
| 1202 |     QPointF h = points[7]; | 
| 1203 |  | 
| 1204 |     QPainterPath subA; | 
| 1205 |     subA.addPolygon(polygon: QPolygonF() << a << b << c << d); | 
| 1206 |     subA.closeSubpath(); | 
| 1207 |  | 
| 1208 |     QPainterPath subB; | 
| 1209 |     subB.addPolygon(polygon: QPolygonF() << f << e << d << g); | 
| 1210 |     subB.closeSubpath(); | 
| 1211 |  | 
| 1212 |     QPainterPath subC; | 
| 1213 |     subC.addPolygon(polygon: QPolygonF() << h << a << d << g); | 
| 1214 |     subC.closeSubpath(); | 
| 1215 |  | 
| 1216 |     QPainterPath path; | 
| 1217 |     path.addPath(path: subA); | 
| 1218 |     path.addPath(path: subB); | 
| 1219 |     path.addPath(path: subC); | 
| 1220 |  | 
| 1221 |     QPainterPath simplified = path.simplified(); | 
| 1222 |  | 
| 1223 |     QVERIFY(strictContains(simplified, subA)); | 
| 1224 |     QVERIFY(strictContains(simplified, subB)); | 
| 1225 |     QVERIFY(strictContains(simplified, subC)); | 
| 1226 | } | 
| 1227 |  | 
| 1228 | void tst_QPathClipper::task209056() | 
| 1229 | { | 
| 1230 |     QPainterPath p1; | 
| 1231 |     p1.moveTo( p: QPointF(188.506, 287.793) ); | 
| 1232 |     p1.lineTo( p: QPointF(288.506, 287.793) ); | 
| 1233 |     p1.lineTo( p: QPointF(288.506, 387.793) ); | 
| 1234 |     p1.lineTo( p: QPointF(188.506, 387.793) ); | 
| 1235 |     p1.lineTo( p: QPointF(188.506, 287.793) ); | 
| 1236 |  | 
| 1237 |     QPainterPath p2; | 
| 1238 |     p2.moveTo( p: QPointF(419.447, 164.383) ); | 
| 1239 |     p2.cubicTo( ctrlPt1: QPointF(419.447, 69.5486), ctrlPt2: QPointF(419.447, 259.218),endPt: QPointF(419.447, 164.383) ); | 
| 1240 |  | 
| 1241 |     p2.cubicTo( ctrlPt1: QPointF(48.9378, 259.218), ctrlPt2: QPointF(131.879, 336.097),endPt: QPointF(234.192, 336.097) ); | 
| 1242 |     p2.cubicTo( ctrlPt1: QPointF(336.506, 336.097), ctrlPt2: QPointF(419.447, 259.218),endPt: QPointF(419.447, 164.383) ); | 
| 1243 |  | 
| 1244 |     QPainterPath p3 = p1.intersected(r: p2); | 
| 1245 |  | 
| 1246 |     QVERIFY(p3 != QPainterPath()); | 
| 1247 | } | 
| 1248 |  | 
| 1249 | void tst_QPathClipper::task251909() | 
| 1250 | { | 
| 1251 |     QPainterPath p1; | 
| 1252 |     p1.moveTo(x: 0, y: -10); | 
| 1253 |     p1.lineTo(x: 10, y: -10); | 
| 1254 |     p1.lineTo(x: 10, y: 0); | 
| 1255 |     p1.lineTo(x: 0, y: 0); | 
| 1256 |  | 
| 1257 |     QPainterPath p2; | 
| 1258 |     p2.moveTo(x: 0, y: 8e-14); | 
| 1259 |     p2.lineTo(x: 10, y: -8e-14); | 
| 1260 |     p2.lineTo(x: 10, y: 10); | 
| 1261 |     p2.lineTo(x: 0, y: 10); | 
| 1262 |  | 
| 1263 |     QPainterPath result = p1.united(r: p2); | 
| 1264 |  | 
| 1265 |     QVERIFY(result.elementCount() <= 5); | 
| 1266 | } | 
| 1267 |  | 
| 1268 | void tst_QPathClipper::qtbug3778() | 
| 1269 | { | 
| 1270 |     if (sizeof(double) != sizeof(qreal)) { | 
| 1271 |         QSKIP("This test only works for qreal=double, otherwise ends in rounding errors" ); | 
| 1272 |     } | 
| 1273 |     QPainterPath path1; | 
| 1274 |     path1.moveTo(x: 200, y: 3.22409e-5); | 
| 1275 |     // e-5 and higher leads to a bug | 
| 1276 |     // Using 3.22409e-4 starts to work correctly | 
| 1277 |     path1.lineTo(x: 0, y: 0); | 
| 1278 |     path1.lineTo(x: 1.07025e-13, y: 1450); | 
| 1279 |     path1.lineTo(x: 750, y: 950); | 
| 1280 |     path1.lineTo(x: 950, y: 750); | 
| 1281 |     path1.lineTo(x: 200, y: 3.22409e-13); | 
| 1282 |  | 
| 1283 |     QPainterPath path2; | 
| 1284 |     path2.moveTo(x: 0, y: 0); | 
| 1285 |     path2.lineTo(x: 200, y: 800); | 
| 1286 |     path2.lineTo(x: 600, y: 1500); | 
| 1287 |     path2.lineTo(x: 1500, y: 1400); | 
| 1288 |     path2.lineTo(x: 1900, y: 1200); | 
| 1289 |     path2.lineTo(x: 2000, y: 1000); | 
| 1290 |     path2.lineTo(x: 1400, y: 0); | 
| 1291 |     path2.lineTo(x: 0, y: 0); | 
| 1292 |  | 
| 1293 |     QPainterPath p12 = path1.intersected(r: path2); | 
| 1294 |  | 
| 1295 |     QVERIFY(p12.contains(QPointF(100, 100))); | 
| 1296 | } | 
| 1297 |  | 
| 1298 | void tst_QPathClipper::qtbug60024() | 
| 1299 | { | 
| 1300 |     QPolygonF poly1, poly2; | 
| 1301 |     poly1 << QPointF(508.331,1010.23) ; | 
| 1302 |     poly1 << QPointF(492.798,1023.11) ; | 
| 1303 |     poly1 << QPointF(491.431,1024.23) ; | 
| 1304 |     poly1 << QPointF(491.928,1022.94) ; | 
| 1305 |     poly1 << QPointF(492.054,1022.15) ; | 
| 1306 |     poly1 << QPointF(492.136,1020.91) ; | 
| 1307 |     poly1 << QPointF(491.638,1019.2) ; | 
| 1308 |     poly1 << QPointF(490.436,1017.12) ; | 
| 1309 |     poly1 << QPointF(489.856,1016.46) ; | 
| 1310 |     poly1 << QPointF(489.276,1016.08) ; | 
| 1311 |     poly1 << QPointF(488.16,1015.54) ; | 
| 1312 |     poly1 << QPointF(487.33,1014.91) ; | 
| 1313 |     poly1 << QPointF(486.914,1014.16) ; | 
| 1314 |     poly1 << QPointF(486.875,1013.54) ; | 
| 1315 |     poly1 << QPointF(487.204,1012.38) ; | 
| 1316 |     poly1 << QPointF(487.412,1011.34) ; | 
| 1317 |     poly1 << QPointF(487.373,1009.92) ; | 
| 1318 |     poly1 << QPointF(487.702,1007.34) ; | 
| 1319 |     poly1 << QPointF(487.909,1006.3) ; | 
| 1320 |     poly1 << QPointF(488.242,1005.55) ; | 
| 1321 |     poly1 << QPointF(488.74,1004.14) ; | 
| 1322 |     poly1 << QPointF(489.445,1003.14) ; | 
| 1323 |     poly1 << QPointF(490.107,1001.56) ; | 
| 1324 |     poly1 << QPointF(490.064,1000.98) ; | 
| 1325 |     poly1 << QPointF(489.566,999.936) ; | 
| 1326 |     poly1 << QPointF(488.489,998.194) ; | 
| 1327 |     poly1 << QPointF(488.117,997.274) ; | 
| 1328 |     poly1 << QPointF(487.909,995.946) ; | 
| 1329 |     poly1 << QPointF(487.909,995.027) ; | 
| 1330 |     poly1 << QPointF(488.117,993.16) ; | 
| 1331 |     poly1 << QPointF(488.658,989.749) ; | 
| 1332 |     poly1 << QPointF(488.861,987.002) ; | 
| 1333 |     poly1 << QPointF(489.359,976.434) ; | 
| 1334 |     poly1 << QPointF(489.484,974.476) ; | 
| 1335 |     poly1 << QPointF(489.484,972.859) ; | 
| 1336 |     poly1 << QPointF(489.359,971.775) ; | 
| 1337 |     poly1 << QPointF(489.151,970.986) ; | 
| 1338 |     poly1 << QPointF(488.948,969.323) ; | 
| 1339 |     poly1 << QPointF(488.74,966.036) ; | 
| 1340 |     poly1 << QPointF(488.74,964.118) ; | 
| 1341 |     poly1 << QPointF(489.03,961.292) ; | 
| 1342 |     poly1 << QPointF(489.237,960.667) ; | 
| 1343 |     poly1 << QPointF(489.648,960.043) ; | 
| 1344 |     poly1 << QPointF(490.452,959.229) ; | 
| 1345 |     poly1 << QPointF(491.528,958.225) ; | 
| 1346 |     poly1 << QPointF(491.731,957.515) ; | 
| 1347 |     poly1 << QPointF(491.32,956.812) ; | 
| 1348 |     poly1 << QPointF(490.45,955.852) ; | 
| 1349 |     poly1 << QPointF(489.412,954.354) ; | 
| 1350 |     poly1 << QPointF(488.68,952.934) ; | 
| 1351 |     poly1 << QPointF(488.625,951.201) ; | 
| 1352 |     poly1 << QPointF(488.954,950.072) ; | 
| 1353 |     poly1 << QPointF(489.237,949.225) ; | 
| 1354 |     poly1 << QPointF(489.256,948.668) ; | 
| 1355 |     poly1 << QPointF(489.402,948.186) ; | 
| 1356 |     poly1 << QPointF(489.566,947.437) ; | 
| 1357 |     poly1 << QPointF(490.025,945.899) ; | 
| 1358 |     poly1 << QPointF(490.687,944.026) ; | 
| 1359 |     poly1 << QPointF(491.059,942.073) ; | 
| 1360 |     poly1 << QPointF(491.31,941.159) ; | 
| 1361 |     poly1 << QPointF(491.846,937.248) ; | 
| 1362 |     poly1 << QPointF(492.054,936.374) ; | 
| 1363 |     poly1 << QPointF(492.594,935.29) ; | 
| 1364 |     poly1 << QPointF(492.594,935.086) ; | 
| 1365 |     poly1 << QPointF(492.261,934.416) ; | 
| 1366 |     poly1 << QPointF(492.054,933.377) ; | 
| 1367 |     poly1 << QPointF(492.054,932.628) ; | 
| 1368 |     poly1 << QPointF(492.798,929.217) ; | 
| 1369 |     poly1 << QPointF(493.174,928.217) ; | 
| 1370 |     poly1 << QPointF(493.005,927.514) ; | 
| 1371 |     poly1 << QPointF(492.923,926.719) ; | 
| 1372 |     poly1 << QPointF(493.295,921.44) ; | 
| 1373 |     poly1 << QPointF(493.421,919.771) ; | 
| 1374 |     poly1 << QPointF(493.628,914.492) ; | 
| 1375 |     poly1 << QPointF(493.71,913.158) ; | 
| 1376 |     poly1 << QPointF(493.961,910.831) ; | 
| 1377 |     poly1 << QPointF(494.623,909.247) ; | 
| 1378 |     poly1 << QPointF(495.41,906.085) ; | 
| 1379 |     poly1 << QPointF(495.203,905.421) ; | 
| 1380 |     poly1 << QPointF(494.788,904.632) ; | 
| 1381 |     poly1 << QPointF(494.705,904.297) ; | 
| 1382 |     poly1 << QPointF(494.788,903.797) ; | 
| 1383 |     poly1 << QPointF(495.121,902.844) ; | 
| 1384 |     poly1 << QPointF(495.493,902.055) ; | 
| 1385 |     poly1 << QPointF(496.033,900.556) ; | 
| 1386 |     poly1 << QPointF(496.28,900.096) ; | 
| 1387 |     poly1 << QPointF(496.488,899.222) ; | 
| 1388 |     poly1 << QPointF(496.28,898.723) ; | 
| 1389 |     poly1 << QPointF(495.41,898.098) ; | 
| 1390 |     poly1 << QPointF(494.326,898.084) ; | 
| 1391 |     poly1 << QPointF(493.993,897.42) ; | 
| 1392 |     poly1 << QPointF(493.829,896.67) ; | 
| 1393 |     poly1 << QPointF(493.621,894.962) ; | 
| 1394 |     poly1 << QPointF(493.565,893.93) ; | 
| 1395 |     poly1 << QPointF(494.416,893.358) ; | 
| 1396 |     poly1 << QPointF(501.666,887.435) ; | 
| 1397 |     poly1 << QPointF(513.305,877.908) ; | 
| 1398 |     poly1 << QPointF(523.795,869.356) ; | 
| 1399 |     poly1 << QPointF(603.378,804.221) ; | 
| 1400 |     poly1 << QPointF(618.764,791.762) ; | 
| 1401 |     poly1 << QPointF(618.981,791.584) ; | 
| 1402 |     poly1 << QPointF(634.696,778.743) ; | 
| 1403 |     poly1 << QPointF(673.531,747.007) ; | 
| 1404 |     poly1 << QPointF(726.115,704.031) ; | 
| 1405 |     poly1 << QPointF(759.04,677.12) ; | 
| 1406 |     poly1 << QPointF(759.672,676.62) ; | 
| 1407 |     poly1 << QPointF(778.846,660.773) ; | 
| 1408 |     poly1 << QPointF(789.919,651.709) ; | 
| 1409 |     poly1 << QPointF(810.528,634.696) ; | 
| 1410 |     poly1 << QPointF(810.804,634.468) ; | 
| 1411 |     poly1 << QPointF(818.197,628.365) ; | 
| 1412 |     poly1 << QPointF(826.44,621.505) ; | 
| 1413 |     poly1 << QPointF(832.634,616.351) ; | 
| 1414 |     poly1 << QPointF(835.337,614.05) ; | 
| 1415 |     poly1 << QPointF(835.492,613.931) ; | 
| 1416 |     poly1 << QPointF(852.079,600.176) ; | 
| 1417 |     poly1 << QPointF(860.469,593.219) ; | 
| 1418 |     poly1 << QPointF(869.883,585.411) ; | 
| 1419 |     poly1 << QPointF(896.749,563.131) ; | 
| 1420 |     poly1 << QPointF(922.094,542.111) ; | 
| 1421 |     poly1 << QPointF(936.469,530.189) ; | 
| 1422 |     poly1 << QPointF(990.034,485.759) ; | 
| 1423 |     poly1 << QPointF(1001.65,476.123) ; | 
| 1424 |     poly1 << QPointF(1010.87,468.472) ; | 
| 1425 |     poly1 << QPointF(1028.6,453.769) ; | 
| 1426 |     poly1 << QPointF(1095.89,397.341) ; | 
| 1427 |     poly1 << QPointF(1130.52,368.297) ; | 
| 1428 |     poly1 << QPointF(1135.05,364.497) ; | 
| 1429 |     poly1 << QPointF(1123.55,337.582) ; | 
| 1430 |     poly1 << QPointF(1103.42,290.476) ; | 
| 1431 |     poly1 << QPointF(1095.21,271.259) ; | 
| 1432 |     poly1 << QPointF(1068.04,207.66) ; | 
| 1433 |     poly1 << QPointF(1051.62,169.118) ; | 
| 1434 |     poly1 << QPointF(1038.65,138.708) ; | 
| 1435 |     poly1 << QPointF(1027.81,113.269) ; | 
| 1436 |     poly1 << QPointF(1020.97,97.2145) ; | 
| 1437 |     poly1 << QPointF(1010.84,73.4644) ; | 
| 1438 |     poly1 << QPointF(988.424,20.9198) ; | 
| 1439 |     poly1 << QPointF(968.442,-25.9307) ; | 
| 1440 |     poly1 << QPointF(964.63,-34.8693) ; | 
| 1441 |     poly1 << QPointF(961.883,-41.3111) ; | 
| 1442 |     poly1 << QPointF(953.157,-61.929) ; | 
| 1443 |     poly1 << QPointF(949.712,-70.0717) ; | 
| 1444 |     poly1 << QPointF(946.048,-78.7331) ; | 
| 1445 |     poly1 << QPointF(945.789,-79.3443) ; | 
| 1446 |     poly1 << QPointF(945.548,-79.9146) ; | 
| 1447 |     poly1 << QPointF(941.671,-89.0782) ; | 
| 1448 |     poly1 << QPointF(940.408,-92.0616) ; | 
| 1449 |     poly1 << QPointF(940.095,-92.8021) ; | 
| 1450 |     poly1 << QPointF(938.65,-97.1094) ; | 
| 1451 |     poly1 << QPointF(934.565,-106.581) ; | 
| 1452 |     poly1 << QPointF(928.429,-121.542) ; | 
| 1453 |     poly1 << QPointF(928.24,-122.003) ; | 
| 1454 |     poly1 << QPointF(920.902,-139.241) ; | 
| 1455 |     poly1 << QPointF(910.85,-162.115) ; | 
| 1456 |     poly1 << QPointF(910.744,-162.357) ; | 
| 1457 |     poly1 << QPointF(900.875,-186.271) ; | 
| 1458 |     poly1 << QPointF(889.416,-213.089) ; | 
| 1459 |     poly1 << QPointF(883.705,-226.225) ; | 
| 1460 |     poly1 << QPointF(882.788,-228.422) ; | 
| 1461 |     poly1 << QPointF(881.399,-231.753) ; | 
| 1462 |     poly1 << QPointF(880.373,-234.213) ; | 
| 1463 |     poly1 << QPointF(875.788,-245.204) ; | 
| 1464 |     poly1 << QPointF(872.772,-252.085) ; | 
| 1465 |     poly1 << QPointF(869.686,-259.126) ; | 
| 1466 |     poly1 << QPointF(865.607,-268.43) ; | 
| 1467 |     poly1 << QPointF(868.74,-269.605) ; | 
| 1468 |     poly1 << QPointF(869.315,-269.834) ; | 
| 1469 |     poly1 << QPointF(879.443,-273.853) ; | 
| 1470 |     poly1 << QPointF(880.259,-274.217) ; | 
| 1471 |     poly1 << QPointF(888.958,-278.09) ; | 
| 1472 |     poly1 << QPointF(894.204,-280.426) ; | 
| 1473 |     poly1 << QPointF(902.866,-284.423) ; | 
| 1474 |     poly1 << QPointF(913.804,-289.072) ; | 
| 1475 |     poly1 << QPointF(917.975,-290.846) ; | 
| 1476 |     poly1 << QPointF(921.854,-292.375) ; | 
| 1477 |     poly1 << QPointF(930.52,-295.793) ; | 
| 1478 |     poly1 << QPointF(939.972,-299.79) ; | 
| 1479 |     poly1 << QPointF(940.899,-300.183) ; | 
| 1480 |     poly1 << QPointF(943.262,-294.709) ; | 
| 1481 |     poly1 << QPointF(946.922,-286.233) ; | 
| 1482 |     poly1 << QPointF(952.358,-273.643) ; | 
| 1483 |     poly1 << QPointF(959.976,-256) ; | 
| 1484 |     poly1 << QPointF(975.219,-220.296) ; | 
| 1485 |     poly1 << QPointF(988.991,-188.494) ; | 
| 1486 |     poly1 << QPointF(990.089,-185.959) ; | 
| 1487 |     poly1 << QPointF(1001.86,-158.88) ; | 
| 1488 |     poly1 << QPointF(1003.8,-154.245) ; | 
| 1489 |     poly1 << QPointF(1011.55,-135.749) ; | 
| 1490 |     poly1 << QPointF(1012.2,-134.199) ; | 
| 1491 |     poly1 << QPointF(1012.77,-132.837) ; | 
| 1492 |     poly1 << QPointF(1015.9,-125.529) ; | 
| 1493 |     poly1 << QPointF(1015.99,-125.305) ; | 
| 1494 |     poly1 << QPointF(1016.42,-124.299) ; | 
| 1495 |     poly1 << QPointF(1018.02,-120.569) ; | 
| 1496 |     poly1 << QPointF(1018.47,-119.395) ; | 
| 1497 |     poly1 << QPointF(1028.09,-97.0593) ; | 
| 1498 |     poly1 << QPointF(1028.89,-95.1902) ; | 
| 1499 |     poly1 << QPointF(1032.85,-85.957) ; | 
| 1500 |     poly1 << QPointF(1044.48,-58.8103) ; | 
| 1501 |     poly1 << QPointF(1047.23,-52.3933) ; | 
| 1502 |     poly1 << QPointF(1076.35,15.5527) ; | 
| 1503 |     poly1 << QPointF(1089.43,46.0648) ; | 
| 1504 |     poly1 << QPointF(1105.35,83.1913) ; | 
| 1505 |     poly1 << QPointF(1120.01,117.391) ; | 
| 1506 |     poly1 << QPointF(1131.66,144.66) ; | 
| 1507 |     poly1 << QPointF(1142.1,169.072) ; | 
| 1508 |     poly1 << QPointF(1183.42,265.698) ; | 
| 1509 |     poly1 << QPointF(1200.9,306.583) ; | 
| 1510 |     poly1 << QPointF(1208.48,324.306) ; | 
| 1511 |     poly1 << QPointF(1231.19,377.389) ; | 
| 1512 |     poly1 << QPointF(1241.55,400.064) ; | 
| 1513 |     poly1 << QPointF(1139.56,485.759) ; | 
| 1514 |     poly1 << QPointF(1104.96,514.822) ; | 
| 1515 |     poly1 << QPointF(1044.32,565.761) ; | 
| 1516 |     poly1 << QPointF(1020.92,585.411) ; | 
| 1517 |     poly1 << QPointF(1013.72,591.462) ; | 
| 1518 |     poly1 << QPointF(1012.73,592.285) ; | 
| 1519 |     poly1 << QPointF(926.449,663.776) ; | 
| 1520 |     poly1 << QPointF(843.981,732.099) ; | 
| 1521 |     poly1 << QPointF(826.923,746.23) ; | 
| 1522 |     poly1 << QPointF(810.856,759.539) ; | 
| 1523 |     poly1 << QPointF(736.788,820.887) ; | 
| 1524 |     poly1 << QPointF(709.695,843.348) ; | 
| 1525 |     poly1 << QPointF(693.265,856.967) ; | 
| 1526 |     poly1 << QPointF(690.228,859.484) ; | 
| 1527 |     poly1 << QPointF(673.813,873.091) ; | 
| 1528 |     poly1 << QPointF(672.34,874.317) ; | 
| 1529 |     poly1 << QPointF(618.453,919.164) ; | 
| 1530 |     poly1 << QPointF(607.821,928.011) ; | 
| 1531 |     poly1 << QPointF(596.057,937.538) ; | 
| 1532 |     poly1 << QPointF(580.774,950.204) ; | 
| 1533 |     poly1 << QPointF(573.229,956.457) ; | 
| 1534 |     poly1 << QPointF(533.091,989.719) ; | 
| 1535 |     poly1 << QPointF(513.657,1005.86) ; | 
| 1536 |     poly1 << QPointF(508.331,1010.23) ; | 
| 1537 |  | 
| 1538 |     poly2 << QPointF(941.306,435.236) ; | 
| 1539 |     poly2 << QPointF(983.306,435.236) ; | 
| 1540 |     poly2 << QPointF(983.306,473.236) ; | 
| 1541 |     poly2 << QPointF(941.306,473.236) ; | 
| 1542 |     poly2 << QPointF(941.306,435.236) ; | 
| 1543 |  | 
| 1544 |     QPainterPath path1, path2; | 
| 1545 |     path1.addPolygon(polygon: poly1); | 
| 1546 |     path2.addPolygon(polygon: poly2); | 
| 1547 |  | 
| 1548 |     QVERIFY(!path1.intersects(path2)); | 
| 1549 |     QVERIFY(path1.intersected(path2).isEmpty()); | 
| 1550 | } | 
| 1551 |  | 
| 1552 | QTEST_MAIN(tst_QPathClipper) | 
| 1553 |  | 
| 1554 |  | 
| 1555 | #include "tst_qpathclipper.moc" | 
| 1556 |  |