tests/auto/qtransform/tst_qtransform.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
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 "qtransform.h"
       
    45 #include <math.h>
       
    46 #include <qpolygon.h>
       
    47 #include <qdebug.h>
       
    48 
       
    49 Q_DECLARE_METATYPE(QRect)
       
    50 
       
    51 //TESTED_CLASS=
       
    52 //TESTED_FILES=
       
    53 
       
    54 class tst_QTransform : public QObject
       
    55 {
       
    56     Q_OBJECT
       
    57 
       
    58 public:
       
    59     tst_QTransform();
       
    60     virtual ~tst_QTransform();
       
    61 
       
    62 
       
    63 public slots:
       
    64     void init();
       
    65     void cleanup();
       
    66 private slots:
       
    67     void mapRect_data();
       
    68     void operator_star_qrect_data();
       
    69     void mapToPolygon_data();
       
    70     void mapRect();
       
    71     void operator_star_qrect();
       
    72     void assignments();
       
    73     void mapToPolygon();
       
    74     void translate();
       
    75     void scale();
       
    76     void matrix();
       
    77     void testOffset();
       
    78     void types();
       
    79     void scalarOps();
       
    80     void transform();
       
    81     void mapEmptyPath();
       
    82     void boundingRect();
       
    83     void controlPointRect();
       
    84     void inverted_data();
       
    85     void inverted();
       
    86     void projectivePathMapping();
       
    87     void mapInt();
       
    88 
       
    89 private:
       
    90     void mapping_data();
       
    91 };
       
    92 
       
    93 Q_DECLARE_METATYPE(QTransform)
       
    94 Q_DECLARE_METATYPE(QPolygon)
       
    95 
       
    96 tst_QTransform::tst_QTransform()
       
    97 {
       
    98 }
       
    99 
       
   100 tst_QTransform::~tst_QTransform()
       
   101 {
       
   102 }
       
   103 
       
   104 void tst_QTransform::init()
       
   105 {
       
   106     // No initialisation is required
       
   107 }
       
   108 
       
   109 void tst_QTransform::cleanup()
       
   110 {
       
   111     // No cleanup is required.
       
   112 }
       
   113 
       
   114 #ifdef Q_OS_WIN32
       
   115 #define M_PI 3.14159265897932384626433832795f
       
   116 #endif
       
   117 
       
   118 void tst_QTransform::mapRect_data()
       
   119 {
       
   120     mapping_data();
       
   121 
       
   122     // rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here.
       
   123     qreal deg = -45;
       
   124     QTest::newRow( "rot 45 a" )
       
   125         << QTransform().rotate(deg)
       
   126         << QRect( 0, 0, 10, 10 )
       
   127         << QPolygon( QRect( 0, -7, 14, 14 ) );
       
   128     QTest::newRow( "rot 45 b" )
       
   129         << QTransform().rotate(deg)
       
   130         << QRect( 10, 20, 30, 40 )
       
   131         << QPolygon( QRect( 21, -14, 50, 49 ) );
       
   132     QTest::newRow( "rot 45 c" )
       
   133         << QTransform().rotate(deg).scale(10, 10)
       
   134         << QRect( 0, 0, 10, 10 )
       
   135         << QPolygon( QRect( 0, -71, 141, 142 ) );
       
   136     QTest::newRow( "rot 45 d" )
       
   137         << QTransform().rotate(deg).scale(10, 10)
       
   138         << QRect( 10, 20, 30, 40 )
       
   139         << QPolygon( QRect( 212, -141, 495, 495 ) );
       
   140 
       
   141     deg = 45;
       
   142     QTest::newRow( "rot -45 a" )
       
   143         << QTransform().rotate(deg)
       
   144         << QRect( 0, 0, 10, 10 )
       
   145         << QPolygon( QRect( -7, 0, 14, 14 ) );
       
   146     QTest::newRow( "rot -45 b" )
       
   147         << QTransform().rotate(deg)
       
   148         << QRect( 10, 20, 30, 40 )
       
   149         << QPolygon( QRect( -35, 21, 49, 50 ) );
       
   150     QTest::newRow( "rot -45 c" )
       
   151         << QTransform().rotate(deg).scale(10, 10)
       
   152         << QRect( 0, 0, 10, 10 )
       
   153         << QPolygon( QRect( -71, 0, 142, 141 ) );
       
   154     QTest::newRow( "rot -45 d" )
       
   155         << QTransform().rotate(deg).scale(10, 10)
       
   156         << QRect( 10, 20, 30, 40 )
       
   157         << QPolygon( QRect( -354, 212, 495, 495 ) );
       
   158 }
       
   159 
       
   160 void tst_QTransform::operator_star_qrect_data()
       
   161 {
       
   162     mapping_data();
       
   163 }
       
   164 
       
   165 void tst_QTransform::mapToPolygon_data()
       
   166 {
       
   167     mapping_data();
       
   168 }
       
   169 
       
   170 void tst_QTransform::mapping_data()
       
   171 {
       
   172     //create the testtable instance and define the elements
       
   173     QTest::addColumn<QTransform>("matrix");
       
   174     QTest::addColumn<QRect>("src");
       
   175     QTest::addColumn<QPolygon>("res");
       
   176 
       
   177     //next we fill it with data
       
   178 
       
   179     // identity
       
   180     QTest::newRow( "identity" )
       
   181         << QTransform()
       
   182         << QRect( 10, 20, 30, 40 )
       
   183         << QPolygon( QRect( 10, 20, 30, 40 ) );
       
   184     // scaling
       
   185     QTest::newRow( "scale 0" )
       
   186         << QTransform().scale(2, 2)
       
   187         << QRect( 10, 20, 30, 40 )
       
   188         << QPolygon( QRect( 20, 40, 60, 80 ) );
       
   189     QTest::newRow( "scale 1" )
       
   190         << QTransform().scale(10, 10)
       
   191         << QRect( 10, 20, 30, 40 )
       
   192         << QPolygon( QRect( 100, 200, 300, 400 ) );
       
   193     // mirroring
       
   194     QTest::newRow( "mirror 0" )
       
   195         << QTransform().scale(-1, 1)
       
   196         << QRect( 10, 20, 30, 40 )
       
   197         << QPolygon( QRect( -40, 20, 30, 40 ) );
       
   198     QTest::newRow( "mirror 1" )
       
   199         << QTransform().scale(1, -1)
       
   200         << QRect( 10, 20, 30, 40 )
       
   201         << QPolygon( QRect( 10, -60, 30, 40 ) );
       
   202     QTest::newRow( "mirror 2" )
       
   203         << QTransform().scale(-1, -1)
       
   204         << QRect( 10, 20, 30, 40 )
       
   205         << QPolygon( QRect( -40, -60, 30, 40 ) );
       
   206     QTest::newRow( "mirror 3" )
       
   207         << QTransform().scale(-2, -2)
       
   208         << QRect( 10, 20, 30, 40 )
       
   209         << QPolygon( QRect( -80, -120, 60, 80 ) );
       
   210     QTest::newRow( "mirror 4" )
       
   211         << QTransform().scale(-10, -10)
       
   212         << QRect( 10, 20, 30, 40 )
       
   213         << QPolygon( QRect( -400, -600, 300, 400 ) );
       
   214     QTest::newRow( "mirror 5" )
       
   215         << QTransform().scale(-1, 1)
       
   216         << QRect( 0, 0, 30, 40 )
       
   217         << QPolygon( QRect( -30, 0, 30, 40 ) );
       
   218     QTest::newRow( "mirror 6" )
       
   219         << QTransform().scale(1, -1)
       
   220         << QRect( 0, 0, 30, 40 )
       
   221         << QPolygon( QRect( 0, -40, 30, 40 ) );
       
   222     QTest::newRow( "mirror 7" )
       
   223         << QTransform().scale(-1, -1)
       
   224         << QRect( 0, 0, 30, 40 )
       
   225         << QPolygon( QRect( -30, -40, 30, 40 ) );
       
   226     QTest::newRow( "mirror 8" )
       
   227         << QTransform().scale(-2, -2)
       
   228         << QRect( 0, 0, 30, 40 )
       
   229         << QPolygon( QRect( -60, -80, 60, 80 ) );
       
   230     QTest::newRow( "mirror 9" )
       
   231         << QTransform().scale(-10, -10) << QRect( 0, 0, 30, 40 )
       
   232         << QPolygon( QRect( -300, -400, 300, 400 ) );
       
   233 
       
   234     // rotations
       
   235     float deg = 0.;
       
   236     QTest::newRow( "rot 0 a" )
       
   237         << QTransform().rotate(deg)
       
   238         << QRect( 0, 0, 30, 40 )
       
   239         << QPolygon ( QRect( 0, 0, 30, 40 ) );
       
   240     deg = 0.00001f;
       
   241     QTest::newRow( "rot 0 b" )
       
   242         << QTransform().rotate(deg)
       
   243         << QRect( 0, 0, 30, 40 )
       
   244         << QPolygon ( QRect( 0, 0, 30, 40 ) );
       
   245     deg = 0.;
       
   246     QTest::newRow( "rot 0 c" )
       
   247         << QTransform().rotate(deg)
       
   248         << QRect( 10, 20, 30, 40 )
       
   249         << QPolygon ( QRect( 10, 20, 30, 40 ) );
       
   250     deg = 0.00001f;
       
   251     QTest::newRow( "rot 0 d" )
       
   252         << QTransform().rotate(deg)
       
   253         << QRect( 10, 20, 30, 40 )
       
   254         << QPolygon ( QRect( 10, 20, 30, 40 ) );
       
   255 
       
   256     // rotations
       
   257     deg = -90.f;
       
   258     QTest::newRow( "rotscale 90 a" )
       
   259         << QTransform().rotate(deg).scale(10, 10)
       
   260         << QRect( 0, 0, 30, 40 )
       
   261         << QPolygon( QRect( 0, -300, 400, 300 ) );
       
   262     deg = -90.00001f;
       
   263     QTest::newRow( "rotscale 90 b" )
       
   264         << QTransform().rotate(deg).scale(10, 10)
       
   265         << QRect( 0, 0, 30, 40 )
       
   266         << QPolygon( QRect( 0, -300, 400, 300 ) );
       
   267     deg = -90.f;
       
   268     QTest::newRow( "rotscale 90 c" )
       
   269         << QTransform().rotate(deg).scale(10, 10)
       
   270         << QRect( 10, 20, 30, 40 )
       
   271         << QPolygon( QRect( 200, -400, 400, 300 ) );
       
   272     deg = -90.00001f;
       
   273     QTest::newRow( "rotscale 90 d" )
       
   274         << QTransform().rotate(deg).scale(10, 10)
       
   275         << QRect( 10, 20, 30, 40 )
       
   276         << QPolygon( QRect( 200, -400, 400, 300 ) );
       
   277 
       
   278     deg = 180.f;
       
   279     QTest::newRow( "rotscale 180 a" )
       
   280         << QTransform().rotate(deg).scale(10, 10)
       
   281         << QRect( 0, 0, 30, 40 )
       
   282         << QPolygon( QRect( -300, -400, 300, 400 ) );
       
   283     deg = 180.000001f;
       
   284     QTest::newRow( "rotscale 180 b" )
       
   285         << QTransform().rotate(deg).scale(10, 10)
       
   286         << QRect( 0, 0, 30, 40 )
       
   287         << QPolygon( QRect( -300, -400, 300, 400 ) );
       
   288     deg = 180.f;
       
   289     QTest::newRow( "rotscale 180 c" )
       
   290         << QTransform().rotate(deg).scale(10, 10)
       
   291         << QRect( 10, 20, 30, 40 )
       
   292         << QPolygon( QRect( -400, -600, 300, 400 ) );
       
   293     deg = 180.000001f;
       
   294     QTest::newRow( "rotscale 180 d" )
       
   295         << QTransform().rotate(deg).scale(10, 10)
       
   296         << QRect( 10, 20, 30, 40 )
       
   297         << QPolygon( QRect( -400, -600, 300, 400 ) );
       
   298 
       
   299     deg = -270.f;
       
   300     QTest::newRow( "rotscale 270 a" )
       
   301         << QTransform().rotate(deg).scale(10, 10)
       
   302         << QRect( 0, 0, 30, 40 )
       
   303         << QPolygon( QRect( -400, 0, 400, 300 ) );
       
   304     deg = -270.0000001f;
       
   305     QTest::newRow( "rotscale 270 b" )
       
   306         << QTransform().rotate(deg).scale(10, 10)
       
   307         << QRect( 0, 0, 30, 40 )
       
   308         << QPolygon( QRect( -400, 0, 400, 300 ) );
       
   309     deg = -270.f;
       
   310     QTest::newRow( "rotscale 270 c" )
       
   311         << QTransform().rotate(deg).scale(10, 10)
       
   312         << QRect( 10, 20, 30, 40 )
       
   313         << QPolygon( QRect( -600, 100, 400, 300 ) );
       
   314     deg = -270.000001f;
       
   315     QTest::newRow( "rotscale 270 d" )
       
   316         << QTransform().rotate(deg).scale(10, 10)
       
   317         << QRect( 10, 20, 30, 40 )
       
   318         << QPolygon( QRect( -600, 100, 400, 300 ) );
       
   319 }
       
   320 
       
   321 void tst_QTransform::mapRect()
       
   322 {
       
   323     QFETCH( QTransform, matrix );
       
   324     QFETCH( QRect, src );
       
   325     QFETCH( QPolygon, res );
       
   326     QRect mapped = matrix.mapRect(src);
       
   327     QCOMPARE( mapped, res.boundingRect().adjusted(0, 0, -1, -1) );
       
   328 
       
   329     QRectF r = matrix.mapRect(QRectF(src));
       
   330     QRect ir(r.topLeft().toPoint(), r.bottomRight().toPoint() - QPoint(1, 1));
       
   331     QCOMPARE( mapped, ir );
       
   332 }
       
   333 
       
   334 void tst_QTransform::operator_star_qrect()
       
   335 {
       
   336 #if 0
       
   337     QFETCH( QTransform, matrix );
       
   338     QFETCH( QRect, src );
       
   339     QFETCH( QPolygon, res );
       
   340 
       
   341     QCOMPARE( (matrix * src), QRegion(res) );
       
   342 #endif
       
   343 }
       
   344 
       
   345 void tst_QTransform::assignments()
       
   346 {
       
   347     QTransform m;
       
   348     m.scale(2, 3);
       
   349     m.rotate(45);
       
   350     m.shear(4, 5);
       
   351 
       
   352     QTransform c1(m);
       
   353 
       
   354     QCOMPARE(m.m11(), c1.m11());
       
   355     QCOMPARE(m.m12(), c1.m12());
       
   356     QCOMPARE(m.m21(), c1.m21());
       
   357     QCOMPARE(m.m22(), c1.m22());
       
   358     QCOMPARE(m.dx(), c1.dx());
       
   359     QCOMPARE(m.dy(), c1.dy());
       
   360 
       
   361     QTransform c2 = m;
       
   362     QCOMPARE(m.m11(), c2.m11());
       
   363     QCOMPARE(m.m12(), c2.m12());
       
   364     QCOMPARE(m.m21(), c2.m21());
       
   365     QCOMPARE(m.m22(), c2.m22());
       
   366     QCOMPARE(m.dx(),  c2.dx());
       
   367     QCOMPARE(m.dy(),  c2.dy());
       
   368 }
       
   369 
       
   370 
       
   371 void tst_QTransform::mapToPolygon()
       
   372 {
       
   373     QFETCH( QTransform, matrix );
       
   374     QFETCH( QRect, src );
       
   375     QFETCH( QPolygon, res );
       
   376 
       
   377     QPolygon poly = matrix.mapToPolygon(src);
       
   378 
       
   379     // don't care about starting point
       
   380     bool equal = false;
       
   381     for (int i = 0; i < poly.size(); ++i) {
       
   382         QPolygon rot;
       
   383         for (int j = i; j < poly.size(); ++j)
       
   384             rot << poly[j];
       
   385         for (int j = 0; j < i; ++j)
       
   386             rot << poly[j];
       
   387         if (rot == res)
       
   388             equal = true;
       
   389     }
       
   390 
       
   391     QVERIFY(equal);
       
   392 }
       
   393 
       
   394 
       
   395 void tst_QTransform::translate()
       
   396 {
       
   397     QTransform m( 1, 2, 3, 4, 5, 6 );
       
   398     QTransform res2( m );
       
   399     QTransform res( 1, 2, 3, 4, 75, 106 );
       
   400     m.translate( 10,  20 );
       
   401     QVERIFY( m == res );
       
   402     m.translate( -10,  -20 );
       
   403     QVERIFY( m == res2 );
       
   404     QVERIFY( QTransform::fromTranslate( 0, 0 ).type() == QTransform::TxNone );
       
   405     QVERIFY( QTransform::fromTranslate( 10, 0 ).type() == QTransform::TxTranslate );
       
   406     QVERIFY( QTransform::fromTranslate( -1, 5 ) == QTransform().translate( -1, 5 ));
       
   407     QVERIFY( QTransform::fromTranslate( 0, 0 ) == QTransform());
       
   408 }
       
   409 
       
   410 void tst_QTransform::scale()
       
   411 {
       
   412     QTransform m( 1, 2, 3, 4, 5, 6 );
       
   413     QTransform res2( m );
       
   414     QTransform res( 10, 20, 60, 80, 5, 6 );
       
   415     m.scale( 10,  20 );
       
   416     QVERIFY( m == res );
       
   417     m.scale( 1./10.,  1./20. );
       
   418     QVERIFY( m == res2 );
       
   419     QVERIFY( QTransform::fromScale( 1, 1 ).type() == QTransform::TxNone );
       
   420     QVERIFY( QTransform::fromScale( 2, 4 ).type() == QTransform::TxScale );
       
   421     QVERIFY( QTransform::fromScale( 2, 4 ) == QTransform().scale( 2, 4 ));
       
   422     QVERIFY( QTransform::fromScale( 1, 1 ) == QTransform());
       
   423 }
       
   424 
       
   425 void tst_QTransform::matrix()
       
   426 {
       
   427     QMatrix mat1;
       
   428     mat1.scale(0.3, 0.7);
       
   429     mat1.translate(53.3, 94.4);
       
   430     mat1.rotate(45);
       
   431 
       
   432     QMatrix mat2;
       
   433     mat2.rotate(33);
       
   434     mat2.scale(0.6, 0.6);
       
   435     mat2.translate(13.333, 7.777);
       
   436 
       
   437     QTransform tran1(mat1);
       
   438     QTransform tran2(mat2);
       
   439     QTransform dummy;
       
   440     dummy.setMatrix(mat1.m11(), mat1.m12(), 0,
       
   441                     mat1.m21(), mat1.m22(), 0,
       
   442                     mat1.dx(), mat1.dy(), 1);
       
   443 
       
   444     QVERIFY(tran1 == dummy);
       
   445     QVERIFY(tran1.inverted() == dummy.inverted());
       
   446     QVERIFY(tran1.inverted() == QTransform(mat1.inverted()));
       
   447     QVERIFY(tran2.inverted() == QTransform(mat2.inverted()));
       
   448 
       
   449     QMatrix mat3 = mat1 * mat2;
       
   450     QTransform tran3 = tran1 * tran2;
       
   451     QVERIFY(QTransform(mat3) == tran3);
       
   452 
       
   453     /* QMatrix::operator==() doesn't use qFuzzyCompare(), which
       
   454      * on win32-g++ results in a failure. So we work around it by
       
   455      * calling QTranform::operator==(), which performs a fuzzy compare. */
       
   456     QCOMPARE(QTransform(mat3), QTransform(tran3.toAffine()));
       
   457 
       
   458     QTransform tranInv = tran1.inverted();
       
   459     QMatrix   matInv = mat1.inverted();
       
   460 
       
   461     QRect rect(43, 70, 200, 200);
       
   462     QPoint pt(43, 66);
       
   463     QVERIFY(tranInv.map(pt) == matInv.map(pt));
       
   464     QVERIFY(tranInv.map(pt) == matInv.map(pt));
       
   465 
       
   466     QPainterPath path;
       
   467     path.moveTo(55, 60);
       
   468     path.lineTo(110, 110);
       
   469     path.quadTo(220, 50, 10, 20);
       
   470     path.closeSubpath();
       
   471     QVERIFY(tranInv.map(path) == matInv.map(path));
       
   472 }
       
   473 
       
   474 void tst_QTransform::testOffset()
       
   475 {
       
   476     QTransform trans;
       
   477     const QMatrix &aff = trans.toAffine();
       
   478     QCOMPARE((void*)(&aff), (void*)(&trans));
       
   479 }
       
   480 
       
   481 void tst_QTransform::types()
       
   482 {
       
   483     QTransform m1;
       
   484     QCOMPARE(m1.type(), QTransform::TxNone);
       
   485 
       
   486     m1.translate(1.0f, 0.0f);
       
   487     QCOMPARE(m1.type(), QTransform::TxTranslate);
       
   488     QCOMPARE(m1.inverted().type(), QTransform::TxTranslate);
       
   489 
       
   490     m1.scale(1.0f, 2.0f);
       
   491     QCOMPARE(m1.type(), QTransform::TxScale);
       
   492     QCOMPARE(m1.inverted().type(), QTransform::TxScale);
       
   493 
       
   494     m1.rotate(45.0f);
       
   495     QCOMPARE(m1.type(), QTransform::TxRotate);
       
   496     QCOMPARE(m1.inverted().type(), QTransform::TxRotate);
       
   497 
       
   498     m1.shear(0.5f, 0.25f);
       
   499     QCOMPARE(m1.type(), QTransform::TxShear);
       
   500     QCOMPARE(m1.inverted().type(), QTransform::TxShear);
       
   501 
       
   502     m1.rotate(45.0f, Qt::XAxis);
       
   503     QCOMPARE(m1.type(), QTransform::TxProject);
       
   504     m1.shear(0.5f, 0.25f);
       
   505     QCOMPARE(m1.type(), QTransform::TxProject);
       
   506     m1.rotate(45.0f);
       
   507     QCOMPARE(m1.type(), QTransform::TxProject);
       
   508     m1.scale(1.0f, 2.0f);
       
   509     QCOMPARE(m1.type(), QTransform::TxProject);
       
   510     m1.translate(1.0f, 0.0f);
       
   511     QCOMPARE(m1.type(), QTransform::TxProject);
       
   512 
       
   513     QTransform m2(1.0f, 0.0f, 0.0f,
       
   514                   0.0f, 1.0f, 0.0f,
       
   515                   -1.0f, -1.0f, 1.0f);
       
   516 
       
   517     QCOMPARE(m2.type(), QTransform::TxTranslate);
       
   518     QCOMPARE((m1 * m2).type(), QTransform::TxProject);
       
   519 
       
   520     m1 *= QTransform();
       
   521     QCOMPARE(m1.type(), QTransform::TxProject);
       
   522 
       
   523     m1 *= QTransform(1.0f, 0.0f, 0.0f,
       
   524                      0.0f, 1.0f, 0.0f,
       
   525                      1.0f, 0.0f, 1.0f);
       
   526     QCOMPARE(m1.type(), QTransform::TxProject);
       
   527 
       
   528     m2.reset();
       
   529     QCOMPARE(m2.type(), QTransform::TxNone);
       
   530 
       
   531     m2.setMatrix(1.0f, 0.0f, 0.0f,
       
   532                  0.0f, 1.0f, 0.0f,
       
   533                  0.0f, 0.0f, 1.0f);
       
   534     QCOMPARE(m2.type(), QTransform::TxNone);
       
   535 
       
   536     m2 *= QTransform();
       
   537     QCOMPARE(m2.type(), QTransform::TxNone);
       
   538 
       
   539     m2.setMatrix(2.0f, 0.0f, 0.0f,
       
   540                  0.0f, 1.0f, 0.0f,
       
   541                  0.0f, 0.0f, 1.0f);
       
   542     QCOMPARE(m2.type(), QTransform::TxScale);
       
   543     m2 *= QTransform();
       
   544     QCOMPARE(m2.type(), QTransform::TxScale);
       
   545 
       
   546     m2.setMatrix(0.0f, 1.0f, 0.0f,
       
   547                  1.0f, 0.0f, 0.0f,
       
   548                  0.0f, 1.0f, 1.0f);
       
   549     QCOMPARE(m2.type(), QTransform::TxRotate);
       
   550     m2 *= QTransform();
       
   551     QCOMPARE(m2.type(), QTransform::TxRotate);
       
   552 
       
   553     m2.setMatrix(1.0f, 0.0f, 0.5f,
       
   554                  0.0f, 1.0f, 0.0f,
       
   555                  0.0f, 0.0f, 1.0f);
       
   556     QCOMPARE(m2.type(), QTransform::TxProject);
       
   557     m2 *= QTransform();
       
   558     QCOMPARE(m2.type(), QTransform::TxProject);
       
   559 
       
   560     m2.setMatrix(1.0f, 1.0f, 0.0f,
       
   561                  1.0f, 0.0f, 0.0f,
       
   562                  0.0f, 1.0f, 1.0f);
       
   563     QCOMPARE(m2.type(), QTransform::TxShear);
       
   564 
       
   565     m2 *= m2.inverted();
       
   566     QCOMPARE(m2.type(), QTransform::TxNone);
       
   567 
       
   568     m2.translate(5.0f, 5.0f);
       
   569     m2.rotate(45.0f);
       
   570     m2.rotate(-45.0f);
       
   571     QCOMPARE(m2.type(), QTransform::TxTranslate);
       
   572 
       
   573     m2.scale(2.0f, 3.0f);
       
   574     m2.shear(1.0f, 0.0f);
       
   575     m2.shear(-1.0f, 0.0f);
       
   576     QCOMPARE(m2.type(), QTransform::TxScale);
       
   577 
       
   578     m2 *= QTransform(1.0f, 1.0f, 0.0f,
       
   579                      0.0f, 1.0f, 0.0f,
       
   580                      0.0f, 0.0f, 1.0f);
       
   581     QCOMPARE(m2.type(), QTransform::TxShear);
       
   582 
       
   583     m2 *= QTransform(1.0f, 0.0f, 0.0f,
       
   584                      0.0f, 1.0f, 0.0f,
       
   585                      1.0f, 0.0f, 1.0f);
       
   586     QCOMPARE(m2.type(), QTransform::TxShear);
       
   587 
       
   588     QTransform m3(1.8f, 0.0f, 0.0f,
       
   589                   0.0f, 1.8f, 0.0f,
       
   590                   0.0f, 0.0f, 1.0f);
       
   591 
       
   592     QCOMPARE(m3.type(), QTransform::TxScale);
       
   593     m3.translate(5.0f, 5.0f);
       
   594     QCOMPARE(m3.type(), QTransform::TxScale);
       
   595     QCOMPARE(m3.inverted().type(), QTransform::TxScale);
       
   596 
       
   597     m3.setMatrix(1.0f, 0.0f, 0.0f,
       
   598                  0.0f, 1.0f, 0.0f,
       
   599                  0.0f, 0.0f, 2.0f);
       
   600     QCOMPARE(m3.type(), QTransform::TxProject);
       
   601 
       
   602     m3.setMatrix(0.0f, 2.0f, 0.0f,
       
   603                  1.0f, 0.0f, 0.0f,
       
   604                  0.0f, 0.0f, 2.0f);
       
   605     QCOMPARE(m3.type(), QTransform::TxProject);
       
   606 
       
   607     QTransform m4;
       
   608     m4.scale(5, 5);
       
   609     m4.translate(4, 2);
       
   610     m4.rotate(45);
       
   611 
       
   612     QCOMPARE(m4.type(), QTransform::TxRotate);
       
   613 }
       
   614 
       
   615 
       
   616 void tst_QTransform::scalarOps()
       
   617 {
       
   618     QTransform t;
       
   619     QCOMPARE(t.m11(), 1.);
       
   620     QCOMPARE(t.m33(), 1.);
       
   621     QCOMPARE(t.m21(), 0.);
       
   622 
       
   623     t = QTransform() + 3;
       
   624     QCOMPARE(t.m11(), 4.);
       
   625     QCOMPARE(t.m33(), 4.);
       
   626     QCOMPARE(t.m21(), 3.);
       
   627 
       
   628     t = t - 3;
       
   629     QCOMPARE(t.m11(), 1.);
       
   630     QCOMPARE(t.m33(), 1.);
       
   631     QCOMPARE(t.m21(), 0.);
       
   632     QCOMPARE(t.isIdentity(), true);
       
   633 
       
   634     t += 3;
       
   635     t = t * 2;
       
   636     QCOMPARE(t.m11(), 8.);
       
   637     QCOMPARE(t.m33(), 8.);
       
   638     QCOMPARE(t.m21(), 6.);
       
   639 }
       
   640 
       
   641 void tst_QTransform::transform()
       
   642 {
       
   643     QTransform t;
       
   644     t.rotate(30, Qt::YAxis);
       
   645     t.translate(15, 10);
       
   646     t.scale(2, 2);
       
   647     t.rotate(30);
       
   648     t.shear(0.5, 0.5);
       
   649 
       
   650     QTransform a, b, c, d, e;
       
   651     a.rotate(30, Qt::YAxis);
       
   652     b.translate(15, 10);
       
   653     c.scale(2, 2);
       
   654     d.rotate(30);
       
   655     e.shear(0.5, 0.5);
       
   656 
       
   657     QVERIFY(qFuzzyCompare(t, e * d * c * b * a));
       
   658 }
       
   659 
       
   660 void tst_QTransform::mapEmptyPath()
       
   661 {
       
   662     QPainterPath path;
       
   663     path.moveTo(10, 10);
       
   664     path.lineTo(10, 10);
       
   665     QCOMPARE(QTransform().map(path), path);
       
   666 }
       
   667 
       
   668 void tst_QTransform::boundingRect()
       
   669 {
       
   670     QPainterPath path;
       
   671     path.moveTo(10, 10);
       
   672     path.lineTo(10, 10);
       
   673     QCOMPARE(path.boundingRect(), QRectF(10, 10, 0, 0));
       
   674 }
       
   675 
       
   676 void tst_QTransform::controlPointRect()
       
   677 {
       
   678     QPainterPath path;
       
   679     path.moveTo(10, 10);
       
   680     path.lineTo(10, 10);
       
   681     QCOMPARE(path.controlPointRect(), QRectF(10, 10, 0, 0));
       
   682 }
       
   683 
       
   684 void tst_QTransform::inverted_data()
       
   685 {
       
   686     QTest::addColumn<QTransform>("matrix");
       
   687 
       
   688     QTest::newRow("identity")
       
   689         << QTransform();
       
   690 
       
   691     QTest::newRow("TxTranslate")
       
   692         << QTransform().translate(200, 10);
       
   693 
       
   694     QTest::newRow("TxScale")
       
   695         << QTransform().scale(5, 2);
       
   696 
       
   697     QTest::newRow("TxTranslate TxScale")
       
   698         << QTransform().translate(100, -10).scale(40, 2);
       
   699 
       
   700     QTest::newRow("TxScale TxTranslate")
       
   701         << QTransform().scale(40, 2).translate(100, -10);
       
   702 
       
   703     QTest::newRow("TxRotate")
       
   704         << QTransform().rotate(40, Qt::ZAxis);
       
   705 
       
   706     QTest::newRow("TxRotate TxScale")
       
   707         << QTransform().rotate(60, Qt::ZAxis).scale(2, 0.25);
       
   708 
       
   709     QTest::newRow("TxScale TxRotate")
       
   710         << QTransform().scale(2, 0.25).rotate(30, Qt::ZAxis);
       
   711 
       
   712     QTest::newRow("TxRotate TxScale TxTranslate")
       
   713         << QTransform().rotate(60, Qt::ZAxis).scale(2, 0.25).translate(200, -3000);
       
   714 
       
   715     QTest::newRow("TxRotate TxTranslate TxScale")
       
   716         << QTransform().rotate(60, Qt::ZAxis).translate(200, -3000).scale(19, 77);
       
   717 
       
   718     QTest::newRow("TxShear")
       
   719         << QTransform().shear(10, 10);
       
   720 
       
   721     QTest::newRow("TxShear TxRotate")
       
   722         << QTransform().shear(10, 10).rotate(45, Qt::ZAxis);
       
   723 
       
   724     QTest::newRow("TxShear TxRotate TxScale")
       
   725         << QTransform().shear(10, 10).rotate(45, Qt::ZAxis).scale(19, 81);
       
   726 
       
   727     QTest::newRow("TxTranslate TxShear TxRotate TxScale")
       
   728         << QTransform().translate(150, -1).shear(10, 10).rotate(45, Qt::ZAxis).scale(19, 81);
       
   729 
       
   730     const qreal s = 500000;
       
   731 
       
   732     QTransform big;
       
   733     big.scale(s, s);
       
   734 
       
   735     QTest::newRow("big") << big;
       
   736 
       
   737     QTransform small;
       
   738     small.scale(1/s, 1/s);
       
   739 
       
   740     QTest::newRow("small") << small;
       
   741 }
       
   742 
       
   743 void tst_QTransform::inverted()
       
   744 {
       
   745     if (sizeof(qreal) != sizeof(double))
       
   746         QSKIP("precision error if qreal is not double", SkipAll);
       
   747 
       
   748     QFETCH(QTransform, matrix);
       
   749 
       
   750     const QTransform inverted = matrix.inverted();
       
   751 
       
   752     QVERIFY(matrix.isIdentity() == inverted.isIdentity());
       
   753     QVERIFY(matrix.type() == inverted.type());
       
   754 
       
   755     QVERIFY((matrix * inverted).isIdentity());
       
   756     QVERIFY((inverted * matrix).isIdentity());
       
   757 }
       
   758 
       
   759 void tst_QTransform::projectivePathMapping()
       
   760 {
       
   761     QPainterPath path;
       
   762     path.addRect(-50, -50, 100, 100);
       
   763 
       
   764     const QRectF view(0, 0, 1024, 1024);
       
   765 
       
   766     QVERIFY(view.intersects(path.boundingRect()));
       
   767 
       
   768     for (int i = 0; i < 85; i += 5) {
       
   769         QTransform transform;
       
   770         transform.translate(512, 512);
       
   771         transform.rotate(i, Qt::YAxis);
       
   772 
       
   773         const QPainterPath mapped = transform.map(path);
       
   774 
       
   775         QVERIFY(view.intersects(mapped.boundingRect()));
       
   776         QVERIFY(transform.inverted().mapRect(view).intersects(path.boundingRect()));
       
   777     }
       
   778 }
       
   779 
       
   780 void tst_QTransform::mapInt()
       
   781 {
       
   782     int x = 0;
       
   783     int y = 0;
       
   784 
       
   785     QTransform::fromTranslate(10, 10).map(x, y, &x, &y);
       
   786 
       
   787     QCOMPARE(x, 10);
       
   788     QCOMPARE(y, 10);
       
   789 }
       
   790 
       
   791 QTEST_APPLESS_MAIN(tst_QTransform)
       
   792 
       
   793 
       
   794 #include "tst_qtransform.moc"