tests/auto/qregion/tst_qregion.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 #include <qregion.h>
       
    45 
       
    46 #include <qbitmap.h>
       
    47 #include <qpainter.h>
       
    48 #include <qpolygon.h>
       
    49 #ifdef Q_WS_X11
       
    50 #include <private/qt_x11_p.h>
       
    51 #endif
       
    52 
       
    53 
       
    54 //TESTED_CLASS=
       
    55 //TESTED_FILES=
       
    56 
       
    57 class tst_QRegion : public QObject
       
    58 {
       
    59     Q_OBJECT
       
    60 
       
    61 public:
       
    62     tst_QRegion();
       
    63 
       
    64 private slots:
       
    65     void boundingRect();
       
    66     void rects();
       
    67     void setRects();
       
    68     void ellipseRegion();
       
    69     void polygonRegion();
       
    70     void bitmapRegion();
       
    71     void intersected_data();
       
    72     void intersected();
       
    73     void emptyPolygonRegion_data();
       
    74     void emptyPolygonRegion();
       
    75 
       
    76     void intersects_region_data();
       
    77     void intersects_region();
       
    78     void intersects_rect_data();
       
    79     void intersects_rect();
       
    80     void contains_point();
       
    81 
       
    82     void operator_plus_data();
       
    83     void operator_plus();
       
    84     void operator_minus_data();
       
    85     void operator_minus();
       
    86     void operator_intersect_data();
       
    87     void operator_intersect();
       
    88     void operator_xor_data();
       
    89     void operator_xor();
       
    90 
       
    91     void numRects_data();
       
    92     void numRects();
       
    93 
       
    94     void isEmpty_data();
       
    95     void isEmpty();
       
    96 #ifdef Q_OS_WIN
       
    97     void handle();
       
    98 #endif
       
    99 #if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL)
       
   100     void clipRectangles();
       
   101 #endif
       
   102 
       
   103     void regionFromPath();
       
   104 
       
   105     void regionToPath_data();
       
   106     void regionToPath();
       
   107 };
       
   108 
       
   109 Q_DECLARE_METATYPE(QPolygon)
       
   110 Q_DECLARE_METATYPE(QVector<QRect>)
       
   111 Q_DECLARE_METATYPE(QRegion)
       
   112 
       
   113 tst_QRegion::tst_QRegion()
       
   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::rects()
       
   138 {
       
   139     {
       
   140 	QRect rect;
       
   141 	QRegion region( rect );
       
   142 	QVERIFY( region.isEmpty() );
       
   143 	QVERIFY( region.rects().isEmpty() );
       
   144     }
       
   145     {
       
   146 	QRect rect( 10, -20, 30, 40 );
       
   147 	QRegion region( rect );
       
   148 	QCOMPARE( region.rects().count(), 1 );
       
   149 	QCOMPARE( region.rects()[0], rect );
       
   150     }
       
   151     {
       
   152 	QRect r( QPoint(10, 10), QPoint(40, 40) );
       
   153 	QRegion region( r );
       
   154 	QVERIFY( region.contains( QPoint(10,10) ) );
       
   155 	QVERIFY( region.contains( QPoint(20,40) ) );
       
   156 	QVERIFY( region.contains( QPoint(40,20) ) );
       
   157 	QVERIFY( !region.contains( QPoint(20,41) ) );
       
   158 	QVERIFY( !region.contains( QPoint(41,20) ) );
       
   159     }
       
   160     {
       
   161 	QRect r( 10, 10, 30, 30 );
       
   162 	QRegion region( r );
       
   163 	QVERIFY( region.contains( QPoint(10,10) ) );
       
   164 	QVERIFY( region.contains( QPoint(20,39) ) );
       
   165 	QVERIFY( region.contains( QPoint(39,20) ) );
       
   166 	QVERIFY( !region.contains( QPoint(20,40) ) );
       
   167 	QVERIFY( !region.contains( QPoint(40,20) ) );
       
   168     }
       
   169 }
       
   170 
       
   171 void tst_QRegion::setRects()
       
   172 {
       
   173     {
       
   174 	QRegion region;
       
   175 	region.setRects( 0, 0 );
       
   176 	QVERIFY( region.rects().isEmpty() );
       
   177     }
       
   178     {
       
   179 	QRegion region;
       
   180 	QRect rect;
       
   181 	region.setRects( &rect, 0 );
       
   182         QVERIFY(region.isEmpty());
       
   183         QVERIFY(region == QRegion());
       
   184 	QVERIFY(!region.boundingRect().isValid());
       
   185 	QVERIFY(region.rects().isEmpty());
       
   186     }
       
   187     {
       
   188 	QRegion region;
       
   189 	QRect rect;
       
   190 	region.setRects( &rect, 1 );
       
   191 	QVERIFY( !region.boundingRect().isValid() );
       
   192 	QVERIFY( region.rects().isEmpty() );
       
   193     }
       
   194     {
       
   195 	QRegion region;
       
   196 	QRect rect( 10, -20, 30, 40 );
       
   197 	region.setRects( &rect, 1 );
       
   198 	QCOMPARE( region.rects().count(), 1 );
       
   199 	QCOMPARE( region.rects()[0], rect );
       
   200     }
       
   201 }
       
   202 
       
   203 void tst_QRegion::ellipseRegion()
       
   204 {
       
   205     QRegion region(0, 0, 100, 100, QRegion::Ellipse);
       
   206 
       
   207     // These should not be inside the circe
       
   208     QVERIFY(!region.contains(QPoint(13, 13)));
       
   209     QVERIFY(!region.contains(QPoint(13, 86)));
       
   210     QVERIFY(!region.contains(QPoint(86, 13)));
       
   211     QVERIFY(!region.contains(QPoint(86, 86)));
       
   212 
       
   213     // These should be inside
       
   214     QVERIFY(region.contains(QPoint(16, 16)));
       
   215     QVERIFY(region.contains(QPoint(16, 83)));
       
   216     QVERIFY(region.contains(QPoint(83, 16)));
       
   217     QVERIFY(region.contains(QPoint(83, 83)));
       
   218 
       
   219     //     ..a..
       
   220     //   ..     ..
       
   221     //  .         .
       
   222     // .           .
       
   223     // b           c
       
   224     // .           .
       
   225     //  .         .
       
   226     //   ..     ..
       
   227     //     ..d..
       
   228     QVERIFY(region.contains(QPoint(50, 0)));   // Mid-top    (a)
       
   229     QVERIFY(region.contains(QPoint(0, 50)));   // Mid-left   (b)
       
   230     QVERIFY(region.contains(QPoint(99, 50)));  // Mid-right  (c)
       
   231     QVERIFY(region.contains(QPoint(50, 99)));  // Mid-bottom (d)
       
   232 
       
   233     QRect bounds = region.boundingRect();
       
   234     QCOMPARE(bounds.x(), 0);
       
   235     QCOMPARE(bounds.y(), 0);
       
   236     QCOMPARE(bounds.width(), 100);
       
   237     QCOMPARE(bounds.height(), 100);
       
   238 }
       
   239 
       
   240 void tst_QRegion::polygonRegion()
       
   241 {
       
   242     QPolygon pa;
       
   243     {
       
   244 	QRegion region ( pa );
       
   245 	QVERIFY( region.isEmpty() );
       
   246     }
       
   247     {
       
   248 	pa.setPoints( 8, 10, 10, //  a____________b
       
   249 			 40, 10, //  |            |
       
   250 			 40, 20, //  |___      ___|
       
   251 			 30, 20, //      |    |
       
   252 			 30, 40, //      |    |
       
   253 			 20, 40, //      |    |
       
   254 			 20, 20, //      |____c
       
   255 			 10, 20 );
       
   256 
       
   257 	QRegion region ( pa );
       
   258 	QVERIFY( !region.isEmpty() );
       
   259 
       
   260 	// These should not be inside the circle
       
   261 	QVERIFY( !region.contains( QPoint(  9,  9 ) ) );
       
   262 	QVERIFY( !region.contains( QPoint( 30, 41 ) ) );
       
   263 	QVERIFY( !region.contains( QPoint( 41, 10 ) ) );
       
   264 	QVERIFY( !region.contains( QPoint( 31, 21 ) ) );
       
   265 
       
   266 	// These should be inside
       
   267 	QVERIFY( region.contains( QPoint( 10, 10 ) ) ); // Upper-left  (a)
       
   268 
       
   269     }
       
   270 }
       
   271 
       
   272 void tst_QRegion::emptyPolygonRegion_data()
       
   273 {
       
   274     QTest::addColumn<QPolygon>("pa");
       
   275     QTest::addColumn<bool>("isEmpty");
       
   276     QTest::addColumn<int>("numRects");
       
   277     QTest::addColumn<QVector<QRect> >("rects");
       
   278 
       
   279     QPolygon pa;
       
   280 
       
   281 
       
   282     QTest::newRow("no points") << pa << true << 0 << QVector<QRect>();
       
   283     pa = QPolygon() << QPoint(10,10);
       
   284     QTest::newRow("one point") << pa << true << 0 << QVector<QRect>();
       
   285     pa = QPolygon() << QPoint(10,10) << QPoint(10,20);
       
   286     QTest::newRow("two points, horizontal") << pa << true << 0 << QVector<QRect>();
       
   287 
       
   288     pa = QPolygon() << QPoint(10,10) << QPoint(20,10);
       
   289     QTest::newRow("two points, vertical") << pa << true << 0 << QVector<QRect>();
       
   290 
       
   291     pa = QPolygon() << QPoint(10,10) << QPoint(20,20);
       
   292     QTest::newRow("two points, diagonal") << pa << true << 0 << QVector<QRect>();
       
   293 
       
   294     pa = QPolygon() << QPoint(10,10) << QPoint(15,15) << QPoint(10,15) << QPoint(10, 10) ;
       
   295     QVector<QRect> v;
       
   296     v << QRect(10,11,1, 1) << QRect(10,12,2,1) << QRect(10,13,3,1) << QRect(10,14,4,1);
       
   297     QTest::newRow("triangle") << pa << false << 4 << v;
       
   298 
       
   299     v.clear();
       
   300     v << QRect(10,10,10,10);
       
   301 
       
   302     QTest::newRow("rectangle") << QPolygon(QRect(10,10,10,10))  << false << 1 << v;
       
   303 
       
   304 }
       
   305 
       
   306 void tst_QRegion::emptyPolygonRegion()
       
   307 {
       
   308     QFETCH(QPolygon, pa);
       
   309 
       
   310     QRegion r(pa);
       
   311     QTEST(r.isEmpty(), "isEmpty");
       
   312     QTEST(r.rects().count(), "numRects");
       
   313     QTEST(r.rects(), "rects");
       
   314 }
       
   315 
       
   316 
       
   317 static const char *circle_xpm[] = {
       
   318     "20 20 2 1",
       
   319     "	c #FFFFFF",
       
   320     ".	c #000000",
       
   321     "       ......       ",
       
   322     "     ..........     ",
       
   323     "   ..............   ",
       
   324     "  ................  ",
       
   325     "  ................  ",
       
   326     " .................. ",
       
   327     " .................. ",
       
   328     "....................",
       
   329     "....................",
       
   330     "....................",
       
   331     "....................",
       
   332     "....................",
       
   333     "....................",
       
   334     " .................. ",
       
   335     " .................. ",
       
   336     "  ................  ",
       
   337     "  ................  ",
       
   338     "   ..............   ",
       
   339     "     ..........     ",
       
   340     "       ......       "
       
   341 };
       
   342 
       
   343 void tst_QRegion::bitmapRegion()
       
   344 {
       
   345     QBitmap circle;
       
   346     {
       
   347 	QRegion region( circle );
       
   348 	QVERIFY( region.isEmpty() );
       
   349     }
       
   350     {
       
   351 	circle = QPixmap( circle_xpm );
       
   352 	QRegion region( circle );
       
   353 
       
   354 	//// These should not be inside the circe
       
   355 	QVERIFY( !region.contains( QPoint( 2,   2 ) ) );
       
   356 	QVERIFY( !region.contains( QPoint( 2,  17 ) ) );
       
   357 	QVERIFY( !region.contains( QPoint( 17,  2 ) ) );
       
   358 	QVERIFY( !region.contains( QPoint( 17, 17 ) ) );
       
   359 
       
   360 	//// These should be inside
       
   361 	QVERIFY( region.contains( QPoint( 3,   3 ) ) );
       
   362 	QVERIFY( region.contains( QPoint( 3,  16 ) ) );
       
   363 	QVERIFY( region.contains( QPoint( 16,  3 ) ) );
       
   364 	QVERIFY( region.contains( QPoint( 16, 16 ) ) );
       
   365 
       
   366 	QVERIFY( region.contains( QPoint( 0, 10 ) ) );  // Mid-left
       
   367 	QVERIFY( region.contains( QPoint( 10, 0 ) ) );  // Mid-top
       
   368 	QVERIFY( region.contains( QPoint( 19, 10 ) ) ); // Mid-right
       
   369 	QVERIFY( region.contains( QPoint( 10, 19 ) ) ); // Mid-bottom
       
   370     }
       
   371 }
       
   372 
       
   373 void tst_QRegion::intersected_data()
       
   374 {
       
   375     QTest::addColumn<QRegion>("r1");
       
   376     QTest::addColumn<QRegion>("r2");
       
   377     QTest::addColumn<bool>("intersects");
       
   378     // QTest::addColumn<QRegion>("intersected");
       
   379 
       
   380     QPolygon ps1(8);
       
   381     QPolygon ps2(8);
       
   382     ps1.putPoints(0,8, 20,20, 50,20, 50,100, 70,100, 70,20, 120,20, 120,200, 20, 200);
       
   383     ps2.putPoints(0,8, 100,150, 140,150, 140,160, 160,160, 160,150, 200,150, 200,180, 100,180);
       
   384     QTest::newRow("task30716") << QRegion(ps1) << QRegion(ps2) << true;
       
   385 }
       
   386 
       
   387 void tst_QRegion::intersected()
       
   388 {
       
   389     QFETCH(QRegion, r1);
       
   390     QFETCH(QRegion, r2);
       
   391     QFETCH(bool, intersects);
       
   392 
       
   393     QRegion interReg = r1.intersected(r2);
       
   394     QVERIFY(interReg.isEmpty() != intersects);
       
   395     // Need a way to test the intersected QRegion is right
       
   396 }
       
   397 
       
   398 void tst_QRegion::intersects_region_data()
       
   399 {
       
   400     QTest::addColumn<QRegion>("r1");
       
   401     QTest::addColumn<QRegion>("r2");
       
   402     QTest::addColumn<bool>("intersects");
       
   403 
       
   404     QTest::newRow("rect overlap rect") << QRegion(100, 100, 200, 200)
       
   405                                        << QRegion(200, 200, 200, 200)
       
   406                                        << true;
       
   407 
       
   408     QTest::newRow("rect not overlap rect") << QRegion(100, 100, 200, 200)
       
   409                                            << QRegion(400, 400, 200, 200)
       
   410                                            << false;
       
   411 
       
   412     QTest::newRow("ellipse overlap ellipse") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
       
   413                                              << QRegion(200, 200, 200, 200, QRegion::Ellipse)
       
   414                                              << true;
       
   415 
       
   416     QTest::newRow("ellipse not overlap ellipse") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
       
   417                                                  << QRegion(400, 400, 200, 200, QRegion::Ellipse)
       
   418                                                  << false;
       
   419 }
       
   420 
       
   421 void tst_QRegion::intersects_region()
       
   422 {
       
   423     QFETCH(QRegion, r1);
       
   424     QFETCH(QRegion, r2);
       
   425     QFETCH(bool, intersects);
       
   426     QCOMPARE(r1.intersects(r2), intersects);
       
   427 }
       
   428 
       
   429 
       
   430 void tst_QRegion::intersects_rect_data()
       
   431 {
       
   432     QTest::addColumn<QRegion>("region");
       
   433     QTest::addColumn<QRect>("rect");
       
   434     QTest::addColumn<bool>("intersects");
       
   435 
       
   436     QTest::newRow("rect overlap rect") << QRegion(100, 100, 200, 200)
       
   437                                        << QRect(200, 200, 200, 200)
       
   438                                        << true;
       
   439 
       
   440     QTest::newRow("rect not overlap rect") << QRegion(100, 100, 200, 200)
       
   441                                            << QRect(400, 400, 200, 200)
       
   442                                            << false;
       
   443 
       
   444     QTest::newRow("ellipse overlap rect") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
       
   445                                           << QRect(200, 200, 200, 200)
       
   446                                           << true;
       
   447 
       
   448     QTest::newRow("ellipse not overlap rect") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
       
   449                                               << QRect(400, 400, 200, 200)
       
   450                                               << false;
       
   451 }
       
   452 
       
   453 void tst_QRegion::intersects_rect()
       
   454 {
       
   455     QFETCH(QRegion, region);
       
   456     QFETCH(QRect, rect);
       
   457     QFETCH(bool, intersects);
       
   458     QCOMPARE(region.intersects(rect), intersects);
       
   459 }
       
   460 
       
   461 void tst_QRegion::contains_point()
       
   462 {
       
   463     QCOMPARE(QRegion().contains(QPoint(1,1)),false);
       
   464     QCOMPARE(QRegion(0,0,2,2).contains(QPoint(1,1)),true);
       
   465 }
       
   466 
       
   467 void tst_QRegion::operator_plus_data()
       
   468 {
       
   469     QTest::addColumn<QRegion>("r1");
       
   470     QTest::addColumn<QRegion>("r2");
       
   471     QTest::addColumn<QRegion>("expected");
       
   472 
       
   473     QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
       
   474     QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
       
   475                              << QRegion(QRect(10, 10, 10, 10));
       
   476     QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
       
   477                              << QRegion(QRect(10, 10, 10, 10));
       
   478 
       
   479     QRegion expected;
       
   480     QVector<QRect> rects;
       
   481     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
       
   482     expected.setRects(rects.constData(), rects.size());
       
   483     QTest::newRow("non overlapping") << QRegion(10, 10, 10, 10)
       
   484                                      << QRegion(22, 10, 10, 10)
       
   485                                      << expected;
       
   486 
       
   487     rects.clear();
       
   488     rects << QRect(50, 0, 50, 2);
       
   489     expected.setRects(rects.constData(), rects.size());
       
   490     QTest::newRow("adjacent y-rects") << QRegion(50, 0, 50, 1)
       
   491                                       << QRegion(50, 1, 50, 1)
       
   492                                       << expected;
       
   493 
       
   494     rects.clear();
       
   495     rects << QRect(50, 0, 2, 1);
       
   496     expected.setRects(rects.constData(), rects.size());
       
   497     QTest::newRow("adjacent x-rects") << QRegion(50, 0, 1, 1)
       
   498                                       << QRegion(51, 0, 1, 1)
       
   499                                       << expected;
       
   500 
       
   501     rects.clear();
       
   502     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 5, 10);
       
   503     QRegion r1;
       
   504     r1.setRects(rects.constData(), rects.size());
       
   505     QTest::newRow("double merge") << r1 << QRegion(15, 20, 5, 10)
       
   506                                   << QRegion(10, 10, 10, 20);
       
   507     rects.clear();
       
   508     rects << QRect(15, 10, 5, 10) << QRect(10, 20, 10, 10);
       
   509     r1.setRects(rects.constData(), rects.size());
       
   510     QTest::newRow("double merge 2") << r1 << QRegion(10, 10, 5, 10)
       
   511                                     << QRegion(10, 10, 10, 20);
       
   512     QTest::newRow("overlapping x") << QRegion(10, 10, 10, 10)
       
   513                                    << QRegion(15, 10, 10, 10)
       
   514                                    << QRegion(10, 10, 15, 10);
       
   515     QTest::newRow("overlapping y") << QRegion(10, 10, 10, 10)
       
   516                                    << QRegion(10, 15, 10, 10)
       
   517                                    << QRegion(10, 10, 10, 15);
       
   518     rects.clear();
       
   519     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 5, 10);
       
   520     r1.setRects(rects.constData(), rects.size());
       
   521     rects.clear();
       
   522     rects << QRect(15, 20, 5, 10) << QRect(10, 30, 10, 10);
       
   523     QRegion r2;
       
   524     r2.setRects(rects.constData(), rects.size());
       
   525     QTest::newRow("triple merge") << r1 << r2
       
   526                                   << QRegion(10, 10, 10, 30);
       
   527 
       
   528     rects.clear();
       
   529     rects << QRect(10, 10, 4, 10) << QRect(15, 10, 10, 10);
       
   530     r1.setRects(rects.constData(), rects.size());
       
   531     rects.clear();
       
   532     rects << QRect(15, 20, 10, 10);
       
   533     r2.setRects(rects.constData(), rects.size());
       
   534     rects.clear();
       
   535     rects << QRect(10, 10, 4, 10) << QRect(15, 10, 10, 10)
       
   536           << QRect(15, 20, 10, 10);
       
   537     expected.setRects(rects.constData(), rects.size());
       
   538     QTest::newRow("don't merge y") << r1 << r2 << expected;
       
   539 
       
   540     QTest::newRow("equal 1") << QRegion(10, 10, 10, 10)
       
   541                              << QRegion(10, 10, 10, 10)
       
   542                              << QRegion(10, 10, 10, 10);
       
   543     QTest::newRow("equal 2") << expected << expected << expected;
       
   544 }
       
   545 
       
   546 void tst_QRegion::operator_plus()
       
   547 {
       
   548     QFETCH(QRegion, r1);
       
   549     QFETCH(QRegion, r2);
       
   550     QFETCH(QRegion, expected);
       
   551 
       
   552     if (r1 + r2 != expected) {
       
   553         qDebug() << "r1 + r2" << (r1 + r2);
       
   554         qDebug() << "expected" << expected;
       
   555     }
       
   556     QCOMPARE(r1 + r2, expected);
       
   557     if (r2.numRects() == 1) {
       
   558         if (r1 + r2.boundingRect() != expected) {
       
   559             qDebug() << "r1 + QRect(r2)" << (r1 + r2.boundingRect());
       
   560             qDebug() << "expected" << expected;
       
   561         }
       
   562         QCOMPARE(r1 + r2.boundingRect(), expected);
       
   563     }
       
   564 
       
   565     if (r2 + r1 != expected) {
       
   566         qDebug() << "r2 + r1" << (r2 + r1);
       
   567         qDebug() << "expected" << expected;
       
   568     }
       
   569     QCOMPARE(r2 + r1, expected);
       
   570     if (r1.numRects() == 1) {
       
   571         if (r1 + r2.boundingRect() != expected) {
       
   572             qDebug() << "r2 + QRect(r1)" << (r2 + r1.boundingRect());
       
   573             qDebug() << "expected" << expected;
       
   574         }
       
   575         QCOMPARE(r2 + r1.boundingRect(), expected);
       
   576     }
       
   577 
       
   578     QRegion result1 = r1;
       
   579     result1 += r2;
       
   580     if (result1 != expected) {
       
   581         qDebug() << "r1 += r2" << result1;
       
   582         qDebug() << "expected" << expected;
       
   583     }
       
   584     QCOMPARE(result1, expected);
       
   585     if (r2.numRects() == 1) {
       
   586         result1 = r1;
       
   587         result1 += r2.boundingRect();
       
   588         if (result1 != expected) {
       
   589             qDebug() << "r1 += QRect(r2)" << result1;
       
   590             qDebug() << "expected" << expected;
       
   591         }
       
   592         QCOMPARE(result1, expected);
       
   593     }
       
   594 
       
   595     QRegion result2 = r2;
       
   596     result2 += r1;
       
   597     if (result2 != expected) {
       
   598         qDebug() << "r2 += r1" << result2;
       
   599         qDebug() << "expected" << expected;
       
   600     }
       
   601     QCOMPARE(result2, expected);
       
   602     if (r1.numRects() == 1) {
       
   603         result2 = r2;
       
   604         result2 += r1.boundingRect();
       
   605         if (result2 != expected) {
       
   606             qDebug() << "r2 += QRect(r1)" << result2;
       
   607             qDebug() << "expected" << expected;
       
   608         }
       
   609         QCOMPARE(result2, expected);
       
   610     }
       
   611 }
       
   612 
       
   613 void tst_QRegion::operator_minus_data()
       
   614 {
       
   615     QTest::addColumn<QRegion>("dest");
       
   616     QTest::addColumn<QRegion>("subtract");
       
   617     QTest::addColumn<QRegion>("expected");
       
   618 
       
   619     QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
       
   620     QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
       
   621                              << QRegion();
       
   622     QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
       
   623                              << QRegion(QRect(10, 10, 10, 10));
       
   624 
       
   625     QRegion dest;
       
   626     QVector<QRect> rects;
       
   627     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
       
   628     dest.setRects(rects.constData(), rects.size());
       
   629     QTest::newRow("simple 1") << dest
       
   630                               << QRegion(22, 10, 10, 10)
       
   631                               << QRegion(10, 10, 10, 10);
       
   632     QTest::newRow("simple 2") << dest
       
   633                               << QRegion(10, 10, 10, 10)
       
   634                               << QRegion(22, 10, 10, 10);
       
   635 
       
   636     rects.clear();
       
   637     rects << QRect(0, 0, 10, 10) << QRect(15, 0, 10, 10);
       
   638     dest.setRects(rects.constData(), rects.size());
       
   639 
       
   640     QRegion minus;
       
   641     rects.clear();
       
   642     rects << QRect(0, 0, 12, 12) << QRect(15, 0, 12, 12);
       
   643     minus.setRects(rects.constData(), rects.size());
       
   644     QTest::newRow("empty 3") << dest << minus << QRegion();
       
   645 }
       
   646 
       
   647 void tst_QRegion::operator_minus()
       
   648 {
       
   649     QFETCH(QRegion, dest);
       
   650     QFETCH(QRegion, subtract);
       
   651     QFETCH(QRegion, expected);
       
   652 
       
   653     if (dest - subtract != expected) {
       
   654         qDebug() << "dest - subtract" << (dest - subtract);
       
   655         qDebug() << "expected" << expected;
       
   656     };
       
   657     QCOMPARE(dest - subtract, expected);
       
   658 
       
   659     dest -= subtract;
       
   660 
       
   661     if (dest != expected) {
       
   662         qDebug() << "dest" << dest;
       
   663         qDebug() << "expected" << expected;
       
   664     };
       
   665     QCOMPARE(dest, expected);
       
   666 }
       
   667 
       
   668 void tst_QRegion::operator_intersect_data()
       
   669 {
       
   670     QTest::addColumn<QRegion>("r1");
       
   671     QTest::addColumn<QRegion>("r2");
       
   672     QTest::addColumn<QRegion>("expected");
       
   673 
       
   674     QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
       
   675     QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
       
   676                              << QRegion();
       
   677     QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
       
   678                              << QRegion();
       
   679 
       
   680     QRegion dest;
       
   681     QVector<QRect> rects;
       
   682     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
       
   683     dest.setRects(rects.constData(), rects.size());
       
   684     QTest::newRow("simple 1") << dest
       
   685                               << QRegion(22, 10, 10, 10)
       
   686                               << QRegion(22, 10, 10, 10);
       
   687     QTest::newRow("simple 2") << dest
       
   688                               << QRegion(10, 10, 10, 10)
       
   689                               << QRegion(10, 10, 10, 10);
       
   690 
       
   691     rects.clear();
       
   692     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 15, 10);
       
   693     dest.setRects(rects.constData(), rects.size());
       
   694     QTest::newRow("merge 1") << dest
       
   695                              << QRegion(10, 10, 10, 20)
       
   696                              << QRegion(10, 10, 10, 20);
       
   697 
       
   698     rects.clear();
       
   699     rects << QRect(11, 11, 218, 117) << QRect(11, 128, 218, 27)
       
   700           << QRect(264, 128, 122, 27) << QRect(11, 155, 218, 43)
       
   701           << QRect(11, 198, 218, 27) << QRect(264, 198, 122, 27)
       
   702           << QRect(11, 225, 218, 221);
       
   703     dest.setRects(rects.constData(), rects.size());
       
   704     QTest::newRow("merge 2") << dest << QRegion(11, 11, 218, 458)
       
   705                              << QRegion(11, 11, 218, 435);
       
   706 
       
   707     rects.clear();
       
   708     rects << QRect(0, 0, 10, 10) << QRect(20, 0, 10, 10);
       
   709     dest.setRects(rects.constData(), rects.size());
       
   710     QTest::newRow("empty 3") << dest << QRegion(11, 0, 5, 5) << QRegion();
       
   711 
       
   712     QTest::newRow("extents check") << dest << QRegion(0, 0, 15, 15)
       
   713                                    << QRegion(0, 0, 10, 10);
       
   714 
       
   715     rects.clear();
       
   716     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 10, 10)
       
   717           << QRect(30, 20, 10, 10) << QRect(10, 30, 10, 10);
       
   718     dest.setRects(rects.constData(), rects.size());
       
   719     rects.clear();
       
   720     rects << QRect(10, 10, 10, 10) << QRect(10, 20, 10, 10)
       
   721           << QRect(30, 20, 10, 10);
       
   722     QRegion expected;
       
   723     expected.setRects(rects.constData(), rects.size());
       
   724     QTest::newRow("dont merge") << dest << QRegion(0, 0, 100, 30)
       
   725                                 << expected;
       
   726 }
       
   727 
       
   728 void tst_QRegion::operator_intersect()
       
   729 {
       
   730     QFETCH(QRegion, r1);
       
   731     QFETCH(QRegion, r2);
       
   732     QFETCH(QRegion, expected);
       
   733 
       
   734     if ((r1 & r2) != expected) {
       
   735         qDebug() << "r1 & r2" << (r1 & r2);
       
   736         qDebug() << "expected" << expected;
       
   737     }
       
   738     QCOMPARE(r1 & r2, expected);
       
   739 
       
   740     if ((r2 & r1) != expected) {
       
   741         qDebug() << "r2 & r1" << (r2 & r1);
       
   742         qDebug() << "expected" << expected;
       
   743     }
       
   744     QCOMPARE(r2 & r1, expected);
       
   745 
       
   746     r1 &= r2;
       
   747     QCOMPARE(r1, expected);
       
   748 }
       
   749 
       
   750 void tst_QRegion::operator_xor_data()
       
   751 {
       
   752     QTest::addColumn<QRegion>("dest");
       
   753     QTest::addColumn<QRegion>("arg");
       
   754     QTest::addColumn<QRegion>("expected");
       
   755 
       
   756     QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
       
   757     QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
       
   758                              << QRegion(QRect(10, 10, 10, 10));
       
   759     QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
       
   760                              << QRegion(QRect(10, 10, 10, 10));
       
   761 
       
   762     QRegion dest;
       
   763     QVector<QRect> rects;
       
   764     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
       
   765     dest.setRects(rects.constData(), rects.size());
       
   766     QTest::newRow("simple 1") << dest
       
   767                               << QRegion(22, 10, 10, 10)
       
   768                               << QRegion(10, 10, 10, 10);
       
   769     QTest::newRow("simple 2") << dest
       
   770                               << QRegion(10, 10, 10, 10)
       
   771                               << QRegion(22, 10, 10, 10);
       
   772     QTest::newRow("simple 3") << dest << dest << QRegion();
       
   773     QTest::newRow("simple 4") << QRegion(10, 10, 10, 10)
       
   774                               << QRegion(10, 10, 5, 10)
       
   775                               << QRegion(15, 10, 5, 10);
       
   776     QTest::newRow("simple 5") << QRegion(10, 10, 10, 10)
       
   777                               << QRegion(10, 10, 10, 5)
       
   778                               << QRegion(10, 15, 10, 5);
       
   779 
       
   780     const QRegion rgnA(0, 0, 100, 100);
       
   781     const QRegion rgnB(0, 0, 10, 10);
       
   782 
       
   783     QTest::newRow("simple 6") << rgnA
       
   784                               << rgnA - rgnB
       
   785                               << rgnB;
       
   786 
       
   787     QTest::newRow("simple 7") << rgnB
       
   788                               << rgnA
       
   789                               << rgnA - rgnB;
       
   790 }
       
   791 
       
   792 void tst_QRegion::operator_xor()
       
   793 {
       
   794     QFETCH(QRegion, dest);
       
   795     QFETCH(QRegion, arg);
       
   796     QFETCH(QRegion, expected);
       
   797 
       
   798     QCOMPARE(dest ^ arg, expected);
       
   799     QCOMPARE(dest.xored(arg), expected);
       
   800 
       
   801     dest ^= arg;
       
   802     QCOMPARE(dest, expected);
       
   803 }
       
   804 
       
   805 void tst_QRegion::numRects_data()
       
   806 {
       
   807     QTest::addColumn<QRegion>("region");
       
   808     QTest::addColumn<int>("expected");
       
   809 
       
   810     QTest::newRow("empty") << QRegion() << 0;
       
   811     QTest::newRow("rect") << QRegion(10, 10, 10, 10) << 1;
       
   812 
       
   813     QRegion dest;
       
   814     QVector<QRect> rects;
       
   815     rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
       
   816     dest.setRects(rects.constData(), rects.size());
       
   817 
       
   818     QTest::newRow("2 rects") << dest << rects.size();
       
   819 }
       
   820 
       
   821 void tst_QRegion::numRects()
       
   822 {
       
   823     QFETCH(QRegion, region);
       
   824     QFETCH(int, expected);
       
   825 
       
   826     QCOMPARE(region.numRects(), expected);
       
   827 }
       
   828 
       
   829 void tst_QRegion::isEmpty_data()
       
   830 {
       
   831     QTest::addColumn<QRegion>("region");
       
   832 
       
   833     QTest::newRow("QRegion") << QRegion();
       
   834 
       
   835     QVector<QRect> rects;
       
   836     rects << QRect(0, 0, 10, 10) << QRect(15, 0, 10, 10);
       
   837     QRegion r1;
       
   838     r1.setRects(rects.constData(), rects.size());
       
   839 
       
   840     QRegion r2;
       
   841     rects.clear();
       
   842     rects << QRect(0, 0, 12, 12) << QRect(15, 0, 12, 12);
       
   843     r2.setRects(rects.constData(), rects.size());
       
   844     QTest::newRow("minus") << (r1 - r2);
       
   845 }
       
   846 
       
   847 void tst_QRegion::isEmpty()
       
   848 {
       
   849     QFETCH(QRegion, region);
       
   850 
       
   851     QVERIFY(region.isEmpty());
       
   852     QCOMPARE(region, QRegion());
       
   853     QCOMPARE(region.numRects(), 0);
       
   854     QCOMPARE(region.boundingRect(), QRect());
       
   855     QVERIFY(region.rects().isEmpty());
       
   856 }
       
   857 
       
   858 #ifdef Q_OS_WIN
       
   859 void tst_QRegion::handle()
       
   860 {
       
   861     QRegion r;
       
   862     HRGN hrgn = r.handle();
       
   863     QRegion r2(QRect(0,0,10,10));
       
   864     hrgn = r2.handle();
       
   865 }
       
   866 #endif
       
   867 
       
   868 #if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL)
       
   869 void tst_QRegion::clipRectangles()
       
   870 {
       
   871     QRegion region(30, 30, 30, 30);
       
   872     int num = 0;
       
   873     qt_getClipRects(region, num);
       
   874     QCOMPARE(num, 1);
       
   875 
       
   876     region += QRegion(10, 10, 10, 10);
       
   877     XRectangle *rects2 = static_cast<XRectangle *>(qt_getClipRects(region, num));
       
   878     QCOMPARE(num, 2);
       
   879 
       
   880     // Here's the important part (Y-sorted):
       
   881     QCOMPARE(int(rects2[0].y), 10);
       
   882     QCOMPARE(int(rects2[1].y), 30);
       
   883 }
       
   884 #endif
       
   885 
       
   886 void tst_QRegion::regionFromPath()
       
   887 {
       
   888     {
       
   889         QPainterPath path;
       
   890         path.addRect(0, 0, 10, 10);
       
   891         path.addRect(0, 100, 100, 1000);
       
   892 
       
   893         QRegion rgn(path.toFillPolygon().toPolygon());
       
   894         QCOMPARE(rgn.rects().size(), 2);
       
   895         QCOMPARE(rgn.rects().at(0), QRect(0, 0, 10, 10));
       
   896         QCOMPARE(rgn.rects().at(1), QRect(0, 100, 100, 1000));
       
   897 
       
   898         QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 1100));
       
   899     }
       
   900 
       
   901     {
       
   902         QPainterPath path;
       
   903         path.addRect(0, 0, 100, 100);
       
   904         path.addRect(10, 10, 80, 80);
       
   905 
       
   906         QRegion rgn(path.toFillPolygon().toPolygon());
       
   907         QCOMPARE(rgn.rects().size(), 4);
       
   908 
       
   909         QCOMPARE(rgn.rects().at(0), QRect(0, 0, 100, 10));
       
   910         QCOMPARE(rgn.rects().at(1), QRect(0, 10, 10, 80));
       
   911         QCOMPARE(rgn.rects().at(2), QRect(90, 10, 10, 80));
       
   912         QCOMPARE(rgn.rects().at(3), QRect(0, 90, 100, 10));
       
   913 
       
   914         QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 100));
       
   915     }
       
   916 }
       
   917 
       
   918 Q_DECLARE_METATYPE(QPainterPath)
       
   919 
       
   920 void tst_QRegion::regionToPath_data()
       
   921 {
       
   922     QTest::addColumn<QPainterPath>("path");
       
   923     {
       
   924         QPainterPath path;
       
   925         path.addRect(QRect(0, 0, 10, 10));
       
   926 
       
   927         QTest::newRow("Rectangle") << path;
       
   928     }
       
   929 
       
   930     {
       
   931         QPainterPath path;
       
   932         path.addRect(QRect(0, 0, 10, 10));
       
   933         path.addRect(QRect(20, 0, 10, 10));
       
   934 
       
   935         QTest::newRow("Two rects") << path;
       
   936     }
       
   937 
       
   938     {
       
   939         QPainterPath path;
       
   940         path.addEllipse(QRect(0, 0, 10, 10));
       
   941 
       
   942         QTest::newRow("Ellipse") << path;
       
   943     }
       
   944 
       
   945     {
       
   946         QPainterPath path;
       
   947         path.addRect(QRect(0, 0, 3, 8));
       
   948         path.addRect(QRect(6, 0, 3, 8));
       
   949         path.addRect(QRect(3, 3, 3, 2));
       
   950         path.addRect(QRect(12, 3, 3, 2));
       
   951 
       
   952         QTest::newRow("H-dot") << path;
       
   953     }
       
   954 
       
   955     {
       
   956         QPainterPath path;
       
   957         for (int y = 0; y <= 10; ++y) {
       
   958             for (int x = 0; x <= 10; ++x) {
       
   959                 if (!(y & 1) || ((x ^ y) & 1))
       
   960                     path.addRect(QRect(x, y, 1, 1));
       
   961             }
       
   962         }
       
   963 
       
   964         QTest::newRow("Grid") << path;
       
   965     }
       
   966 }
       
   967 
       
   968 #ifdef QT_BUILD_INTERNAL
       
   969 QT_BEGIN_NAMESPACE
       
   970 extern QPainterPath qt_regionToPath(const QRegion &region);
       
   971 QT_END_NAMESPACE
       
   972 #endif
       
   973 
       
   974 void tst_QRegion::regionToPath()
       
   975 {
       
   976 #ifdef QT_BUILD_INTERNAL
       
   977 
       
   978     QFETCH(QPainterPath, path);
       
   979 
       
   980     for (int i = 0; i < 360; i += 10) {
       
   981 
       
   982         QTransform transform;
       
   983         transform.scale(5, 5);
       
   984         transform.rotate(i);
       
   985 
       
   986         QPainterPath mapped = transform.map(path);
       
   987         QRegion region(mapped.toFillPolygon().toPolygon());
       
   988 
       
   989         QPainterPath a;
       
   990         a.addRegion(region);
       
   991 
       
   992         QPainterPath b = qt_regionToPath(region);
       
   993 
       
   994         QRect r = a.boundingRect().toAlignedRect();
       
   995         QImage ia(r.size(), QImage::Format_RGB32);
       
   996         ia.fill(0xffffffff);
       
   997         QImage ib = ia;
       
   998 
       
   999         QPainter p(&ia);
       
  1000         p.translate(-r.x(), -r.y());
       
  1001         p.fillPath(a, Qt::red);
       
  1002         p.end();
       
  1003         p.begin(&ib);
       
  1004         p.translate(-r.x(), -r.y());
       
  1005         p.fillPath(b, Qt::red);
       
  1006         p.end();
       
  1007 
       
  1008         QCOMPARE(ia, ib);
       
  1009         QCOMPARE(a.boundingRect(), b.boundingRect());
       
  1010     }
       
  1011 #endif
       
  1012 }
       
  1013 
       
  1014 QTEST_MAIN(tst_QRegion)
       
  1015 #include "tst_qregion.moc"