| 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 | #include <qregion.h> | 
| 32 |  | 
| 33 | #include <qbitmap.h> | 
| 34 | #include <qpainter.h> | 
| 35 | #include <qpainterpath.h> | 
| 36 | #include <qpolygon.h> | 
| 37 |  | 
| 38 | class tst_QRegion : public QObject | 
| 39 | { | 
| 40 |     Q_OBJECT | 
| 41 |  | 
| 42 | public: | 
| 43 |     tst_QRegion(); | 
| 44 |  | 
| 45 | private slots: | 
| 46 |     void moveSemantics(); | 
| 47 |     void boundingRect(); | 
| 48 |     void rangeFor(); | 
| 49 |     void rects(); | 
| 50 |     void swap(); | 
| 51 |     void setRects(); | 
| 52 |     void ellipseRegion(); | 
| 53 |     void polygonRegion(); | 
| 54 |     void bitmapRegion(); | 
| 55 |     void intersected_data(); | 
| 56 |     void intersected(); | 
| 57 |     void emptyPolygonRegion_data(); | 
| 58 |     void emptyPolygonRegion(); | 
| 59 |  | 
| 60 |     void intersects_region_data(); | 
| 61 |     void intersects_region(); | 
| 62 |     void intersects_rect_data(); | 
| 63 |     void intersects_rect(); | 
| 64 |     void contains_point(); | 
| 65 |  | 
| 66 |     void operator_plus_data(); | 
| 67 |     void operator_plus(); | 
| 68 |     void operator_minus_data(); | 
| 69 |     void operator_minus(); | 
| 70 |     void operator_intersect_data(); | 
| 71 |     void operator_intersect(); | 
| 72 |     void operator_xor_data(); | 
| 73 |     void operator_xor(); | 
| 74 |  | 
| 75 |     void rectCount_data(); | 
| 76 |     void rectCount(); | 
| 77 |  | 
| 78 |     void isEmpty_data(); | 
| 79 |     void isEmpty(); | 
| 80 |  | 
| 81 |     void regionFromPath(); | 
| 82 |     void scaleRegions_data(); | 
| 83 |     void scaleRegions(); | 
| 84 |  | 
| 85 | #ifdef QT_BUILD_INTERNAL | 
| 86 |     void regionToPath_data(); | 
| 87 |     void regionToPath(); | 
| 88 | #endif | 
| 89 | }; | 
| 90 |  | 
| 91 | tst_QRegion::tst_QRegion() | 
| 92 | { | 
| 93 | } | 
| 94 |  | 
| 95 | void tst_QRegion::moveSemantics() | 
| 96 | { | 
| 97 |     const QRegion rect(QRect(0, 0, 100, 100)); | 
| 98 |  | 
| 99 |     // move assignment | 
| 100 |     { | 
| 101 |         QRegion r1 = rect; | 
| 102 |         QRegion r2; | 
| 103 |         r2 = std::move(r1); | 
| 104 |         QVERIFY(r1.isNull()); | 
| 105 |         QCOMPARE(r2, rect); | 
| 106 |     } | 
| 107 |  | 
| 108 |     // move construction | 
| 109 |     { | 
| 110 |         QRegion r1 = rect; | 
| 111 |         QRegion r2 = std::move(r1); | 
| 112 |         QVERIFY(r1.isNull()); | 
| 113 |         QCOMPARE(r2, rect); | 
| 114 |     } | 
| 115 | } | 
| 116 |  | 
| 117 | void tst_QRegion::boundingRect() | 
| 118 | { | 
| 119 |     { | 
| 120 |         QRect rect; | 
| 121 |         QRegion region(rect); | 
| 122 |         QCOMPARE(region.boundingRect(), rect); | 
| 123 |     } | 
| 124 |     { | 
| 125 |         QRect rect(10, -20, 30, 40); | 
| 126 |         QRegion region(rect); | 
| 127 |         QCOMPARE(region.boundingRect(), rect); | 
| 128 |     } | 
| 129 |     { | 
| 130 |         QRect rect(15,25,10,10); | 
| 131 |         QRegion region(rect); | 
| 132 |         QCOMPARE(region.boundingRect(), rect); | 
| 133 |     } | 
| 134 |  | 
| 135 | } | 
| 136 |  | 
| 137 | void tst_QRegion::rangeFor() | 
| 138 | { | 
| 139 |     // compile-only test for range-for over QRegion, so really useless | 
| 140 |     // content otherwise: | 
| 141 |     QRect rect(10, -20, 30, 40); | 
| 142 |     QRegion region(rect); | 
| 143 |     int equal = 0; | 
| 144 |     for (const QRect &r : region) // check this compiles | 
| 145 |         equal += int(r == rect); // can't use QCOMPARE here b/c of the | 
| 146 |                                  // MSVC 201272013 parse bug re: | 
| 147 |                                  // do-while in range-for loops | 
| 148 |     QCOMPARE(equal, 1); | 
| 149 | } | 
| 150 |  | 
| 151 | void tst_QRegion::rects() | 
| 152 | { | 
| 153 |     { | 
| 154 |         QRect rect; | 
| 155 |         QRegion region(rect); | 
| 156 |         QVERIFY(region.isEmpty()); | 
| 157 |         QCOMPARE(region.begin(), region.end()); | 
| 158 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 159 |         QVERIFY(region.rects().isEmpty()); | 
| 160 | #endif | 
| 161 |     } | 
| 162 |     { | 
| 163 |         QRect rect(10, -20, 30, 40); | 
| 164 |         QRegion region(rect); | 
| 165 |         QCOMPARE(region.end(), region.begin() + 1); | 
| 166 |         QCOMPARE(*region.begin(), rect); | 
| 167 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 168 |         QCOMPARE(region.rects().count(), 1); | 
| 169 |         QCOMPARE(region.rects()[0], rect); | 
| 170 | #endif | 
| 171 |     } | 
| 172 |     { | 
| 173 |         QRect r(QPoint(10, 10), QPoint(40, 40)); | 
| 174 |         QRegion region(r); | 
| 175 |         QVERIFY(region.contains(QPoint(10,10))); | 
| 176 |         QVERIFY(region.contains(QPoint(20,40))); | 
| 177 |         QVERIFY(region.contains(QPoint(40,20))); | 
| 178 |         QVERIFY(!region.contains(QPoint(20,41))); | 
| 179 |         QVERIFY(!region.contains(QPoint(41,20))); | 
| 180 |     } | 
| 181 |     { | 
| 182 |         QRect r(10, 10, 30, 30); | 
| 183 |         QRegion region(r); | 
| 184 |         QVERIFY(region.contains(QPoint(10,10))); | 
| 185 |         QVERIFY(region.contains(QPoint(20,39))); | 
| 186 |         QVERIFY(region.contains(QPoint(39,20))); | 
| 187 |         QVERIFY(!region.contains(QPoint(20,40))); | 
| 188 |         QVERIFY(!region.contains(QPoint(40,20))); | 
| 189 |     } | 
| 190 | } | 
| 191 |  | 
| 192 | void tst_QRegion::swap() | 
| 193 | { | 
| 194 |     QRegion r1(QRect(0, 0,10,10)); | 
| 195 |     QRegion r2(QRect(10,10,10,10)); | 
| 196 |     r1.swap(other&: r2); | 
| 197 |     QCOMPARE(*r1.begin(), QRect(10,10,10,10)); | 
| 198 |     QCOMPARE(*r2.begin(), QRect(0, 0,10,10)); | 
| 199 | } | 
| 200 |  | 
| 201 | void tst_QRegion::setRects() | 
| 202 | { | 
| 203 |     { | 
| 204 |         QRegion region; | 
| 205 |         region.setRects(rect: 0, num: 0); | 
| 206 |         QVERIFY(region.isEmpty()); | 
| 207 |         QCOMPARE(region.begin(), region.end()); | 
| 208 |     } | 
| 209 |     { | 
| 210 |         QRegion region; | 
| 211 |         QRect rect; | 
| 212 |         region.setRects(rect: &rect, num: 0); | 
| 213 |         QVERIFY(region.isEmpty()); | 
| 214 |         QCOMPARE(region, QRegion()); | 
| 215 |         QCOMPARE(region.begin(), region.end()); | 
| 216 |         QVERIFY(!region.boundingRect().isValid()); | 
| 217 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 218 |         QVERIFY(region.rects().isEmpty()); | 
| 219 | #endif | 
| 220 |     } | 
| 221 |     { | 
| 222 |         QRegion region; | 
| 223 |         QRect rect; | 
| 224 |         region.setRects(rect: &rect, num: 1); | 
| 225 |         QCOMPARE(region.begin(), region.end()); | 
| 226 |         QVERIFY(!region.boundingRect().isValid()); | 
| 227 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 228 |         QVERIFY(region.rects().isEmpty()); | 
| 229 | #endif | 
| 230 |     } | 
| 231 |     { | 
| 232 |         QRegion region; | 
| 233 |         QRect rect(10, -20, 30, 40); | 
| 234 |         region.setRects(rect: &rect, num: 1); | 
| 235 |         QCOMPARE(region.end(), region.begin() + 1); | 
| 236 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 237 |         QCOMPARE(region.rects().count(), 1); | 
| 238 |         QCOMPARE(region.rects()[0], rect); | 
| 239 | #endif | 
| 240 |         QCOMPARE(*region.begin(), rect); | 
| 241 |     } | 
| 242 | } | 
| 243 |  | 
| 244 | void tst_QRegion::ellipseRegion() | 
| 245 | { | 
| 246 |     QRegion region(0, 0, 100, 100, QRegion::Ellipse); | 
| 247 |  | 
| 248 |     // These should not be inside the circe | 
| 249 |     QVERIFY(!region.contains(QPoint(13, 13))); | 
| 250 |     QVERIFY(!region.contains(QPoint(13, 86))); | 
| 251 |     QVERIFY(!region.contains(QPoint(86, 13))); | 
| 252 |     QVERIFY(!region.contains(QPoint(86, 86))); | 
| 253 |  | 
| 254 |     // These should be inside | 
| 255 |     QVERIFY(region.contains(QPoint(16, 16))); | 
| 256 |     QVERIFY(region.contains(QPoint(16, 83))); | 
| 257 |     QVERIFY(region.contains(QPoint(83, 16))); | 
| 258 |     QVERIFY(region.contains(QPoint(83, 83))); | 
| 259 |  | 
| 260 |     //     ..a.. | 
| 261 |     //   ..     .. | 
| 262 |     //  .         . | 
| 263 |     // .           . | 
| 264 |     // b           c | 
| 265 |     // .           . | 
| 266 |     //  .         . | 
| 267 |     //   ..     .. | 
| 268 |     //     ..d.. | 
| 269 |     QVERIFY(region.contains(QPoint(50, 0)));   // Mid-top    (a) | 
| 270 |     QVERIFY(region.contains(QPoint(0, 50)));   // Mid-left   (b) | 
| 271 |     QVERIFY(region.contains(QPoint(99, 50)));  // Mid-right  (c) | 
| 272 |     QVERIFY(region.contains(QPoint(50, 99)));  // Mid-bottom (d) | 
| 273 |  | 
| 274 |     QRect bounds = region.boundingRect(); | 
| 275 |     QCOMPARE(bounds.x(), 0); | 
| 276 |     QCOMPARE(bounds.y(), 0); | 
| 277 |     QCOMPARE(bounds.width(), 100); | 
| 278 |     QCOMPARE(bounds.height(), 100); | 
| 279 | } | 
| 280 |  | 
| 281 | void tst_QRegion::polygonRegion() | 
| 282 | { | 
| 283 |     QPolygon pa; | 
| 284 |     { | 
| 285 |         QRegion region (pa); | 
| 286 |         QVERIFY(region.isEmpty()); | 
| 287 |     } | 
| 288 |     { | 
| 289 |         pa.setPoints(nPoints: 8, firstx: 10, firsty: 10, //  a____________b | 
| 290 |                         40, 10, //  |            | | 
| 291 |                         40, 20, //  |___      ___| | 
| 292 |                         30, 20, //      |    | | 
| 293 |                         30, 40, //      |    | | 
| 294 |                         20, 40, //      |    | | 
| 295 |                         20, 20, //      |____c | 
| 296 |                         10, 20); | 
| 297 |  | 
| 298 |         QRegion region (pa); | 
| 299 |         QVERIFY(!region.isEmpty()); | 
| 300 |  | 
| 301 |         // These should not be inside the circle | 
| 302 |         QVERIFY(!region.contains(QPoint( 9,  9))); | 
| 303 |         QVERIFY(!region.contains(QPoint(30, 41))); | 
| 304 |         QVERIFY(!region.contains(QPoint(41, 10))); | 
| 305 |         QVERIFY(!region.contains(QPoint(31, 21))); | 
| 306 |  | 
| 307 |         // These should be inside | 
| 308 |         QVERIFY(region.contains(QPoint(10, 10))); // Upper-left  (a) | 
| 309 |  | 
| 310 |     } | 
| 311 | } | 
| 312 |  | 
| 313 | void tst_QRegion::emptyPolygonRegion_data() | 
| 314 | { | 
| 315 |     QTest::addColumn<QPolygon>(name: "pa" ); | 
| 316 |     QTest::addColumn<bool>(name: "isEmpty" ); | 
| 317 |     QTest::addColumn<int>(name: "numRects" ); | 
| 318 |     QTest::addColumn<QVector<QRect> >(name: "rects" ); | 
| 319 |  | 
| 320 |     QPolygon pa; | 
| 321 |  | 
| 322 |  | 
| 323 |     QTest::newRow(dataTag: "no points" ) << pa << true << 0 << QVector<QRect>(); | 
| 324 |     pa = QPolygon() << QPoint(10,10); | 
| 325 |     QTest::newRow(dataTag: "one point" ) << pa << true << 0 << QVector<QRect>(); | 
| 326 |     pa = QPolygon() << QPoint(10,10) << QPoint(10,20); | 
| 327 |     QTest::newRow(dataTag: "two points, horizontal" ) << pa << true << 0 << QVector<QRect>(); | 
| 328 |  | 
| 329 |     pa = QPolygon() << QPoint(10,10) << QPoint(20,10); | 
| 330 |     QTest::newRow(dataTag: "two points, vertical" ) << pa << true << 0 << QVector<QRect>(); | 
| 331 |  | 
| 332 |     pa = QPolygon() << QPoint(10,10) << QPoint(20,20); | 
| 333 |     QTest::newRow(dataTag: "two points, diagonal" ) << pa << true << 0 << QVector<QRect>(); | 
| 334 |  | 
| 335 |     pa = QPolygon() << QPoint(10,10) << QPoint(15,15) << QPoint(10,15) << QPoint(10, 10) ; | 
| 336 |     QVector<QRect> v; | 
| 337 |     v << QRect(10,11,1, 1) << QRect(10,12,2,1) << QRect(10,13,3,1) << QRect(10,14,4,1); | 
| 338 |     QTest::newRow(dataTag: "triangle" ) << pa << false << 4 << v; | 
| 339 |  | 
| 340 |     v.clear(); | 
| 341 |     v << QRect(10,10,10,10); | 
| 342 |  | 
| 343 |     QTest::newRow(dataTag: "rectangle" ) << QPolygon(QRect(10,10,10,10))  << false << 1 << v; | 
| 344 |  | 
| 345 | } | 
| 346 |  | 
| 347 | void tst_QRegion::emptyPolygonRegion() | 
| 348 | { | 
| 349 |     QFETCH(QPolygon, pa); | 
| 350 |  | 
| 351 |     QRegion r(pa); | 
| 352 |     QTEST(r.isEmpty(), "isEmpty" ); | 
| 353 |     QTEST(int(std::distance(r.begin(), r.end())), "numRects" ); | 
| 354 |     QVector<QRect> rects; | 
| 355 |     std::copy(first: r.begin(), last: r.end(), result: std::back_inserter(x&: rects)); | 
| 356 |     QTEST(rects.size(), "numRects" ); | 
| 357 |     QTEST(rects, "rects" ); | 
| 358 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 359 |     QCOMPARE(r.rects(), rects); | 
| 360 | #endif | 
| 361 | } | 
| 362 |  | 
| 363 |  | 
| 364 | static const char *circle_xpm[] = { | 
| 365 |     "20 20 2 1" , | 
| 366 |     "  c #FFFFFF" , | 
| 367 |     ". c #000000" , | 
| 368 |     "       ......       " , | 
| 369 |     "     ..........     " , | 
| 370 |     "   ..............   " , | 
| 371 |     "  ................  " , | 
| 372 |     "  ................  " , | 
| 373 |     " .................. " , | 
| 374 |     " .................. " , | 
| 375 |     "...................." , | 
| 376 |     "...................." , | 
| 377 |     "...................." , | 
| 378 |     "...................." , | 
| 379 |     "...................." , | 
| 380 |     "...................." , | 
| 381 |     " .................. " , | 
| 382 |     " .................. " , | 
| 383 |     "  ................  " , | 
| 384 |     "  ................  " , | 
| 385 |     "   ..............   " , | 
| 386 |     "     ..........     " , | 
| 387 |     "       ......       "  | 
| 388 | }; | 
| 389 |  | 
| 390 | void tst_QRegion::bitmapRegion() | 
| 391 | { | 
| 392 |     QBitmap circle; | 
| 393 |     { | 
| 394 |         QRegion region(circle); | 
| 395 |         QVERIFY(region.isEmpty()); | 
| 396 |     } | 
| 397 |     { | 
| 398 |         circle = QPixmap(circle_xpm); | 
| 399 |         QRegion region(circle); | 
| 400 |  | 
| 401 |         //// These should not be inside the circe | 
| 402 |         QVERIFY(!region.contains(QPoint(2,   2))); | 
| 403 |         QVERIFY(!region.contains(QPoint(2,  17))); | 
| 404 |         QVERIFY(!region.contains(QPoint(17,  2))); | 
| 405 |         QVERIFY(!region.contains(QPoint(17, 17))); | 
| 406 |  | 
| 407 |         //// These should be inside | 
| 408 |         QVERIFY(region.contains(QPoint(3,   3))); | 
| 409 |         QVERIFY(region.contains(QPoint(3,  16))); | 
| 410 |         QVERIFY(region.contains(QPoint(16,  3))); | 
| 411 |         QVERIFY(region.contains(QPoint(16, 16))); | 
| 412 |  | 
| 413 |         QVERIFY(region.contains(QPoint(0, 10)));  // Mid-left | 
| 414 |         QVERIFY(region.contains(QPoint(10, 0)));  // Mid-top | 
| 415 |         QVERIFY(region.contains(QPoint(19, 10))); // Mid-right | 
| 416 |         QVERIFY(region.contains(QPoint(10, 19))); // Mid-bottom | 
| 417 |     } | 
| 418 | } | 
| 419 |  | 
| 420 | void tst_QRegion::intersected_data() | 
| 421 | { | 
| 422 |     QTest::addColumn<QRegion>(name: "r1" ); | 
| 423 |     QTest::addColumn<QRegion>(name: "r2" ); | 
| 424 |     QTest::addColumn<bool>(name: "intersects" ); | 
| 425 |     // QTest::addColumn<QRegion>("intersected"); | 
| 426 |  | 
| 427 |     QPolygon ps1(8); | 
| 428 |     QPolygon ps2(8); | 
| 429 |     ps1.putPoints(index: 0,nPoints: 8, firstx: 20,firsty: 20, 50,20, 50,100, 70,100, 70,20, 120,20, 120,200, 20, 200); | 
| 430 |     ps2.putPoints(index: 0,nPoints: 8, firstx: 100,firsty: 150, 140,150, 140,160, 160,160, 160,150, 200,150, 200,180, 100,180); | 
| 431 |     QTest::newRow(dataTag: "task30716" ) << QRegion(ps1) << QRegion(ps2) << true; | 
| 432 | } | 
| 433 |  | 
| 434 | void tst_QRegion::intersected() | 
| 435 | { | 
| 436 |     QFETCH(QRegion, r1); | 
| 437 |     QFETCH(QRegion, r2); | 
| 438 |     QFETCH(bool, intersects); | 
| 439 |  | 
| 440 |     QRegion interReg = r1.intersected(r: r2); | 
| 441 |     QVERIFY(interReg.isEmpty() != intersects); | 
| 442 |     // Need a way to test the intersected QRegion is right | 
| 443 | } | 
| 444 |  | 
| 445 | void tst_QRegion::intersects_region_data() | 
| 446 | { | 
| 447 |     QTest::addColumn<QRegion>(name: "r1" ); | 
| 448 |     QTest::addColumn<QRegion>(name: "r2" ); | 
| 449 |     QTest::addColumn<bool>(name: "intersects" ); | 
| 450 |  | 
| 451 |     QTest::newRow(dataTag: "rect overlap rect" ) << QRegion(100, 100, 200, 200) | 
| 452 |                                        << QRegion(200, 200, 200, 200) | 
| 453 |                                        << true; | 
| 454 |  | 
| 455 |     QTest::newRow(dataTag: "rect not overlap rect" ) << QRegion(100, 100, 200, 200) | 
| 456 |                                            << QRegion(400, 400, 200, 200) | 
| 457 |                                            << false; | 
| 458 |  | 
| 459 |     QTest::newRow(dataTag: "ellipse overlap ellipse" ) << QRegion(100, 100, 200, 200, QRegion::Ellipse) | 
| 460 |                                              << QRegion(200, 200, 200, 200, QRegion::Ellipse) | 
| 461 |                                              << true; | 
| 462 |  | 
| 463 |     QTest::newRow(dataTag: "ellipse not overlap ellipse" ) << QRegion(100, 100, 200, 200, QRegion::Ellipse) | 
| 464 |                                                  << QRegion(400, 400, 200, 200, QRegion::Ellipse) | 
| 465 |                                                  << false; | 
| 466 | } | 
| 467 |  | 
| 468 | void tst_QRegion::intersects_region() | 
| 469 | { | 
| 470 |     QFETCH(QRegion, r1); | 
| 471 |     QFETCH(QRegion, r2); | 
| 472 |     QFETCH(bool, intersects); | 
| 473 |     QCOMPARE(r1.intersects(r2), intersects); | 
| 474 | } | 
| 475 |  | 
| 476 |  | 
| 477 | void tst_QRegion::intersects_rect_data() | 
| 478 | { | 
| 479 |     QTest::addColumn<QRegion>(name: "region" ); | 
| 480 |     QTest::addColumn<QRect>(name: "rect" ); | 
| 481 |     QTest::addColumn<bool>(name: "intersects" ); | 
| 482 |  | 
| 483 |     QTest::newRow(dataTag: "rect overlap rect" ) << QRegion(100, 100, 200, 200) | 
| 484 |                                        << QRect(200, 200, 200, 200) | 
| 485 |                                        << true; | 
| 486 |  | 
| 487 |     QTest::newRow(dataTag: "rect not overlap rect" ) << QRegion(100, 100, 200, 200) | 
| 488 |                                            << QRect(400, 400, 200, 200) | 
| 489 |                                            << false; | 
| 490 |  | 
| 491 |     QTest::newRow(dataTag: "ellipse overlap rect" ) << QRegion(100, 100, 200, 200, QRegion::Ellipse) | 
| 492 |                                           << QRect(200, 200, 200, 200) | 
| 493 |                                           << true; | 
| 494 |  | 
| 495 |     QTest::newRow(dataTag: "ellipse not overlap rect" ) << QRegion(100, 100, 200, 200, QRegion::Ellipse) | 
| 496 |                                               << QRect(400, 400, 200, 200) | 
| 497 |                                               << false; | 
| 498 | } | 
| 499 |  | 
| 500 | void tst_QRegion::intersects_rect() | 
| 501 | { | 
| 502 |     QFETCH(QRegion, region); | 
| 503 |     QFETCH(QRect, rect); | 
| 504 |     QFETCH(bool, intersects); | 
| 505 |     QCOMPARE(region.intersects(rect), intersects); | 
| 506 | } | 
| 507 |  | 
| 508 | void tst_QRegion::contains_point() | 
| 509 | { | 
| 510 |     QCOMPARE(QRegion().contains(QPoint(1,1)),false); | 
| 511 |     QCOMPARE(QRegion(0,0,2,2).contains(QPoint(1,1)),true); | 
| 512 | } | 
| 513 |  | 
| 514 | void tst_QRegion::operator_plus_data() | 
| 515 | { | 
| 516 |     QTest::addColumn<QRegion>(name: "r1" ); | 
| 517 |     QTest::addColumn<QRegion>(name: "r2" ); | 
| 518 |     QTest::addColumn<QRegion>(name: "expected" ); | 
| 519 |  | 
| 520 |     QTest::newRow(dataTag: "empty 0" ) << QRegion() << QRegion() << QRegion(); | 
| 521 |     QTest::newRow(dataTag: "empty 1" ) << QRegion() << QRegion(QRect(10, 10, 10, 10)) | 
| 522 |                              << QRegion(QRect(10, 10, 10, 10)); | 
| 523 |     QTest::newRow(dataTag: "empty 2" ) << QRegion(QRect(10, 10, 10, 10)) << QRegion() | 
| 524 |                              << QRegion(QRect(10, 10, 10, 10)); | 
| 525 |  | 
| 526 |     QRegion expected; | 
| 527 |     QVector<QRect> rects; | 
| 528 |     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10); | 
| 529 |     expected.setRects(rect: rects.constData(), num: rects.size()); | 
| 530 |     QTest::newRow(dataTag: "non overlapping" ) << QRegion(10, 10, 10, 10) | 
| 531 |                                      << QRegion(22, 10, 10, 10) | 
| 532 |                                      << expected; | 
| 533 |  | 
| 534 |     rects.clear(); | 
| 535 |     rects << QRect(50, 0, 50, 2); | 
| 536 |     expected.setRects(rect: rects.constData(), num: rects.size()); | 
| 537 |     QTest::newRow(dataTag: "adjacent y-rects" ) << QRegion(50, 0, 50, 1) | 
| 538 |                                       << QRegion(50, 1, 50, 1) | 
| 539 |                                       << expected; | 
| 540 |  | 
| 541 |     rects.clear(); | 
| 542 |     rects << QRect(50, 0, 2, 1); | 
| 543 |     expected.setRects(rect: rects.constData(), num: rects.size()); | 
| 544 |     QTest::newRow(dataTag: "adjacent x-rects" ) << QRegion(50, 0, 1, 1) | 
| 545 |                                       << QRegion(51, 0, 1, 1) | 
| 546 |                                       << expected; | 
| 547 |  | 
| 548 |     rects.clear(); | 
| 549 |     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 5, 10); | 
| 550 |     QRegion r1; | 
| 551 |     r1.setRects(rect: rects.constData(), num: rects.size()); | 
| 552 |     QTest::newRow(dataTag: "double merge" ) << r1 << QRegion(15, 20, 5, 10) | 
| 553 |                                   << QRegion(10, 10, 10, 20); | 
| 554 |     rects.clear(); | 
| 555 |     rects << QRect(15, 10, 5, 10) << QRect(10, 20, 10, 10); | 
| 556 |     r1.setRects(rect: rects.constData(), num: rects.size()); | 
| 557 |     QTest::newRow(dataTag: "double merge 2" ) << r1 << QRegion(10, 10, 5, 10) | 
| 558 |                                     << QRegion(10, 10, 10, 20); | 
| 559 |     QTest::newRow(dataTag: "overlapping x" ) << QRegion(10, 10, 10, 10) | 
| 560 |                                    << QRegion(15, 10, 10, 10) | 
| 561 |                                    << QRegion(10, 10, 15, 10); | 
| 562 |     QTest::newRow(dataTag: "overlapping y" ) << QRegion(10, 10, 10, 10) | 
| 563 |                                    << QRegion(10, 15, 10, 10) | 
| 564 |                                    << QRegion(10, 10, 10, 15); | 
| 565 |     rects.clear(); | 
| 566 |     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 5, 10); | 
| 567 |     r1.setRects(rect: rects.constData(), num: rects.size()); | 
| 568 |     rects.clear(); | 
| 569 |     rects << QRect(15, 20, 5, 10) << QRect(10, 30, 10, 10); | 
| 570 |     QRegion r2; | 
| 571 |     r2.setRects(rect: rects.constData(), num: rects.size()); | 
| 572 |     QTest::newRow(dataTag: "triple merge" ) << r1 << r2 | 
| 573 |                                   << QRegion(10, 10, 10, 30); | 
| 574 |  | 
| 575 |     rects.clear(); | 
| 576 |     rects << QRect(10, 10, 4, 10) << QRect(15, 10, 10, 10); | 
| 577 |     r1.setRects(rect: rects.constData(), num: rects.size()); | 
| 578 |     rects.clear(); | 
| 579 |     rects << QRect(15, 20, 10, 10); | 
| 580 |     r2.setRects(rect: rects.constData(), num: rects.size()); | 
| 581 |     rects.clear(); | 
| 582 |     rects << QRect(10, 10, 4, 10) << QRect(15, 10, 10, 10) | 
| 583 |           << QRect(15, 20, 10, 10); | 
| 584 |     expected.setRects(rect: rects.constData(), num: rects.size()); | 
| 585 |     QTest::newRow(dataTag: "don't merge y" ) << r1 << r2 << expected; | 
| 586 |  | 
| 587 |     QTest::newRow(dataTag: "equal 1" ) << QRegion(10, 10, 10, 10) | 
| 588 |                              << QRegion(10, 10, 10, 10) | 
| 589 |                              << QRegion(10, 10, 10, 10); | 
| 590 |     QTest::newRow(dataTag: "equal 2" ) << expected << expected << expected; | 
| 591 | } | 
| 592 |  | 
| 593 | void tst_QRegion::operator_plus() | 
| 594 | { | 
| 595 |     QFETCH(QRegion, r1); | 
| 596 |     QFETCH(QRegion, r2); | 
| 597 |     QFETCH(QRegion, expected); | 
| 598 |  | 
| 599 |     if (r1 + r2 != expected) { | 
| 600 |         qDebug() << "r1 + r2"  << (r1 + r2); | 
| 601 |         qDebug() << "expected"  << expected; | 
| 602 |     } | 
| 603 |     QCOMPARE(r1 + r2, expected); | 
| 604 |     if (r2.rectCount() == 1) { | 
| 605 |         if (r1 + r2.boundingRect() != expected) { | 
| 606 |             qDebug() << "r1 + QRect(r2)"  << (r1 + r2.boundingRect()); | 
| 607 |             qDebug() << "expected"  << expected; | 
| 608 |         } | 
| 609 |         QCOMPARE(r1 + r2.boundingRect(), expected); | 
| 610 |     } | 
| 611 |  | 
| 612 |     if (r2 + r1 != expected) { | 
| 613 |         qDebug() << "r2 + r1"  << (r2 + r1); | 
| 614 |         qDebug() << "expected"  << expected; | 
| 615 |     } | 
| 616 |     QCOMPARE(r2 + r1, expected); | 
| 617 |     if (r1.rectCount() == 1) { | 
| 618 |         if (r1 + r2.boundingRect() != expected) { | 
| 619 |             qDebug() << "r2 + QRect(r1)"  << (r2 + r1.boundingRect()); | 
| 620 |             qDebug() << "expected"  << expected; | 
| 621 |         } | 
| 622 |         QCOMPARE(r2 + r1.boundingRect(), expected); | 
| 623 |     } | 
| 624 |  | 
| 625 |     QRegion result1 = r1; | 
| 626 |     result1 += r2; | 
| 627 |     if (result1 != expected) { | 
| 628 |         qDebug() << "r1 += r2"  << result1; | 
| 629 |         qDebug() << "expected"  << expected; | 
| 630 |     } | 
| 631 |     QCOMPARE(result1, expected); | 
| 632 |     if (r2.rectCount() == 1) { | 
| 633 |         result1 = r1; | 
| 634 |         result1 += r2.boundingRect(); | 
| 635 |         if (result1 != expected) { | 
| 636 |             qDebug() << "r1 += QRect(r2)"  << result1; | 
| 637 |             qDebug() << "expected"  << expected; | 
| 638 |         } | 
| 639 |         QCOMPARE(result1, expected); | 
| 640 |     } | 
| 641 |  | 
| 642 |     QRegion result2 = r2; | 
| 643 |     result2 += r1; | 
| 644 |     if (result2 != expected) { | 
| 645 |         qDebug() << "r2 += r1"  << result2; | 
| 646 |         qDebug() << "expected"  << expected; | 
| 647 |     } | 
| 648 |     QCOMPARE(result2, expected); | 
| 649 |     if (r1.rectCount() == 1) { | 
| 650 |         result2 = r2; | 
| 651 |         result2 += r1.boundingRect(); | 
| 652 |         if (result2 != expected) { | 
| 653 |             qDebug() << "r2 += QRect(r1)"  << result2; | 
| 654 |             qDebug() << "expected"  << expected; | 
| 655 |         } | 
| 656 |         QCOMPARE(result2, expected); | 
| 657 |     } | 
| 658 | } | 
| 659 |  | 
| 660 | void tst_QRegion::operator_minus_data() | 
| 661 | { | 
| 662 |     QTest::addColumn<QRegion>(name: "dest" ); | 
| 663 |     QTest::addColumn<QRegion>(name: "subtract" ); | 
| 664 |     QTest::addColumn<QRegion>(name: "expected" ); | 
| 665 |  | 
| 666 |     QTest::newRow(dataTag: "empty 0" ) << QRegion() << QRegion() << QRegion(); | 
| 667 |     QTest::newRow(dataTag: "empty 1" ) << QRegion() << QRegion(QRect(10, 10, 10, 10)) | 
| 668 |                              << QRegion(); | 
| 669 |     QTest::newRow(dataTag: "empty 2" ) << QRegion(QRect(10, 10, 10, 10)) << QRegion() | 
| 670 |                              << QRegion(QRect(10, 10, 10, 10)); | 
| 671 |  | 
| 672 |     QRegion dest; | 
| 673 |     QVector<QRect> rects; | 
| 674 |     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10); | 
| 675 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 676 |     QTest::newRow(dataTag: "simple 1" ) << dest | 
| 677 |                               << QRegion(22, 10, 10, 10) | 
| 678 |                               << QRegion(10, 10, 10, 10); | 
| 679 |     QTest::newRow(dataTag: "simple 2" ) << dest | 
| 680 |                               << QRegion(10, 10, 10, 10) | 
| 681 |                               << QRegion(22, 10, 10, 10); | 
| 682 |  | 
| 683 |     rects.clear(); | 
| 684 |     rects << QRect(0, 0, 10, 10) << QRect(15, 0, 10, 10); | 
| 685 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 686 |  | 
| 687 |     QRegion minus; | 
| 688 |     rects.clear(); | 
| 689 |     rects << QRect(0, 0, 12, 12) << QRect(15, 0, 12, 12); | 
| 690 |     minus.setRects(rect: rects.constData(), num: rects.size()); | 
| 691 |     QTest::newRow(dataTag: "empty 3" ) << dest << minus << QRegion(); | 
| 692 | } | 
| 693 |  | 
| 694 | void tst_QRegion::operator_minus() | 
| 695 | { | 
| 696 |     QFETCH(QRegion, dest); | 
| 697 |     QFETCH(QRegion, subtract); | 
| 698 |     QFETCH(QRegion, expected); | 
| 699 |  | 
| 700 |     if (dest - subtract != expected) { | 
| 701 |         qDebug() << "dest - subtract"  << (dest - subtract); | 
| 702 |         qDebug() << "expected"  << expected; | 
| 703 |     }; | 
| 704 |     QCOMPARE(dest - subtract, expected); | 
| 705 |  | 
| 706 |     dest -= subtract; | 
| 707 |  | 
| 708 |     if (dest != expected) { | 
| 709 |         qDebug() << "dest"  << dest; | 
| 710 |         qDebug() << "expected"  << expected; | 
| 711 |     }; | 
| 712 |     QCOMPARE(dest, expected); | 
| 713 | } | 
| 714 |  | 
| 715 | void tst_QRegion::operator_intersect_data() | 
| 716 | { | 
| 717 |     QTest::addColumn<QRegion>(name: "r1" ); | 
| 718 |     QTest::addColumn<QRegion>(name: "r2" ); | 
| 719 |     QTest::addColumn<QRegion>(name: "expected" ); | 
| 720 |  | 
| 721 |     QTest::newRow(dataTag: "empty 0" ) << QRegion() << QRegion() << QRegion(); | 
| 722 |     QTest::newRow(dataTag: "empty 1" ) << QRegion() << QRegion(QRect(10, 10, 10, 10)) | 
| 723 |                              << QRegion(); | 
| 724 |     QTest::newRow(dataTag: "empty 2" ) << QRegion(QRect(10, 10, 10, 10)) << QRegion() | 
| 725 |                              << QRegion(); | 
| 726 |  | 
| 727 |     QRegion dest; | 
| 728 |     QVector<QRect> rects; | 
| 729 |     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10); | 
| 730 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 731 |     QTest::newRow(dataTag: "simple 1" ) << dest | 
| 732 |                               << QRegion(22, 10, 10, 10) | 
| 733 |                               << QRegion(22, 10, 10, 10); | 
| 734 |     QTest::newRow(dataTag: "simple 2" ) << dest | 
| 735 |                               << QRegion(10, 10, 10, 10) | 
| 736 |                               << QRegion(10, 10, 10, 10); | 
| 737 |  | 
| 738 |     rects.clear(); | 
| 739 |     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 15, 10); | 
| 740 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 741 |     QTest::newRow(dataTag: "merge 1" ) << dest | 
| 742 |                              << QRegion(10, 10, 10, 20) | 
| 743 |                              << QRegion(10, 10, 10, 20); | 
| 744 |  | 
| 745 |     rects.clear(); | 
| 746 |     rects << QRect(11, 11, 218, 117) << QRect(11, 128, 218, 27) | 
| 747 |           << QRect(264, 128, 122, 27) << QRect(11, 155, 218, 43) | 
| 748 |           << QRect(11, 198, 218, 27) << QRect(264, 198, 122, 27) | 
| 749 |           << QRect(11, 225, 218, 221); | 
| 750 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 751 |     QTest::newRow(dataTag: "merge 2" ) << dest << QRegion(11, 11, 218, 458) | 
| 752 |                              << QRegion(11, 11, 218, 435); | 
| 753 |  | 
| 754 |     rects.clear(); | 
| 755 |     rects << QRect(0, 0, 10, 10) << QRect(20, 0, 10, 10); | 
| 756 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 757 |     QTest::newRow(dataTag: "empty 3" ) << dest << QRegion(11, 0, 5, 5) << QRegion(); | 
| 758 |  | 
| 759 |     QTest::newRow(dataTag: "extents check" ) << dest << QRegion(0, 0, 15, 15) | 
| 760 |                                    << QRegion(0, 0, 10, 10); | 
| 761 |  | 
| 762 |     rects.clear(); | 
| 763 |     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 10, 10) | 
| 764 |           << QRect(30, 20, 10, 10) << QRect(10, 30, 10, 10); | 
| 765 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 766 |     rects.clear(); | 
| 767 |     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 10, 10) | 
| 768 |           << QRect(30, 20, 10, 10); | 
| 769 |     QRegion expected; | 
| 770 |     expected.setRects(rect: rects.constData(), num: rects.size()); | 
| 771 |     QTest::newRow(dataTag: "dont merge" ) << dest << QRegion(0, 0, 100, 30) | 
| 772 |                                 << expected; | 
| 773 | } | 
| 774 |  | 
| 775 | void tst_QRegion::operator_intersect() | 
| 776 | { | 
| 777 |     QFETCH(QRegion, r1); | 
| 778 |     QFETCH(QRegion, r2); | 
| 779 |     QFETCH(QRegion, expected); | 
| 780 |  | 
| 781 |     if ((r1 & r2) != expected) { | 
| 782 |         qDebug() << "r1 & r2"  << (r1 & r2); | 
| 783 |         qDebug() << "expected"  << expected; | 
| 784 |     } | 
| 785 |     QCOMPARE(r1 & r2, expected); | 
| 786 |  | 
| 787 |     if ((r2 & r1) != expected) { | 
| 788 |         qDebug() << "r2 & r1"  << (r2 & r1); | 
| 789 |         qDebug() << "expected"  << expected; | 
| 790 |     } | 
| 791 |     QCOMPARE(r2 & r1, expected); | 
| 792 |  | 
| 793 |     r1 &= r2; | 
| 794 |     QCOMPARE(r1, expected); | 
| 795 | } | 
| 796 |  | 
| 797 | void tst_QRegion::operator_xor_data() | 
| 798 | { | 
| 799 |     QTest::addColumn<QRegion>(name: "dest" ); | 
| 800 |     QTest::addColumn<QRegion>(name: "arg" ); | 
| 801 |     QTest::addColumn<QRegion>(name: "expected" ); | 
| 802 |  | 
| 803 |     QTest::newRow(dataTag: "empty 0" ) << QRegion() << QRegion() << QRegion(); | 
| 804 |     QTest::newRow(dataTag: "empty 1" ) << QRegion() << QRegion(QRect(10, 10, 10, 10)) | 
| 805 |                              << QRegion(QRect(10, 10, 10, 10)); | 
| 806 |     QTest::newRow(dataTag: "empty 2" ) << QRegion(QRect(10, 10, 10, 10)) << QRegion() | 
| 807 |                              << QRegion(QRect(10, 10, 10, 10)); | 
| 808 |  | 
| 809 |     QRegion dest; | 
| 810 |     QVector<QRect> rects; | 
| 811 |     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10); | 
| 812 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 813 |     QTest::newRow(dataTag: "simple 1" ) << dest | 
| 814 |                               << QRegion(22, 10, 10, 10) | 
| 815 |                               << QRegion(10, 10, 10, 10); | 
| 816 |     QTest::newRow(dataTag: "simple 2" ) << dest | 
| 817 |                               << QRegion(10, 10, 10, 10) | 
| 818 |                               << QRegion(22, 10, 10, 10); | 
| 819 |     QTest::newRow(dataTag: "simple 3" ) << dest << dest << QRegion(); | 
| 820 |     QTest::newRow(dataTag: "simple 4" ) << QRegion(10, 10, 10, 10) | 
| 821 |                               << QRegion(10, 10, 5, 10) | 
| 822 |                               << QRegion(15, 10, 5, 10); | 
| 823 |     QTest::newRow(dataTag: "simple 5" ) << QRegion(10, 10, 10, 10) | 
| 824 |                               << QRegion(10, 10, 10, 5) | 
| 825 |                               << QRegion(10, 15, 10, 5); | 
| 826 |  | 
| 827 |     const QRegion rgnA(0, 0, 100, 100); | 
| 828 |     const QRegion rgnB(0, 0, 10, 10); | 
| 829 |  | 
| 830 |     QTest::newRow(dataTag: "simple 6" ) << rgnA | 
| 831 |                               << rgnA - rgnB | 
| 832 |                               << rgnB; | 
| 833 |  | 
| 834 |     QTest::newRow(dataTag: "simple 7" ) << rgnB | 
| 835 |                               << rgnA | 
| 836 |                               << rgnA - rgnB; | 
| 837 | } | 
| 838 |  | 
| 839 | void tst_QRegion::operator_xor() | 
| 840 | { | 
| 841 |     QFETCH(QRegion, dest); | 
| 842 |     QFETCH(QRegion, arg); | 
| 843 |     QFETCH(QRegion, expected); | 
| 844 |  | 
| 845 |     QCOMPARE(dest ^ arg, expected); | 
| 846 |     QCOMPARE(dest.xored(arg), expected); | 
| 847 |  | 
| 848 |     dest ^= arg; | 
| 849 |     QCOMPARE(dest, expected); | 
| 850 | } | 
| 851 |  | 
| 852 | void tst_QRegion::rectCount_data() | 
| 853 | { | 
| 854 |     QTest::addColumn<QRegion>(name: "region" ); | 
| 855 |     QTest::addColumn<int>(name: "expected" ); | 
| 856 |  | 
| 857 |     QTest::newRow(dataTag: "empty" ) << QRegion() << 0; | 
| 858 |     QTest::newRow(dataTag: "rect" ) << QRegion(10, 10, 10, 10) << 1; | 
| 859 |  | 
| 860 |     QRegion dest; | 
| 861 |     QVector<QRect> rects; | 
| 862 |     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10); | 
| 863 |     dest.setRects(rect: rects.constData(), num: rects.size()); | 
| 864 |  | 
| 865 |     QTest::newRow(dataTag: "2 rects" ) << dest << rects.size(); | 
| 866 | } | 
| 867 |  | 
| 868 | void tst_QRegion::rectCount() | 
| 869 | { | 
| 870 |     QFETCH(QRegion, region); | 
| 871 |     QFETCH(int, expected); | 
| 872 |  | 
| 873 |     QCOMPARE(region.rectCount(), expected); | 
| 874 | } | 
| 875 |  | 
| 876 | void tst_QRegion::isEmpty_data() | 
| 877 | { | 
| 878 |     QTest::addColumn<QRegion>(name: "region" ); | 
| 879 |  | 
| 880 |     QTest::newRow(dataTag: "QRegion" ) << QRegion(); | 
| 881 |  | 
| 882 |     QVector<QRect> rects; | 
| 883 |     rects << QRect(0, 0, 10, 10) << QRect(15, 0, 10, 10); | 
| 884 |     QRegion r1; | 
| 885 |     r1.setRects(rect: rects.constData(), num: rects.size()); | 
| 886 |  | 
| 887 |     QRegion r2; | 
| 888 |     rects.clear(); | 
| 889 |     rects << QRect(0, 0, 12, 12) << QRect(15, 0, 12, 12); | 
| 890 |     r2.setRects(rect: rects.constData(), num: rects.size()); | 
| 891 |     QTest::newRow(dataTag: "minus" ) << (r1 - r2); | 
| 892 | } | 
| 893 |  | 
| 894 | void tst_QRegion::isEmpty() | 
| 895 | { | 
| 896 |     QFETCH(QRegion, region); | 
| 897 |  | 
| 898 |     QVERIFY(region.isEmpty()); | 
| 899 |     QCOMPARE(region.begin(), region.end()); | 
| 900 |     QCOMPARE(region, QRegion()); | 
| 901 |     QCOMPARE(region.rectCount(), 0); | 
| 902 |     QCOMPARE(region.boundingRect(), QRect()); | 
| 903 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 904 |     QVERIFY(region.rects().isEmpty()); | 
| 905 | #endif | 
| 906 | } | 
| 907 |  | 
| 908 | void tst_QRegion::regionFromPath() | 
| 909 | { | 
| 910 |     { | 
| 911 |         QPainterPath path; | 
| 912 |         path.addRect(x: 0, y: 0, w: 10, h: 10); | 
| 913 |         path.addRect(x: 0, y: 100, w: 100, h: 1000); | 
| 914 |  | 
| 915 |         QRegion rgn(path.toFillPolygon().toPolygon()); | 
| 916 |  | 
| 917 |         QCOMPARE(rgn.end(), rgn.begin() + 2); | 
| 918 |         QCOMPARE(rgn.begin()[0], QRect(0, 0, 10, 10)); | 
| 919 |         QCOMPARE(rgn.begin()[1], QRect(0, 100, 100, 1000)); | 
| 920 |  | 
| 921 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 922 |         QCOMPARE(rgn.rects().size(), 2); | 
| 923 |         QCOMPARE(rgn.rects().at(0), QRect(0, 0, 10, 10)); | 
| 924 |         QCOMPARE(rgn.rects().at(1), QRect(0, 100, 100, 1000)); | 
| 925 | #endif | 
| 926 |  | 
| 927 |         QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 1100)); | 
| 928 |     } | 
| 929 |  | 
| 930 |     { | 
| 931 |         QPainterPath path; | 
| 932 |         path.addRect(x: 0, y: 0, w: 100, h: 100); | 
| 933 |         path.addRect(x: 10, y: 10, w: 80, h: 80); | 
| 934 |  | 
| 935 |         QRegion rgn(path.toFillPolygon().toPolygon()); | 
| 936 |  | 
| 937 |         QCOMPARE(rgn.end(), rgn.begin() + 4); | 
| 938 |         QCOMPARE(rgn.begin()[0], QRect(0, 0, 100, 10)); | 
| 939 |         QCOMPARE(rgn.begin()[1], QRect(0, 10, 10, 80)); | 
| 940 |         QCOMPARE(rgn.begin()[2], QRect(90, 10, 10, 80)); | 
| 941 |         QCOMPARE(rgn.begin()[3], QRect(0, 90, 100, 10)); | 
| 942 |  | 
| 943 | #if QT_DEPRECATED_SINCE(5, 11) | 
| 944 |         QCOMPARE(rgn.rects().size(), 4); | 
| 945 |         QCOMPARE(rgn.rects().at(0), QRect(0, 0, 100, 10)); | 
| 946 |         QCOMPARE(rgn.rects().at(1), QRect(0, 10, 10, 80)); | 
| 947 |         QCOMPARE(rgn.rects().at(2), QRect(90, 10, 10, 80)); | 
| 948 |         QCOMPARE(rgn.rects().at(3), QRect(0, 90, 100, 10)); | 
| 949 | #endif | 
| 950 |  | 
| 951 |         QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 100)); | 
| 952 |     } | 
| 953 | } | 
| 954 |  | 
| 955 | void tst_QRegion::scaleRegions_data() | 
| 956 | { | 
| 957 |     QTest::addColumn<qreal>(name: "scale" ); | 
| 958 |     QTest::addColumn<QVector<QRect>>(name: "inputRects" ); | 
| 959 |     QTest::addColumn<QVector<QRect>>(name: "expectedRects" ); | 
| 960 |  | 
| 961 |     QTest::newRow(dataTag: "1.0 single" )  << 1.0 | 
| 962 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20) } | 
| 963 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20) }; | 
| 964 |     QTest::newRow(dataTag: "1.0 multi" )   << 1.0 | 
| 965 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } | 
| 966 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) }; | 
| 967 |     QTest::newRow(dataTag: "2.0 single" )  << 2.0 | 
| 968 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20) } | 
| 969 |                                  << QVector<QRect>{ QRect(20, 20, 40, 40) }; | 
| 970 |     QTest::newRow(dataTag: "2.0 multi" )   << 2.0 | 
| 971 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } | 
| 972 |                                  << QVector<QRect>{ QRect(20, 20, 40, 40), QRect(80, 20, 40, 40) }; | 
| 973 |     QTest::newRow(dataTag: "-1.0 single" ) << -1.0 | 
| 974 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20) } | 
| 975 |                                  << QVector<QRect>{ QRect(-30, -30, 20, 20) }; | 
| 976 |     QTest::newRow(dataTag: "-1.0 multi" )  << -1.0 | 
| 977 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } | 
| 978 |                                  << QVector<QRect>{ QRect(-60, -30, 20, 20), QRect(-30, -30, 20, 20) }; | 
| 979 |     QTest::newRow(dataTag: "-2.0 single" ) << -2.0 | 
| 980 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20) } | 
| 981 |                                  << QVector<QRect>{ QRect(-60, -60, 40, 40) }; | 
| 982 |     QTest::newRow(dataTag: "-2.0 multi" )  << -2.0 | 
| 983 |                                  << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } | 
| 984 |                                  << QVector<QRect>{ QRect(-120, -60, 40, 40), QRect(-60, -60, 40, 40) }; | 
| 985 | } | 
| 986 |  | 
| 987 | void tst_QRegion::scaleRegions() | 
| 988 | { | 
| 989 |     QFETCH(qreal, scale); | 
| 990 |     QFETCH(QVector<QRect>, inputRects); | 
| 991 |     QFETCH(QVector<QRect>, expectedRects); | 
| 992 |  | 
| 993 |     QRegion region; | 
| 994 |     region.setRects(rect: inputRects.constData(), num: inputRects.size()); | 
| 995 |  | 
| 996 |     QRegion expected(expectedRects.first()); | 
| 997 |     expected.setRects(rect: expectedRects.constData(), num: expectedRects.size()); | 
| 998 |  | 
| 999 |     QTransform t; | 
| 1000 |     t.scale(sx: scale, sy: scale); | 
| 1001 |  | 
| 1002 |     auto result = t.map(r: region); | 
| 1003 |  | 
| 1004 |     QCOMPARE(result.rectCount(), expectedRects.size()); | 
| 1005 |     QCOMPARE(result, expected); | 
| 1006 | } | 
| 1007 |  | 
| 1008 | Q_DECLARE_METATYPE(QPainterPath) | 
| 1009 |  | 
| 1010 | #ifdef QT_BUILD_INTERNAL | 
| 1011 | void tst_QRegion::regionToPath_data() | 
| 1012 | { | 
| 1013 |     QTest::addColumn<QPainterPath>(name: "path" ); | 
| 1014 |     { | 
| 1015 |         QPainterPath path; | 
| 1016 |         path.addRect(rect: QRect(0, 0, 10, 10)); | 
| 1017 |  | 
| 1018 |         QTest::newRow(dataTag: "Rectangle" ) << path; | 
| 1019 |     } | 
| 1020 |  | 
| 1021 |     { | 
| 1022 |         QPainterPath path; | 
| 1023 |         path.addRect(rect: QRect(0, 0, 10, 10)); | 
| 1024 |         path.addRect(rect: QRect(20, 0, 10, 10)); | 
| 1025 |  | 
| 1026 |         QTest::newRow(dataTag: "Two rects" ) << path; | 
| 1027 |     } | 
| 1028 |  | 
| 1029 |     { | 
| 1030 |         QPainterPath path; | 
| 1031 |         path.addEllipse(rect: QRect(0, 0, 10, 10)); | 
| 1032 |  | 
| 1033 |         QTest::newRow(dataTag: "Ellipse" ) << path; | 
| 1034 |     } | 
| 1035 |  | 
| 1036 |     { | 
| 1037 |         QPainterPath path; | 
| 1038 |         path.addRect(rect: QRect(0, 0, 3, 8)); | 
| 1039 |         path.addRect(rect: QRect(6, 0, 3, 8)); | 
| 1040 |         path.addRect(rect: QRect(3, 3, 3, 2)); | 
| 1041 |         path.addRect(rect: QRect(12, 3, 3, 2)); | 
| 1042 |  | 
| 1043 |         QTest::newRow(dataTag: "H-dot" ) << path; | 
| 1044 |     } | 
| 1045 |  | 
| 1046 |     { | 
| 1047 |         QPainterPath path; | 
| 1048 |         for (int y = 0; y <= 10; ++y) { | 
| 1049 |             for (int x = 0; x <= 10; ++x) { | 
| 1050 |                 if (!(y & 1) || ((x ^ y) & 1)) | 
| 1051 |                     path.addRect(rect: QRect(x, y, 1, 1)); | 
| 1052 |             } | 
| 1053 |         } | 
| 1054 |  | 
| 1055 |         QTest::newRow(dataTag: "Grid" ) << path; | 
| 1056 |     } | 
| 1057 | } | 
| 1058 | #endif | 
| 1059 |  | 
| 1060 | #ifdef QT_BUILD_INTERNAL | 
| 1061 | QT_BEGIN_NAMESPACE | 
| 1062 | extern QPainterPath qt_regionToPath(const QRegion ®ion); | 
| 1063 | QT_END_NAMESPACE | 
| 1064 | #endif | 
| 1065 |  | 
| 1066 | #ifdef QT_BUILD_INTERNAL | 
| 1067 | void tst_QRegion::regionToPath() | 
| 1068 | { | 
| 1069 |  | 
| 1070 |     QFETCH(QPainterPath, path); | 
| 1071 |  | 
| 1072 |     for (int i = 0; i < 360; i += 10) { | 
| 1073 |  | 
| 1074 |         QTransform transform; | 
| 1075 |         transform.scale(sx: 5, sy: 5); | 
| 1076 |         transform.rotate(a: i); | 
| 1077 |  | 
| 1078 |         QPainterPath mapped = transform.map(p: path); | 
| 1079 |         QRegion region(mapped.toFillPolygon().toPolygon()); | 
| 1080 |  | 
| 1081 |         QPainterPath a; | 
| 1082 |         a.addRegion(region); | 
| 1083 |  | 
| 1084 |         QPainterPath b = qt_regionToPath(region); | 
| 1085 |  | 
| 1086 |         QRect r = a.boundingRect().toAlignedRect(); | 
| 1087 |         QImage ia(r.size(), QImage::Format_RGB32); | 
| 1088 |         ia.fill(pixel: 0xffffffff); | 
| 1089 |         QImage ib = ia; | 
| 1090 |  | 
| 1091 |         QPainter p(&ia); | 
| 1092 |         p.translate(dx: -r.x(), dy: -r.y()); | 
| 1093 |         p.fillPath(path: a, brush: Qt::red); | 
| 1094 |         p.end(); | 
| 1095 |         p.begin(&ib); | 
| 1096 |         p.translate(dx: -r.x(), dy: -r.y()); | 
| 1097 |         p.fillPath(path: b, brush: Qt::red); | 
| 1098 |         p.end(); | 
| 1099 |  | 
| 1100 |         QCOMPARE(ia, ib); | 
| 1101 |         QCOMPARE(a.boundingRect(), b.boundingRect()); | 
| 1102 |     } | 
| 1103 | } | 
| 1104 | #endif | 
| 1105 |  | 
| 1106 | QTEST_MAIN(tst_QRegion) | 
| 1107 | #include "tst_qregion.moc" | 
| 1108 |  |