/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include "qtransform.h" #include #include class tst_QTransform : public QObject { Q_OBJECT private slots: void mapRect_data(); void mapToPolygon_data(); void mapRect(); void assignments(); void mapToPolygon(); void qhash(); void translate(); void scale(); void matrix(); void testOffset(); void types(); void types2_data(); void types2(); void scalarOps(); void transform(); void mapEmptyPath(); void boundingRect(); void controlPointRect(); void inverted_data(); void inverted(); void projectivePathMapping(); void mapInt(); void mapPathWithPoint(); private: void mapping_data(); }; Q_DECLARE_METATYPE(QTransform) Q_DECLARE_METATYPE(QTransform::TransformationType) void tst_QTransform::mapRect_data() { mapping_data(); // rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here. qreal deg = -45; QTest::newRow( "rot 45 a" ) << QTransform().rotate(deg) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -7, 14, 14 ) ); QTest::newRow( "rot 45 b" ) << QTransform().rotate(deg) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 21, -14, 50, 49 ) ); QTest::newRow( "rot 45 c" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -71, 141, 142 ) ); QTest::newRow( "rot 45 d" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 212, -141, 495, 495 ) ); deg = 45; QTest::newRow( "rot -45 a" ) << QTransform().rotate(deg) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -7, 0, 14, 14 ) ); QTest::newRow( "rot -45 b" ) << QTransform().rotate(deg) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -35, 21, 49, 50 ) ); QTest::newRow( "rot -45 c" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -71, 0, 142, 141 ) ); QTest::newRow( "rot -45 d" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -354, 212, 495, 495 ) ); } void tst_QTransform::mapToPolygon_data() { mapping_data(); } void tst_QTransform::mapping_data() { //create the testtable instance and define the elements QTest::addColumn("matrix"); QTest::addColumn("src"); QTest::addColumn("res"); //next we fill it with data // identity QTest::newRow( "identity" ) << QTransform() << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 10, 20, 30, 40 ) ); // scaling QTest::newRow( "scale 0" ) << QTransform().scale(2, 2) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 20, 40, 60, 80 ) ); QTest::newRow( "scale 1" ) << QTransform().scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 100, 200, 300, 400 ) ); // mirroring QTest::newRow( "mirror 0" ) << QTransform().scale(-1, 1) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -40, 20, 30, 40 ) ); QTest::newRow( "mirror 1" ) << QTransform().scale(1, -1) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 10, -60, 30, 40 ) ); QTest::newRow( "mirror 2" ) << QTransform().scale(-1, -1) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -40, -60, 30, 40 ) ); QTest::newRow( "mirror 3" ) << QTransform().scale(-2, -2) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -80, -120, 60, 80 ) ); QTest::newRow( "mirror 4" ) << QTransform().scale(-10, -10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -400, -600, 300, 400 ) ); QTest::newRow( "mirror 5" ) << QTransform().scale(-1, 1) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -30, 0, 30, 40 ) ); QTest::newRow( "mirror 6" ) << QTransform().scale(1, -1) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -40, 30, 40 ) ); QTest::newRow( "mirror 7" ) << QTransform().scale(-1, -1) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -30, -40, 30, 40 ) ); QTest::newRow( "mirror 8" ) << QTransform().scale(-2, -2) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -60, -80, 60, 80 ) ); QTest::newRow( "mirror 9" ) << QTransform().scale(-10, -10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -300, -400, 300, 400 ) ); // rotations float deg = 0.; QTest::newRow( "rot 0 a" ) << QTransform().rotate(deg) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); deg = 0.00001f; QTest::newRow( "rot 0 b" ) << QTransform().rotate(deg) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); deg = 0.; QTest::newRow( "rot 0 c" ) << QTransform().rotate(deg) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); deg = 0.00001f; QTest::newRow( "rot 0 d" ) << QTransform().rotate(deg) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); // rotations deg = -90.f; QTest::newRow( "rotscale 90 a" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -300, 400, 300 ) ); deg = -90.00001f; QTest::newRow( "rotscale 90 b" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -300, 400, 300 ) ); deg = -90.f; QTest::newRow( "rotscale 90 c" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -400, 400, 300 ) ); deg = -90.00001f; QTest::newRow( "rotscale 90 d" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -400, 400, 300 ) ); deg = 180.f; QTest::newRow( "rotscale 180 a" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -300, -400, 300, 400 ) ); deg = 180.000001f; QTest::newRow( "rotscale 180 b" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -300, -400, 300, 400 ) ); deg = 180.f; QTest::newRow( "rotscale 180 c" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -400, -600, 300, 400 ) ); deg = 180.000001f; QTest::newRow( "rotscale 180 d" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -400, -600, 300, 400 ) ); deg = -270.f; QTest::newRow( "rotscale 270 a" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -400, 0, 400, 300 ) ); deg = -270.0000001f; QTest::newRow( "rotscale 270 b" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -400, 0, 400, 300 ) ); deg = -270.f; QTest::newRow( "rotscale 270 c" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -600, 100, 400, 300 ) ); deg = -270.000001f; QTest::newRow( "rotscale 270 d" ) << QTransform().rotate(deg).scale(10, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -600, 100, 400, 300 ) ); } void tst_QTransform::mapRect() { QFETCH( QTransform, matrix ); QFETCH( QRect, src ); QFETCH( QPolygon, res ); QRect mapped = matrix.mapRect(src); QCOMPARE( mapped, res.boundingRect().adjusted(0, 0, -1, -1) ); QRectF r = matrix.mapRect(QRectF(src)); QRect ir(r.topLeft().toPoint(), r.bottomRight().toPoint() - QPoint(1, 1)); QCOMPARE( mapped, ir ); } void tst_QTransform::assignments() { QTransform m; m.scale(2, 3); m.rotate(45); m.shear(4, 5); QTransform c1(m); QCOMPARE(m.m11(), c1.m11()); QCOMPARE(m.m12(), c1.m12()); QCOMPARE(m.m21(), c1.m21()); QCOMPARE(m.m22(), c1.m22()); QCOMPARE(m.dx(), c1.dx()); QCOMPARE(m.dy(), c1.dy()); QTransform c2 = m; QCOMPARE(m.m11(), c2.m11()); QCOMPARE(m.m12(), c2.m12()); QCOMPARE(m.m21(), c2.m21()); QCOMPARE(m.m22(), c2.m22()); QCOMPARE(m.dx(), c2.dx()); QCOMPARE(m.dy(), c2.dy()); } void tst_QTransform::mapToPolygon() { QFETCH( QTransform, matrix ); QFETCH( QRect, src ); QFETCH( QPolygon, res ); QPolygon poly = matrix.mapToPolygon(src); // don't care about starting point bool equal = false; for (int i = 0; i < poly.size(); ++i) { QPolygon rot; for (int j = i; j < poly.size(); ++j) rot << poly[j]; for (int j = 0; j < i; ++j) rot << poly[j]; if (rot == res) equal = true; } QVERIFY(equal); } void tst_QTransform::qhash() { QMatrix m1; m1.shear(3.0, 2.0); m1.rotate(44); QMatrix m2 = m1; QTransform t1(m1); QTransform t2(m2); // not really much to test here, so just the bare minimum: QCOMPARE(qHash(m1), qHash(m2)); QCOMPARE(qHash(t1), qHash(t2)); } void tst_QTransform::translate() { QTransform m( 1, 2, 3, 4, 5, 6 ); QTransform res2( m ); QTransform res( 1, 2, 3, 4, 75, 106 ); m.translate( 10, 20 ); QVERIFY( m == res ); m.translate( -10, -20 ); QVERIFY( m == res2 ); QVERIFY( QTransform::fromTranslate( 0, 0 ).type() == QTransform::TxNone ); QVERIFY( QTransform::fromTranslate( 10, 0 ).type() == QTransform::TxTranslate ); QVERIFY( QTransform::fromTranslate( -1, 5 ) == QTransform().translate( -1, 5 )); QVERIFY( QTransform::fromTranslate( 0, 0 ) == QTransform()); } void tst_QTransform::scale() { QTransform m( 1, 2, 3, 4, 5, 6 ); QTransform res2( m ); QTransform res( 10, 20, 60, 80, 5, 6 ); m.scale( 10, 20 ); QVERIFY( m == res ); m.scale( 1./10., 1./20. ); QVERIFY( m == res2 ); QVERIFY( QTransform::fromScale( 1, 1 ).type() == QTransform::TxNone ); QVERIFY( QTransform::fromScale( 2, 4 ).type() == QTransform::TxScale ); QVERIFY( QTransform::fromScale( 2, 4 ) == QTransform().scale( 2, 4 )); QVERIFY( QTransform::fromScale( 1, 1 ) == QTransform()); } void tst_QTransform::matrix() { QMatrix mat1; mat1.scale(0.3, 0.7); mat1.translate(53.3, 94.4); mat1.rotate(45); QMatrix mat2; mat2.rotate(33); mat2.scale(0.6, 0.6); mat2.translate(13.333, 7.777); QTransform tran1(mat1); QTransform tran2(mat2); QTransform dummy; dummy.setMatrix(mat1.m11(), mat1.m12(), 0, mat1.m21(), mat1.m22(), 0, mat1.dx(), mat1.dy(), 1); QCOMPARE(tran1, dummy); QCOMPARE(tran1.inverted(), dummy.inverted()); QCOMPARE(tran1.inverted(), QTransform(mat1.inverted())); QCOMPARE(tran2.inverted(), QTransform(mat2.inverted())); QMatrix mat3 = mat1 * mat2; QTransform tran3 = tran1 * tran2; QCOMPARE(QTransform(mat3), tran3); /* QMatrix::operator==() doesn't use qFuzzyCompare(), which * on win32-g++ results in a failure. So we work around it by * calling QTranform::operator==(), which performs a fuzzy compare. */ QCOMPARE(QTransform(mat3), QTransform(tran3.toAffine())); QTransform tranInv = tran1.inverted(); QMatrix matInv = mat1.inverted(); QRect rect(43, 70, 200, 200); QPoint pt(43, 66); QCOMPARE(tranInv.map(pt), matInv.map(pt)); QCOMPARE(tranInv.map(pt), matInv.map(pt)); QPainterPath path; path.moveTo(55, 60); path.lineTo(110, 110); path.quadTo(220, 50, 10, 20); path.closeSubpath(); QCOMPARE(tranInv.map(path), matInv.map(path)); } void tst_QTransform::testOffset() { QTransform trans; const QMatrix &aff = trans.toAffine(); QCOMPARE((void*)(&aff), (void*)(&trans)); } void tst_QTransform::types() { QTransform m1; QCOMPARE(m1.type(), QTransform::TxNone); m1.translate(1.0f, 0.0f); QCOMPARE(m1.type(), QTransform::TxTranslate); QCOMPARE(m1.inverted().type(), QTransform::TxTranslate); m1.scale(1.0f, 2.0f); QCOMPARE(m1.type(), QTransform::TxScale); QCOMPARE(m1.inverted().type(), QTransform::TxScale); m1.rotate(45.0f); QCOMPARE(m1.type(), QTransform::TxRotate); QCOMPARE(m1.inverted().type(), QTransform::TxRotate); m1.shear(0.5f, 0.25f); QCOMPARE(m1.type(), QTransform::TxShear); QCOMPARE(m1.inverted().type(), QTransform::TxShear); m1.rotate(45.0f, Qt::XAxis); QCOMPARE(m1.type(), QTransform::TxProject); m1.shear(0.5f, 0.25f); QCOMPARE(m1.type(), QTransform::TxProject); m1.rotate(45.0f); QCOMPARE(m1.type(), QTransform::TxProject); m1.scale(1.0f, 2.0f); QCOMPARE(m1.type(), QTransform::TxProject); m1.translate(1.0f, 0.0f); QCOMPARE(m1.type(), QTransform::TxProject); QTransform m2(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxTranslate); QCOMPARE((m1 * m2).type(), QTransform::TxProject); m1 *= QTransform(); QCOMPARE(m1.type(), QTransform::TxProject); m1 *= QTransform(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); QCOMPARE(m1.type(), QTransform::TxProject); m2.reset(); QCOMPARE(m2.type(), QTransform::TxNone); m2.setMatrix(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxNone); m2 *= QTransform(); QCOMPARE(m2.type(), QTransform::TxNone); m2.setMatrix(2.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxScale); m2 *= QTransform(); QCOMPARE(m2.type(), QTransform::TxScale); m2.setMatrix(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxRotate); m2 *= QTransform(); QCOMPARE(m2.type(), QTransform::TxRotate); m2.setMatrix(1.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxProject); m2 *= QTransform(); QCOMPARE(m2.type(), QTransform::TxProject); m2.setMatrix(1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxShear); m2 *= m2.inverted(); QCOMPARE(m2.type(), QTransform::TxNone); m2.translate(5.0f, 5.0f); m2.rotate(45.0f); m2.rotate(-45.0f); QCOMPARE(m2.type(), QTransform::TxTranslate); m2.scale(2.0f, 3.0f); m2.shear(1.0f, 0.0f); m2.shear(-1.0f, 0.0f); QCOMPARE(m2.type(), QTransform::TxScale); m2 *= QTransform(1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxShear); m2 *= QTransform(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); QCOMPARE(m2.type(), QTransform::TxShear); QTransform m3(1.8f, 0.0f, 0.0f, 0.0f, 1.8f, 0.0f, 0.0f, 0.0f, 1.0f); QCOMPARE(m3.type(), QTransform::TxScale); m3.translate(5.0f, 5.0f); QCOMPARE(m3.type(), QTransform::TxScale); QCOMPARE(m3.inverted().type(), QTransform::TxScale); m3.setMatrix(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 2.0f); QCOMPARE(m3.type(), QTransform::TxProject); m3.setMatrix(0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f); QCOMPARE(m3.type(), QTransform::TxProject); QTransform m4; m4.scale(5, 5); m4.translate(4, 2); m4.rotate(45); QCOMPARE(m4.type(), QTransform::TxRotate); QTransform m5; m5.scale(5, 5); m5 = m5.adjoint() / m5.determinant(); QCOMPARE(m5.type(), QTransform::TxScale); } void tst_QTransform::types2_data() { QTest::addColumn("t1"); QTest::addColumn("type"); QTest::newRow( "identity" ) << QTransform() << QTransform::TxNone; QTest::newRow( "translate" ) << QTransform().translate(10, -0.1) << QTransform::TxTranslate; QTest::newRow( "scale" ) << QTransform().scale(10, -0.1) << QTransform::TxScale; QTest::newRow( "rotate" ) << QTransform().rotate(10) << QTransform::TxRotate; QTest::newRow( "shear" ) << QTransform().shear(10, -0.1) << QTransform::TxShear; QTest::newRow( "project" ) << QTransform().rotate(10, Qt::XAxis) << QTransform::TxProject; QTest::newRow( "combined" ) << QTransform().translate(10, -0.1).scale(10, -0.1).rotate(10, Qt::YAxis) << QTransform::TxProject; } void tst_QTransform::types2() { #define CHECKTXTYPE(func) { QTransform t2(func); \ QTransform t3(t2.m11(), t2.m12(), t2.m13(), t2.m21(), t2.m22(), t2.m23(), t2.m31(), t2.m32(), t2.m33()); \ QVERIFY2(t3.type() == t2.type(), #func); \ } QFETCH( QTransform, t1 ); QFETCH( QTransform::TransformationType, type ); Q_ASSERT(t1.type() == type); CHECKTXTYPE(t1.adjoint()); CHECKTXTYPE(t1.inverted()); CHECKTXTYPE(t1.transposed()); #undef CHECKTXTYPE } void tst_QTransform::scalarOps() { QTransform t; QCOMPARE(t.m11(), 1.); QCOMPARE(t.m33(), 1.); QCOMPARE(t.m21(), 0.); t = QTransform() + 3; QCOMPARE(t.m11(), 4.); QCOMPARE(t.m33(), 4.); QCOMPARE(t.m21(), 3.); t = t - 3; QCOMPARE(t.m11(), 1.); QCOMPARE(t.m33(), 1.); QCOMPARE(t.m21(), 0.); QCOMPARE(t.isIdentity(), true); t += 3; t = t * 2; QCOMPARE(t.m11(), 8.); QCOMPARE(t.m33(), 8.); QCOMPARE(t.m21(), 6.); } void tst_QTransform::transform() { QTransform t; t.rotate(30, Qt::YAxis); t.translate(15, 10); t.scale(2, 2); t.rotate(30); t.shear(0.5, 0.5); QTransform a, b, c, d, e; a.rotate(30, Qt::YAxis); b.translate(15, 10); c.scale(2, 2); d.rotate(30); e.shear(0.5, 0.5); QVERIFY(qFuzzyCompare(t, e * d * c * b * a)); } void tst_QTransform::mapEmptyPath() { QPainterPath path; path.moveTo(10, 10); path.lineTo(10, 10); QCOMPARE(QTransform().map(path), path); } void tst_QTransform::boundingRect() { QPainterPath path; path.moveTo(10, 10); path.lineTo(10, 10); QCOMPARE(path.boundingRect(), QRectF(10, 10, 0, 0)); } void tst_QTransform::controlPointRect() { QPainterPath path; path.moveTo(10, 10); path.lineTo(10, 10); QCOMPARE(path.controlPointRect(), QRectF(10, 10, 0, 0)); } void tst_QTransform::inverted_data() { QTest::addColumn("matrix"); QTest::newRow("identity") << QTransform(); QTest::newRow("TxTranslate") << QTransform().translate(200, 10); QTest::newRow("TxScale") << QTransform().scale(5, 2); QTest::newRow("TxTranslate TxScale") << QTransform().translate(100, -10).scale(40, 2); QTest::newRow("TxScale TxTranslate") << QTransform().scale(40, 2).translate(100, -10); QTest::newRow("TxRotate") << QTransform().rotate(40, Qt::ZAxis); QTest::newRow("TxRotate TxScale") << QTransform().rotate(60, Qt::ZAxis).scale(2, 0.25); QTest::newRow("TxScale TxRotate") << QTransform().scale(2, 0.25).rotate(30, Qt::ZAxis); QTest::newRow("TxRotate TxScale TxTranslate") << QTransform().rotate(60, Qt::ZAxis).scale(2, 0.25).translate(200, -3000); QTest::newRow("TxRotate TxTranslate TxScale") << QTransform().rotate(60, Qt::ZAxis).translate(200, -3000).scale(19, 77); QTest::newRow("TxShear") << QTransform().shear(10, 10); QTest::newRow("TxShear TxRotate") << QTransform().shear(10, 10).rotate(45, Qt::ZAxis); QTest::newRow("TxShear TxRotate TxScale") << QTransform().shear(10, 10).rotate(45, Qt::ZAxis).scale(19, 81); QTest::newRow("TxTranslate TxShear TxRotate TxScale") << QTransform().translate(150, -1).shear(10, 10).rotate(45, Qt::ZAxis).scale(19, 81); const qreal s = 500000; QTransform big; big.scale(s, s); QTest::newRow("big") << big; QTransform smallTransform; smallTransform.scale(1/s, 1/s); QTest::newRow("small") << smallTransform; } void tst_QTransform::inverted() { if (sizeof(qreal) != sizeof(double)) QSKIP("precision error if qreal is not double"); QFETCH(QTransform, matrix); const QTransform inverted = matrix.inverted(); QCOMPARE(matrix.isIdentity(), inverted.isIdentity()); QCOMPARE(matrix.type(), inverted.type()); QVERIFY((matrix * inverted).isIdentity()); QVERIFY((inverted * matrix).isIdentity()); } void tst_QTransform::projectivePathMapping() { QPainterPath path; path.addRect(-50, -50, 100, 100); const QRectF view(0, 0, 1024, 1024); QVERIFY(view.intersects(path.boundingRect())); for (int i = 0; i < 85; i += 5) { QTransform transform; transform.translate(512, 512); transform.rotate(i, Qt::YAxis); const QPainterPath mapped = transform.map(path); QVERIFY(view.intersects(mapped.boundingRect())); QVERIFY(transform.inverted().mapRect(view).intersects(path.boundingRect())); } } void tst_QTransform::mapInt() { int x = 0; int y = 0; QTransform::fromTranslate(10, 10).map(x, y, &x, &y); QCOMPARE(x, 10); QCOMPARE(y, 10); } void tst_QTransform::mapPathWithPoint() { QPainterPath p(QPointF(10, 10)); p = QTransform::fromTranslate(10, 10).map(p); QCOMPARE(p.currentPosition(), QPointF(20, 20)); } QTEST_APPLESS_MAIN(tst_QTransform) #include "tst_qtransform.moc"