|
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" |