qtransform.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qtransform.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33#include "qtransform.h"-
34-
35#include "qdatastream.h"-
36#include "qdebug.h"-
37#include "qhashfunctions.h"-
38#include "qmatrix.h"-
39#include "qregion.h"-
40#include "qpainterpath.h"-
41#include "qpainterpath_p.h"-
42#include "qvariant.h"-
43#include <qmath.h>-
44#include <qnumeric.h>-
45-
46#include <private/qbezier_p.h>-
47-
48QT_BEGIN_NAMESPACE-
49-
50#define Q_NEAR_CLIP (sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001)-
51-
52#ifdef MAP-
53# undef MAP-
54#endif-
55#define MAP(x, y, nx, ny) \-
56 do { \-
57 qreal FX_ = x; \-
58 qreal FY_ = y; \-
59 switch(t) { \-
60 case TxNone: \-
61 nx = FX_; \-
62 ny = FY_; \-
63 break; \-
64 case TxTranslate: \-
65 nx = FX_ + affine._dx; \-
66 ny = FY_ + affine._dy; \-
67 break; \-
68 case TxScale: \-
69 nx = affine._m11 * FX_ + affine._dx; \-
70 ny = affine._m22 * FY_ + affine._dy; \-
71 break; \-
72 case TxRotate: \-
73 case TxShear: \-
74 case TxProject: \-
75 nx = affine._m11 * FX_ + affine._m21 * FY_ + affine._dx; \-
76 ny = affine._m12 * FX_ + affine._m22 * FY_ + affine._dy; \-
77 if (t == TxProject) { \-
78 qreal w = (m_13 * FX_ + m_23 * FY_ + m_33); \-
79 if (w < qreal(Q_NEAR_CLIP)) w = qreal(Q_NEAR_CLIP); \-
80 w = 1./w; \-
81 nx *= w; \-
82 ny *= w; \-
83 } \-
84 } \-
85 } while (0)-
86-
87/*!-
88 \class QTransform-
89 \brief The QTransform class specifies 2D transformations of a coordinate system.-
90 \since 4.3-
91 \ingroup painting-
92 \inmodule QtGui-
93-
94 A transformation specifies how to translate, scale, shear, rotate-
95 or project the coordinate system, and is typically used when-
96 rendering graphics.-
97-
98 QTransform differs from QMatrix in that it is a true 3x3 matrix,-
99 allowing perspective transformations. QTransform's toAffine()-
100 method allows casting QTransform to QMatrix. If a perspective-
101 transformation has been specified on the matrix, then the-
102 conversion will cause loss of data.-
103-
104 QTransform is the recommended transformation class in Qt.-
105-
106 A QTransform object can be built using the setMatrix(), scale(),-
107 rotate(), translate() and shear() functions. Alternatively, it-
108 can be built by applying \l {QTransform#Basic Matrix-
109 Operations}{basic matrix operations}. The matrix can also be-
110 defined when constructed, and it can be reset to the identity-
111 matrix (the default) using the reset() function.-
112-
113 The QTransform class supports mapping of graphic primitives: A given-
114 point, line, polygon, region, or painter path can be mapped to the-
115 coordinate system defined by \e this matrix using the map()-
116 function. In case of a rectangle, its coordinates can be-
117 transformed using the mapRect() function. A rectangle can also be-
118 transformed into a \e polygon (mapped to the coordinate system-
119 defined by \e this matrix), using the mapToPolygon() function.-
120-
121 QTransform provides the isIdentity() function which returns \c true if-
122 the matrix is the identity matrix, and the isInvertible() function-
123 which returns \c true if the matrix is non-singular (i.e. AB = BA =-
124 I). The inverted() function returns an inverted copy of \e this-
125 matrix if it is invertible (otherwise it returns the identity-
126 matrix), and adjoint() returns the matrix's classical adjoint.-
127 In addition, QTransform provides the determinant() function which-
128 returns the matrix's determinant.-
129-
130 Finally, the QTransform class supports matrix multiplication, addition-
131 and subtraction, and objects of the class can be streamed as well-
132 as compared.-
133-
134 \tableofcontents-
135-
136 \section1 Rendering Graphics-
137-
138 When rendering graphics, the matrix defines the transformations-
139 but the actual transformation is performed by the drawing routines-
140 in QPainter.-
141-
142 By default, QPainter operates on the associated device's own-
143 coordinate system. The standard coordinate system of a-
144 QPaintDevice has its origin located at the top-left position. The-
145 \e x values increase to the right; \e y values increase-
146 downward. For a complete description, see the \l {Coordinate-
147 System} {coordinate system} documentation.-
148-
149 QPainter has functions to translate, scale, shear and rotate the-
150 coordinate system without using a QTransform. For example:-
151-
152 \table 100%-
153 \row-
154 \li \inlineimage qtransform-simpletransformation.png-
155 \li-
156 \snippet transform/main.cpp 0-
157 \endtable-
158-
159 Although these functions are very convenient, it can be more-
160 efficient to build a QTransform and call QPainter::setTransform() if you-
161 want to perform more than a single transform operation. For-
162 example:-
163-
164 \table 100%-
165 \row-
166 \li \inlineimage qtransform-combinedtransformation.png-
167 \li-
168 \snippet transform/main.cpp 1-
169 \endtable-
170-
171 \section1 Basic Matrix Operations-
172-
173 \image qtransform-representation.png-
174-
175 A QTransform object contains a 3 x 3 matrix. The \c m31 (\c dx) and-
176 \c m32 (\c dy) elements specify horizontal and vertical translation.-
177 The \c m11 and \c m22 elements specify horizontal and vertical scaling.-
178 The \c m21 and \c m12 elements specify horizontal and vertical \e shearing.-
179 And finally, the \c m13 and \c m23 elements specify horizontal and vertical-
180 projection, with \c m33 as an additional projection factor.-
181-
182 QTransform transforms a point in the plane to another point using the-
183 following formulas:-
184-
185 \snippet code/src_gui_painting_qtransform.cpp 0-
186-
187 The point \e (x, y) is the original point, and \e (x', y') is the-
188 transformed point. \e (x', y') can be transformed back to \e (x,-
189 y) by performing the same operation on the inverted() matrix.-
190-
191 The various matrix elements can be set when constructing the-
192 matrix, or by using the setMatrix() function later on. They can also-
193 be manipulated using the translate(), rotate(), scale() and-
194 shear() convenience functions. The currently set values can be-
195 retrieved using the m11(), m12(), m13(), m21(), m22(), m23(),-
196 m31(), m32(), m33(), dx() and dy() functions.-
197-
198 Translation is the simplest transformation. Setting \c dx and \c-
199 dy will move the coordinate system \c dx units along the X axis-
200 and \c dy units along the Y axis. Scaling can be done by setting-
201 \c m11 and \c m22. For example, setting \c m11 to 2 and \c m22 to-
202 1.5 will double the height and increase the width by 50%. The-
203 identity matrix has \c m11, \c m22, and \c m33 set to 1 (all others are set-
204 to 0) mapping a point to itself. Shearing is controlled by \c m12-
205 and \c m21. Setting these elements to values different from zero-
206 will twist the coordinate system. Rotation is achieved by-
207 setting both the shearing factors and the scaling factors. Perspective-
208 transformation is achieved by setting both the projection factors and-
209 the scaling factors.-
210-
211 Here's the combined transformations example using basic matrix-
212 operations:-
213-
214 \table 100%-
215 \row-
216 \li \inlineimage qtransform-combinedtransformation2.png-
217 \li-
218 \snippet transform/main.cpp 2-
219 \endtable-
220-
221 \sa QPainter, {Coordinate System}, {painting/affine}{Affine-
222 Transformations Example}, {Transformations Example}-
223*/-
224-
225/*!-
226 \enum QTransform::TransformationType-
227-
228 \value TxNone-
229 \value TxTranslate-
230 \value TxScale-
231 \value TxRotate-
232 \value TxShear-
233 \value TxProject-
234*/-
235-
236/*!-
237 \fn QTransform::QTransform(Qt::Initialization)-
238 \internal-
239*/-
240-
241/*!-
242 Constructs an identity matrix.-
243-
244 All elements are set to zero except \c m11 and \c m22 (specifying-
245 the scale) and \c m33 which are set to 1.-
246-
247 \sa reset()-
248*/-
249QTransform::QTransform()-
250 : affine(true)-
251 , m_13(0), m_23(0), m_33(1)-
252 , m_type(TxNone)-
253 , m_dirty(TxNone)-
254 , d(Q_NULLPTR)-
255{-
256}
never executed: end of block
0
257-
258/*!-
259 \fn QTransform::QTransform(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33)-
260-
261 Constructs a matrix with the elements, \a m11, \a m12, \a m13,-
262 \a m21, \a m22, \a m23, \a m31, \a m32, \a m33.-
263-
264 \sa setMatrix()-
265*/-
266QTransform::QTransform(qreal h11, qreal h12, qreal h13,-
267 qreal h21, qreal h22, qreal h23,-
268 qreal h31, qreal h32, qreal h33)-
269 : affine(h11, h12, h21, h22, h31, h32, true)-
270 , m_13(h13), m_23(h23), m_33(h33)-
271 , m_type(TxNone)-
272 , m_dirty(TxProject)-
273 , d(Q_NULLPTR)-
274{-
275}
never executed: end of block
0
276-
277/*!-
278 \fn QTransform::QTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)-
279-
280 Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a m22, \a dx and \a dy.-
281-
282 \sa setMatrix()-
283*/-
284QTransform::QTransform(qreal h11, qreal h12, qreal h21,-
285 qreal h22, qreal dx, qreal dy)-
286 : affine(h11, h12, h21, h22, dx, dy, true)-
287 , m_13(0), m_23(0), m_33(1)-
288 , m_type(TxNone)-
289 , m_dirty(TxShear)-
290 , d(Q_NULLPTR)-
291{-
292}
never executed: end of block
0
293-
294/*!-
295 \fn QTransform::QTransform(const QMatrix &matrix)-
296-
297 Constructs a matrix that is a copy of the given \a matrix.-
298 Note that the \c m13, \c m23, and \c m33 elements are set to 0, 0,-
299 and 1 respectively.-
300 */-
301QTransform::QTransform(const QMatrix &mtx)-
302 : affine(mtx._m11, mtx._m12, mtx._m21, mtx._m22, mtx._dx, mtx._dy, true),-
303 m_13(0), m_23(0), m_33(1)-
304 , m_type(TxNone)-
305 , m_dirty(TxShear)-
306 , d(Q_NULLPTR)-
307{-
308}
never executed: end of block
0
309-
310/*!-
311 Returns the adjoint of this matrix.-
312*/-
313QTransform QTransform::adjoint() const-
314{-
315 qreal h11, h12, h13,-
316 h21, h22, h23,-
317 h31, h32, h33;-
318 h11 = affine._m22*m_33 - m_23*affine._dy;-
319 h21 = m_23*affine._dx - affine._m21*m_33;-
320 h31 = affine._m21*affine._dy - affine._m22*affine._dx;-
321 h12 = m_13*affine._dy - affine._m12*m_33;-
322 h22 = affine._m11*m_33 - m_13*affine._dx;-
323 h32 = affine._m12*affine._dx - affine._m11*affine._dy;-
324 h13 = affine._m12*m_23 - m_13*affine._m22;-
325 h23 = m_13*affine._m21 - affine._m11*m_23;-
326 h33 = affine._m11*affine._m22 - affine._m12*affine._m21;-
327-
328 return QTransform(h11, h12, h13,
never executed: return QTransform(h11, h12, h13, h21, h22, h23, h31, h32, h33, true);
0
329 h21, h22, h23,
never executed: return QTransform(h11, h12, h13, h21, h22, h23, h31, h32, h33, true);
0
330 h31, h32, h33, true);
never executed: return QTransform(h11, h12, h13, h21, h22, h23, h31, h32, h33, true);
0
331}-
332-
333/*!-
334 Returns the transpose of this matrix.-
335*/-
336QTransform QTransform::transposed() const-
337{-
338 QTransform t(affine._m11, affine._m21, affine._dx,-
339 affine._m12, affine._m22, affine._dy,-
340 m_13, m_23, m_33, true);-
341 t.m_type = m_type;-
342 t.m_dirty = m_dirty;-
343 return t;
never executed: return t;
0
344}-
345-
346/*!-
347 Returns an inverted copy of this matrix.-
348-
349 If the matrix is singular (not invertible), the returned matrix is-
350 the identity matrix. If \a invertible is valid (i.e. not 0), its-
351 value is set to true if the matrix is invertible, otherwise it is-
352 set to false.-
353-
354 \sa isInvertible()-
355*/-
356QTransform QTransform::inverted(bool *invertible) const-
357{-
358 QTransform invert(true);-
359 bool inv = true;-
360-
361 switch(inline_type()) {-
362 case TxNone:
never executed: case TxNone:
0
363 break;
never executed: break;
0
364 case TxTranslate:
never executed: case TxTranslate:
0
365 invert.affine._dx = -affine._dx;-
366 invert.affine._dy = -affine._dy;-
367 break;
never executed: break;
0
368 case TxScale:
never executed: case TxScale:
0
369 inv = !qFuzzyIsNull(affine._m11);-
370 inv &= !qFuzzyIsNull(affine._m22);-
371 if (inv) {
invDescription
TRUEnever evaluated
FALSEnever evaluated
0
372 invert.affine._m11 = 1. / affine._m11;-
373 invert.affine._m22 = 1. / affine._m22;-
374 invert.affine._dx = -affine._dx * invert.affine._m11;-
375 invert.affine._dy = -affine._dy * invert.affine._m22;-
376 }
never executed: end of block
0
377 break;
never executed: break;
0
378 case TxRotate:
never executed: case TxRotate:
0
379 case TxShear:
never executed: case TxShear:
0
380 invert.affine = affine.inverted(&inv);-
381 break;
never executed: break;
0
382 default:
never executed: default:
0
383 // general case-
384 qreal det = determinant();-
385 inv = !qFuzzyIsNull(det);-
386 if (inv)
invDescription
TRUEnever evaluated
FALSEnever evaluated
0
387 invert = adjoint() / det;
never executed: invert = adjoint() / det;
0
388 break;
never executed: break;
0
389 }-
390-
391 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
392 *invertible = inv;
never executed: *invertible = inv;
0
393-
394 if (inv) {
invDescription
TRUEnever evaluated
FALSEnever evaluated
0
395 // inverting doesn't change the type-
396 invert.m_type = m_type;-
397 invert.m_dirty = m_dirty;-
398 }
never executed: end of block
0
399-
400 return invert;
never executed: return invert;
0
401}-
402-
403/*!-
404 Moves the coordinate system \a dx along the x axis and \a dy along-
405 the y axis, and returns a reference to the matrix.-
406-
407 \sa setMatrix()-
408*/-
409QTransform &QTransform::translate(qreal dx, qreal dy)-
410{-
411 if (dx == 0 && dy == 0)
dx == 0Description
TRUEnever evaluated
FALSEnever evaluated
dy == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
412 return *this;
never executed: return *this;
0
413#ifndef QT_NO_DEBUG-
414 if (qIsNaN(dx) | qIsNaN(dy)) {
qIsNaN(dx) | qIsNaN(dy)Description
TRUEnever evaluated
FALSEnever evaluated
0
415 qWarning() << "QTransform::translate with NaN called";-
416 return *this;
never executed: return *this;
0
417 }-
418#endif-
419-
420 switch(inline_type()) {-
421 case TxNone:
never executed: case TxNone:
0
422 affine._dx = dx;-
423 affine._dy = dy;-
424 break;
never executed: break;
0
425 case TxTranslate:
never executed: case TxTranslate:
0
426 affine._dx += dx;-
427 affine._dy += dy;-
428 break;
never executed: break;
0
429 case TxScale:
never executed: case TxScale:
0
430 affine._dx += dx*affine._m11;-
431 affine._dy += dy*affine._m22;-
432 break;
never executed: break;
0
433 case TxProject:
never executed: case TxProject:
0
434 m_33 += dx*m_13 + dy*m_23;-
435 // Fall through-
436 case TxShear:
code before this statement never executed: case TxShear:
never executed: case TxShear:
0
437 case TxRotate:
never executed: case TxRotate:
0
438 affine._dx += dx*affine._m11 + dy*affine._m21;-
439 affine._dy += dy*affine._m22 + dx*affine._m12;-
440 break;
never executed: break;
0
441 }-
442 if (m_dirty < TxTranslate)
m_dirty < TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
443 m_dirty = TxTranslate;
never executed: m_dirty = TxTranslate;
0
444 return *this;
never executed: return *this;
0
445}-
446-
447/*!-
448 Creates a matrix which corresponds to a translation of \a dx along-
449 the x axis and \a dy along the y axis. This is the same as-
450 QTransform().translate(dx, dy) but slightly faster.-
451-
452 \since 4.5-
453*/-
454QTransform QTransform::fromTranslate(qreal dx, qreal dy)-
455{-
456#ifndef QT_NO_DEBUG-
457 if (qIsNaN(dx) | qIsNaN(dy)) {
qIsNaN(dx) | qIsNaN(dy)Description
TRUEnever evaluated
FALSEnever evaluated
0
458 qWarning() << "QTransform::fromTranslate with NaN called";-
459 return QTransform();
never executed: return QTransform();
0
460}-
461#endif-
462 QTransform transform(1, 0, 0, 0, 1, 0, dx, dy, 1, true);-
463 if (dx == 0 && dy == 0)
dx == 0Description
TRUEnever evaluated
FALSEnever evaluated
dy == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
464 transform.m_type = TxNone;
never executed: transform.m_type = TxNone;
0
465 else-
466 transform.m_type = TxTranslate;
never executed: transform.m_type = TxTranslate;
0
467 transform.m_dirty = TxNone;-
468 return transform;
never executed: return transform;
0
469}-
470-
471/*!-
472 Scales the coordinate system by \a sx horizontally and \a sy-
473 vertically, and returns a reference to the matrix.-
474-
475 \sa setMatrix()-
476*/-
477QTransform & QTransform::scale(qreal sx, qreal sy)-
478{-
479 if (sx == 1 && sy == 1)
sx == 1Description
TRUEnever evaluated
FALSEnever evaluated
sy == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
480 return *this;
never executed: return *this;
0
481#ifndef QT_NO_DEBUG-
482 if (qIsNaN(sx) | qIsNaN(sy)) {
qIsNaN(sx) | qIsNaN(sy)Description
TRUEnever evaluated
FALSEnever evaluated
0
483 qWarning() << "QTransform::scale with NaN called";-
484 return *this;
never executed: return *this;
0
485 }-
486#endif-
487-
488 switch(inline_type()) {-
489 case TxNone:
never executed: case TxNone:
0
490 case TxTranslate:
never executed: case TxTranslate:
0
491 affine._m11 = sx;-
492 affine._m22 = sy;-
493 break;
never executed: break;
0
494 case TxProject:
never executed: case TxProject:
0
495 m_13 *= sx;-
496 m_23 *= sy;-
497 // fall through-
498 case TxRotate:
code before this statement never executed: case TxRotate:
never executed: case TxRotate:
0
499 case TxShear:
never executed: case TxShear:
0
500 affine._m12 *= sx;-
501 affine._m21 *= sy;-
502 // fall through-
503 case TxScale:
code before this statement never executed: case TxScale:
never executed: case TxScale:
0
504 affine._m11 *= sx;-
505 affine._m22 *= sy;-
506 break;
never executed: break;
0
507 }-
508 if (m_dirty < TxScale)
m_dirty < TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
509 m_dirty = TxScale;
never executed: m_dirty = TxScale;
0
510 return *this;
never executed: return *this;
0
511}-
512-
513/*!-
514 Creates a matrix which corresponds to a scaling of-
515 \a sx horizontally and \a sy vertically.-
516 This is the same as QTransform().scale(sx, sy) but slightly faster.-
517-
518 \since 4.5-
519*/-
520QTransform QTransform::fromScale(qreal sx, qreal sy)-
521{-
522#ifndef QT_NO_DEBUG-
523 if (qIsNaN(sx) | qIsNaN(sy)) {
qIsNaN(sx) | qIsNaN(sy)Description
TRUEnever evaluated
FALSEnever evaluated
0
524 qWarning() << "QTransform::fromScale with NaN called";-
525 return QTransform();
never executed: return QTransform();
0
526}-
527#endif-
528 QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1, true);-
529 if (sx == 1. && sy == 1.)
sx == 1.Description
TRUEnever evaluated
FALSEnever evaluated
sy == 1.Description
TRUEnever evaluated
FALSEnever evaluated
0
530 transform.m_type = TxNone;
never executed: transform.m_type = TxNone;
0
531 else-
532 transform.m_type = TxScale;
never executed: transform.m_type = TxScale;
0
533 transform.m_dirty = TxNone;-
534 return transform;
never executed: return transform;
0
535}-
536-
537/*!-
538 Shears the coordinate system by \a sh horizontally and \a sv-
539 vertically, and returns a reference to the matrix.-
540-
541 \sa setMatrix()-
542*/-
543QTransform & QTransform::shear(qreal sh, qreal sv)-
544{-
545 if (sh == 0 && sv == 0)
sh == 0Description
TRUEnever evaluated
FALSEnever evaluated
sv == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
546 return *this;
never executed: return *this;
0
547#ifndef QT_NO_DEBUG-
548 if (qIsNaN(sh) | qIsNaN(sv)) {
qIsNaN(sh) | qIsNaN(sv)Description
TRUEnever evaluated
FALSEnever evaluated
0
549 qWarning() << "QTransform::shear with NaN called";-
550 return *this;
never executed: return *this;
0
551 }-
552#endif-
553-
554 switch(inline_type()) {-
555 case TxNone:
never executed: case TxNone:
0
556 case TxTranslate:
never executed: case TxTranslate:
0
557 affine._m12 = sv;-
558 affine._m21 = sh;-
559 break;
never executed: break;
0
560 case TxScale:
never executed: case TxScale:
0
561 affine._m12 = sv*affine._m22;-
562 affine._m21 = sh*affine._m11;-
563 break;
never executed: break;
0
564 case TxProject: {
never executed: case TxProject:
0
565 qreal tm13 = sv*m_23;-
566 qreal tm23 = sh*m_13;-
567 m_13 += tm13;-
568 m_23 += tm23;-
569 }-
570 // fall through-
571 case TxRotate:
code before this statement never executed: case TxRotate:
never executed: case TxRotate:
0
572 case TxShear: {
never executed: case TxShear:
0
573 qreal tm11 = sv*affine._m21;-
574 qreal tm22 = sh*affine._m12;-
575 qreal tm12 = sv*affine._m22;-
576 qreal tm21 = sh*affine._m11;-
577 affine._m11 += tm11; affine._m12 += tm12;-
578 affine._m21 += tm21; affine._m22 += tm22;-
579 break;
never executed: break;
0
580 }-
581 }-
582 if (m_dirty < TxShear)
m_dirty < TxShearDescription
TRUEnever evaluated
FALSEnever evaluated
0
583 m_dirty = TxShear;
never executed: m_dirty = TxShear;
0
584 return *this;
never executed: return *this;
0
585}-
586-
587const qreal deg2rad = qreal(0.017453292519943295769); // pi/180-
588const qreal inv_dist_to_plane = 1. / 1024.;-
589-
590/*!-
591 \fn QTransform &QTransform::rotate(qreal angle, Qt::Axis axis)-
592-
593 Rotates the coordinate system counterclockwise by the given \a angle-
594 about the specified \a axis and returns a reference to the matrix.-
595-
596 Note that if you apply a QTransform to a point defined in widget-
597 coordinates, the direction of the rotation will be clockwise-
598 because the y-axis points downwards.-
599-
600 The angle is specified in degrees.-
601-
602 \sa setMatrix()-
603*/-
604QTransform & QTransform::rotate(qreal a, Qt::Axis axis)-
605{-
606 if (a == 0)
a == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
607 return *this;
never executed: return *this;
0
608#ifndef QT_NO_DEBUG-
609 if (qIsNaN(a)) {
qIsNaN(a)Description
TRUEnever evaluated
FALSEnever evaluated
0
610 qWarning() << "QTransform::rotate with NaN called";-
611 return *this;
never executed: return *this;
0
612 }-
613#endif-
614-
615 qreal sina = 0;-
616 qreal cosa = 0;-
617 if (a == 90. || a == -270.)
a == 90.Description
TRUEnever evaluated
FALSEnever evaluated
a == -270.Description
TRUEnever evaluated
FALSEnever evaluated
0
618 sina = 1.;
never executed: sina = 1.;
0
619 else if (a == 270. || a == -90.)
a == 270.Description
TRUEnever evaluated
FALSEnever evaluated
a == -90.Description
TRUEnever evaluated
FALSEnever evaluated
0
620 sina = -1.;
never executed: sina = -1.;
0
621 else if (a == 180.)
a == 180.Description
TRUEnever evaluated
FALSEnever evaluated
0
622 cosa = -1.;
never executed: cosa = -1.;
0
623 else{-
624 qreal b = deg2rad*a; // convert to radians-
625 sina = qSin(b); // fast and convenient-
626 cosa = qCos(b);-
627 }
never executed: end of block
0
628-
629 if (axis == Qt::ZAxis) {
axis == Qt::ZAxisDescription
TRUEnever evaluated
FALSEnever evaluated
0
630 switch(inline_type()) {-
631 case TxNone:
never executed: case TxNone:
0
632 case TxTranslate:
never executed: case TxTranslate:
0
633 affine._m11 = cosa;-
634 affine._m12 = sina;-
635 affine._m21 = -sina;-
636 affine._m22 = cosa;-
637 break;
never executed: break;
0
638 case TxScale: {
never executed: case TxScale:
0
639 qreal tm11 = cosa*affine._m11;-
640 qreal tm12 = sina*affine._m22;-
641 qreal tm21 = -sina*affine._m11;-
642 qreal tm22 = cosa*affine._m22;-
643 affine._m11 = tm11; affine._m12 = tm12;-
644 affine._m21 = tm21; affine._m22 = tm22;-
645 break;
never executed: break;
0
646 }-
647 case TxProject: {
never executed: case TxProject:
0
648 qreal tm13 = cosa*m_13 + sina*m_23;-
649 qreal tm23 = -sina*m_13 + cosa*m_23;-
650 m_13 = tm13;-
651 m_23 = tm23;-
652 // fall through-
653 }-
654 case TxRotate:
code before this statement never executed: case TxRotate:
never executed: case TxRotate:
0
655 case TxShear: {
never executed: case TxShear:
0
656 qreal tm11 = cosa*affine._m11 + sina*affine._m21;-
657 qreal tm12 = cosa*affine._m12 + sina*affine._m22;-
658 qreal tm21 = -sina*affine._m11 + cosa*affine._m21;-
659 qreal tm22 = -sina*affine._m12 + cosa*affine._m22;-
660 affine._m11 = tm11; affine._m12 = tm12;-
661 affine._m21 = tm21; affine._m22 = tm22;-
662 break;
never executed: break;
0
663 }-
664 }-
665 if (m_dirty < TxRotate)
m_dirty < TxRotateDescription
TRUEnever evaluated
FALSEnever evaluated
0
666 m_dirty = TxRotate;
never executed: m_dirty = TxRotate;
0
667 } else {
never executed: end of block
0
668 QTransform result;-
669 if (axis == Qt::YAxis) {
axis == Qt::YAxisDescription
TRUEnever evaluated
FALSEnever evaluated
0
670 result.affine._m11 = cosa;-
671 result.m_13 = -sina * inv_dist_to_plane;-
672 } else {
never executed: end of block
0
673 result.affine._m22 = cosa;-
674 result.m_23 = -sina * inv_dist_to_plane;-
675 }
never executed: end of block
0
676 result.m_type = TxProject;-
677 *this = result * *this;-
678 }
never executed: end of block
0
679-
680 return *this;
never executed: return *this;
0
681}-
682-
683/*!-
684 \fn QTransform & QTransform::rotateRadians(qreal angle, Qt::Axis axis)-
685-
686 Rotates the coordinate system counterclockwise by the given \a angle-
687 about the specified \a axis and returns a reference to the matrix.-
688-
689 Note that if you apply a QTransform to a point defined in widget-
690 coordinates, the direction of the rotation will be clockwise-
691 because the y-axis points downwards.-
692-
693 The angle is specified in radians.-
694-
695 \sa setMatrix()-
696*/-
697QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)-
698{-
699#ifndef QT_NO_DEBUG-
700 if (qIsNaN(a)) {
qIsNaN(a)Description
TRUEnever evaluated
FALSEnever evaluated
0
701 qWarning() << "QTransform::rotateRadians with NaN called";-
702 return *this;
never executed: return *this;
0
703 }-
704#endif-
705 qreal sina = qSin(a);-
706 qreal cosa = qCos(a);-
707-
708 if (axis == Qt::ZAxis) {
axis == Qt::ZAxisDescription
TRUEnever evaluated
FALSEnever evaluated
0
709 switch(inline_type()) {-
710 case TxNone:
never executed: case TxNone:
0
711 case TxTranslate:
never executed: case TxTranslate:
0
712 affine._m11 = cosa;-
713 affine._m12 = sina;-
714 affine._m21 = -sina;-
715 affine._m22 = cosa;-
716 break;
never executed: break;
0
717 case TxScale: {
never executed: case TxScale:
0
718 qreal tm11 = cosa*affine._m11;-
719 qreal tm12 = sina*affine._m22;-
720 qreal tm21 = -sina*affine._m11;-
721 qreal tm22 = cosa*affine._m22;-
722 affine._m11 = tm11; affine._m12 = tm12;-
723 affine._m21 = tm21; affine._m22 = tm22;-
724 break;
never executed: break;
0
725 }-
726 case TxProject: {
never executed: case TxProject:
0
727 qreal tm13 = cosa*m_13 + sina*m_23;-
728 qreal tm23 = -sina*m_13 + cosa*m_23;-
729 m_13 = tm13;-
730 m_23 = tm23;-
731 // fall through-
732 }-
733 case TxRotate:
code before this statement never executed: case TxRotate:
never executed: case TxRotate:
0
734 case TxShear: {
never executed: case TxShear:
0
735 qreal tm11 = cosa*affine._m11 + sina*affine._m21;-
736 qreal tm12 = cosa*affine._m12 + sina*affine._m22;-
737 qreal tm21 = -sina*affine._m11 + cosa*affine._m21;-
738 qreal tm22 = -sina*affine._m12 + cosa*affine._m22;-
739 affine._m11 = tm11; affine._m12 = tm12;-
740 affine._m21 = tm21; affine._m22 = tm22;-
741 break;
never executed: break;
0
742 }-
743 }-
744 if (m_dirty < TxRotate)
m_dirty < TxRotateDescription
TRUEnever evaluated
FALSEnever evaluated
0
745 m_dirty = TxRotate;
never executed: m_dirty = TxRotate;
0
746 } else {
never executed: end of block
0
747 QTransform result;-
748 if (axis == Qt::YAxis) {
axis == Qt::YAxisDescription
TRUEnever evaluated
FALSEnever evaluated
0
749 result.affine._m11 = cosa;-
750 result.m_13 = -sina * inv_dist_to_plane;-
751 } else {
never executed: end of block
0
752 result.affine._m22 = cosa;-
753 result.m_23 = -sina * inv_dist_to_plane;-
754 }
never executed: end of block
0
755 result.m_type = TxProject;-
756 *this = result * *this;-
757 }
never executed: end of block
0
758 return *this;
never executed: return *this;
0
759}-
760-
761/*!-
762 \fn bool QTransform::operator==(const QTransform &matrix) const-
763 Returns \c true if this matrix is equal to the given \a matrix,-
764 otherwise returns \c false.-
765*/-
766bool QTransform::operator==(const QTransform &o) const-
767{-
768 return affine._m11 == o.affine._m11 &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
affine._m11 == o.affine._m11Description
TRUEnever evaluated
FALSEnever evaluated
0
769 affine._m12 == o.affine._m12 &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
affine._m12 == o.affine._m12Description
TRUEnever evaluated
FALSEnever evaluated
0
770 affine._m21 == o.affine._m21 &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
affine._m21 == o.affine._m21Description
TRUEnever evaluated
FALSEnever evaluated
0
771 affine._m22 == o.affine._m22 &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
affine._m22 == o.affine._m22Description
TRUEnever evaluated
FALSEnever evaluated
0
772 affine._dx == o.affine._dx &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
affine._dx == o.affine._dxDescription
TRUEnever evaluated
FALSEnever evaluated
0
773 affine._dy == o.affine._dy &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
affine._dy == o.affine._dyDescription
TRUEnever evaluated
FALSEnever evaluated
0
774 m_13 == o.m_13 &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
m_13 == o.m_13Description
TRUEnever evaluated
FALSEnever evaluated
0
775 m_23 == o.m_23 &&
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
m_23 == o.m_23Description
TRUEnever evaluated
FALSEnever evaluated
0
776 m_33 == o.m_33;
never executed: return affine._m11 == o.affine._m11 && affine._m12 == o.affine._m12 && affine._m21 == o.affine._m21 && affine._m22 == o.affine._m22 && affine._dx == o.affine._dx && affine._dy == o.affine._dy && m_13 == o.m_13 && m_23 == o.m_23 && m_33 == o.m_33;
m_33 == o.m_33Description
TRUEnever evaluated
FALSEnever evaluated
0
777}-
778-
779/*!-
780 \since 5.6-
781 \relates QTransform-
782-
783 Returns the hash value for \a key, using-
784 \a seed to seed the calculation.-
785*/-
786uint qHash(const QTransform &key, uint seed) Q_DECL_NOTHROW-
787{-
788 QtPrivate::QHashCombine hash;-
789 seed = hash(key.m11(), seed);-
790 seed = hash(key.m12(), seed);-
791 seed = hash(key.m21(), seed);-
792 seed = hash(key.m22(), seed);-
793 seed = hash(key.dx(), seed);-
794 seed = hash(key.dy(), seed);-
795 seed = hash(key.m13(), seed);-
796 seed = hash(key.m23(), seed);-
797 seed = hash(key.m33(), seed);-
798 return seed;
never executed: return seed;
0
799}-
800-
801-
802/*!-
803 \fn bool QTransform::operator!=(const QTransform &matrix) const-
804 Returns \c true if this matrix is not equal to the given \a matrix,-
805 otherwise returns \c false.-
806*/-
807bool QTransform::operator!=(const QTransform &o) const-
808{-
809 return !operator==(o);
never executed: return !operator==(o);
0
810}-
811-
812/*!-
813 \fn QTransform & QTransform::operator*=(const QTransform &matrix)-
814 \overload-
815-
816 Returns the result of multiplying this matrix by the given \a-
817 matrix.-
818*/-
819QTransform & QTransform::operator*=(const QTransform &o)-
820{-
821 const TransformationType otherType = o.inline_type();-
822 if (otherType == TxNone)
otherType == TxNoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
823 return *this;
never executed: return *this;
0
824-
825 const TransformationType thisType = inline_type();-
826 if (thisType == TxNone)
thisType == TxNoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
827 return operator=(o);
never executed: return operator=(o);
0
828-
829 TransformationType t = qMax(thisType, otherType);-
830 switch(t) {-
831 case TxNone:
never executed: case TxNone:
0
832 break;
never executed: break;
0
833 case TxTranslate:
never executed: case TxTranslate:
0
834 affine._dx += o.affine._dx;-
835 affine._dy += o.affine._dy;-
836 break;
never executed: break;
0
837 case TxScale:
never executed: case TxScale:
0
838 {-
839 qreal m11 = affine._m11*o.affine._m11;-
840 qreal m22 = affine._m22*o.affine._m22;-
841-
842 qreal m31 = affine._dx*o.affine._m11 + o.affine._dx;-
843 qreal m32 = affine._dy*o.affine._m22 + o.affine._dy;-
844-
845 affine._m11 = m11;-
846 affine._m22 = m22;-
847 affine._dx = m31; affine._dy = m32;-
848 break;
never executed: break;
0
849 }-
850 case TxRotate:
never executed: case TxRotate:
0
851 case TxShear:
never executed: case TxShear:
0
852 {-
853 qreal m11 = affine._m11*o.affine._m11 + affine._m12*o.affine._m21;-
854 qreal m12 = affine._m11*o.affine._m12 + affine._m12*o.affine._m22;-
855-
856 qreal m21 = affine._m21*o.affine._m11 + affine._m22*o.affine._m21;-
857 qreal m22 = affine._m21*o.affine._m12 + affine._m22*o.affine._m22;-
858-
859 qreal m31 = affine._dx*o.affine._m11 + affine._dy*o.affine._m21 + o.affine._dx;-
860 qreal m32 = affine._dx*o.affine._m12 + affine._dy*o.affine._m22 + o.affine._dy;-
861-
862 affine._m11 = m11; affine._m12 = m12;-
863 affine._m21 = m21; affine._m22 = m22;-
864 affine._dx = m31; affine._dy = m32;-
865 break;
never executed: break;
0
866 }-
867 case TxProject:
never executed: case TxProject:
0
868 {-
869 qreal m11 = affine._m11*o.affine._m11 + affine._m12*o.affine._m21 + m_13*o.affine._dx;-
870 qreal m12 = affine._m11*o.affine._m12 + affine._m12*o.affine._m22 + m_13*o.affine._dy;-
871 qreal m13 = affine._m11*o.m_13 + affine._m12*o.m_23 + m_13*o.m_33;-
872-
873 qreal m21 = affine._m21*o.affine._m11 + affine._m22*o.affine._m21 + m_23*o.affine._dx;-
874 qreal m22 = affine._m21*o.affine._m12 + affine._m22*o.affine._m22 + m_23*o.affine._dy;-
875 qreal m23 = affine._m21*o.m_13 + affine._m22*o.m_23 + m_23*o.m_33;-
876-
877 qreal m31 = affine._dx*o.affine._m11 + affine._dy*o.affine._m21 + m_33*o.affine._dx;-
878 qreal m32 = affine._dx*o.affine._m12 + affine._dy*o.affine._m22 + m_33*o.affine._dy;-
879 qreal m33 = affine._dx*o.m_13 + affine._dy*o.m_23 + m_33*o.m_33;-
880-
881 affine._m11 = m11; affine._m12 = m12; m_13 = m13;-
882 affine._m21 = m21; affine._m22 = m22; m_23 = m23;-
883 affine._dx = m31; affine._dy = m32; m_33 = m33;-
884 }-
885 }
never executed: end of block
0
886-
887 m_dirty = t;-
888 m_type = t;-
889-
890 return *this;
never executed: return *this;
0
891}-
892-
893/*!-
894 \fn QTransform QTransform::operator*(const QTransform &matrix) const-
895 Returns the result of multiplying this matrix by the given \a-
896 matrix.-
897-
898 Note that matrix multiplication is not commutative, i.e. a*b !=-
899 b*a.-
900*/-
901QTransform QTransform::operator*(const QTransform &m) const-
902{-
903 const TransformationType otherType = m.inline_type();-
904 if (otherType == TxNone)
otherType == TxNoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
905 return *this;
never executed: return *this;
0
906-
907 const TransformationType thisType = inline_type();-
908 if (thisType == TxNone)
thisType == TxNoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
909 return m;
never executed: return m;
0
910-
911 QTransform t(true);-
912 TransformationType type = qMax(thisType, otherType);-
913 switch(type) {-
914 case TxNone:
never executed: case TxNone:
0
915 break;
never executed: break;
0
916 case TxTranslate:
never executed: case TxTranslate:
0
917 t.affine._dx = affine._dx + m.affine._dx;-
918 t.affine._dy += affine._dy + m.affine._dy;-
919 break;
never executed: break;
0
920 case TxScale:
never executed: case TxScale:
0
921 {-
922 qreal m11 = affine._m11*m.affine._m11;-
923 qreal m22 = affine._m22*m.affine._m22;-
924-
925 qreal m31 = affine._dx*m.affine._m11 + m.affine._dx;-
926 qreal m32 = affine._dy*m.affine._m22 + m.affine._dy;-
927-
928 t.affine._m11 = m11;-
929 t.affine._m22 = m22;-
930 t.affine._dx = m31; t.affine._dy = m32;-
931 break;
never executed: break;
0
932 }-
933 case TxRotate:
never executed: case TxRotate:
0
934 case TxShear:
never executed: case TxShear:
0
935 {-
936 qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21;-
937 qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22;-
938-
939 qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21;-
940 qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22;-
941-
942 qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m.affine._dx;-
943 qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m.affine._dy;-
944-
945 t.affine._m11 = m11; t.affine._m12 = m12;-
946 t.affine._m21 = m21; t.affine._m22 = m22;-
947 t.affine._dx = m31; t.affine._dy = m32;-
948 break;
never executed: break;
0
949 }-
950 case TxProject:
never executed: case TxProject:
0
951 {-
952 qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21 + m_13*m.affine._dx;-
953 qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22 + m_13*m.affine._dy;-
954 qreal m13 = affine._m11*m.m_13 + affine._m12*m.m_23 + m_13*m.m_33;-
955-
956 qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21 + m_23*m.affine._dx;-
957 qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22 + m_23*m.affine._dy;-
958 qreal m23 = affine._m21*m.m_13 + affine._m22*m.m_23 + m_23*m.m_33;-
959-
960 qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m_33*m.affine._dx;-
961 qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m_33*m.affine._dy;-
962 qreal m33 = affine._dx*m.m_13 + affine._dy*m.m_23 + m_33*m.m_33;-
963-
964 t.affine._m11 = m11; t.affine._m12 = m12; t.m_13 = m13;-
965 t.affine._m21 = m21; t.affine._m22 = m22; t.m_23 = m23;-
966 t.affine._dx = m31; t.affine._dy = m32; t.m_33 = m33;-
967 }-
968 }
never executed: end of block
0
969-
970 t.m_dirty = type;-
971 t.m_type = type;-
972-
973 return t;
never executed: return t;
0
974}-
975-
976/*!-
977 \fn QTransform & QTransform::operator*=(qreal scalar)-
978 \overload-
979-
980 Returns the result of performing an element-wise multiplication of this-
981 matrix with the given \a scalar.-
982*/-
983-
984/*!-
985 \fn QTransform & QTransform::operator/=(qreal scalar)-
986 \overload-
987-
988 Returns the result of performing an element-wise division of this-
989 matrix by the given \a scalar.-
990*/-
991-
992/*!-
993 \fn QTransform & QTransform::operator+=(qreal scalar)-
994 \overload-
995-
996 Returns the matrix obtained by adding the given \a scalar to each-
997 element of this matrix.-
998*/-
999-
1000/*!-
1001 \fn QTransform & QTransform::operator-=(qreal scalar)-
1002 \overload-
1003-
1004 Returns the matrix obtained by subtracting the given \a scalar from each-
1005 element of this matrix.-
1006*/-
1007-
1008/*!-
1009 Assigns the given \a matrix's values to this matrix.-
1010*/-
1011QTransform & QTransform::operator=(const QTransform &matrix)-
1012{-
1013 affine._m11 = matrix.affine._m11;-
1014 affine._m12 = matrix.affine._m12;-
1015 affine._m21 = matrix.affine._m21;-
1016 affine._m22 = matrix.affine._m22;-
1017 affine._dx = matrix.affine._dx;-
1018 affine._dy = matrix.affine._dy;-
1019 m_13 = matrix.m_13;-
1020 m_23 = matrix.m_23;-
1021 m_33 = matrix.m_33;-
1022 m_type = matrix.m_type;-
1023 m_dirty = matrix.m_dirty;-
1024-
1025 return *this;
never executed: return *this;
0
1026}-
1027-
1028/*!-
1029 Resets the matrix to an identity matrix, i.e. all elements are set-
1030 to zero, except \c m11 and \c m22 (specifying the scale) and \c m33-
1031 which are set to 1.-
1032-
1033 \sa QTransform(), isIdentity(), {QTransform#Basic Matrix-
1034 Operations}{Basic Matrix Operations}-
1035*/-
1036void QTransform::reset()-
1037{-
1038 affine._m11 = affine._m22 = m_33 = 1.0;-
1039 affine._m12 = m_13 = affine._m21 = m_23 = affine._dx = affine._dy = 0;-
1040 m_type = TxNone;-
1041 m_dirty = TxNone;-
1042}
never executed: end of block
0
1043-
1044#ifndef QT_NO_DATASTREAM-
1045/*!-
1046 \fn QDataStream &operator<<(QDataStream &stream, const QTransform &matrix)-
1047 \since 4.3-
1048 \relates QTransform-
1049-
1050 Writes the given \a matrix to the given \a stream and returns a-
1051 reference to the stream.-
1052-
1053 \sa {Serializing Qt Data Types}-
1054*/-
1055QDataStream & operator<<(QDataStream &s, const QTransform &m)-
1056{-
1057 s << double(m.m11())-
1058 << double(m.m12())-
1059 << double(m.m13())-
1060 << double(m.m21())-
1061 << double(m.m22())-
1062 << double(m.m23())-
1063 << double(m.m31())-
1064 << double(m.m32())-
1065 << double(m.m33());-
1066 return s;
never executed: return s;
0
1067}-
1068-
1069/*!-
1070 \fn QDataStream &operator>>(QDataStream &stream, QTransform &matrix)-
1071 \since 4.3-
1072 \relates QTransform-
1073-
1074 Reads the given \a matrix from the given \a stream and returns a-
1075 reference to the stream.-
1076-
1077 \sa {Serializing Qt Data Types}-
1078*/-
1079QDataStream & operator>>(QDataStream &s, QTransform &t)-
1080{-
1081 double m11, m12, m13,-
1082 m21, m22, m23,-
1083 m31, m32, m33;-
1084-
1085 s >> m11;-
1086 s >> m12;-
1087 s >> m13;-
1088 s >> m21;-
1089 s >> m22;-
1090 s >> m23;-
1091 s >> m31;-
1092 s >> m32;-
1093 s >> m33;-
1094 t.setMatrix(m11, m12, m13,-
1095 m21, m22, m23,-
1096 m31, m32, m33);-
1097 return s;
never executed: return s;
0
1098}-
1099-
1100#endif // QT_NO_DATASTREAM-
1101-
1102#ifndef QT_NO_DEBUG_STREAM-
1103QDebug operator<<(QDebug dbg, const QTransform &m)-
1104{-
1105 static const char *const typeStr[] =-
1106 {-
1107 "TxNone",-
1108 "TxTranslate",-
1109 "TxScale",-
1110 0,-
1111 "TxRotate",-
1112 0, 0, 0,-
1113 "TxShear",-
1114 0, 0, 0, 0, 0, 0, 0,-
1115 "TxProject"-
1116 };-
1117-
1118 QDebugStateSaver saver(dbg);-
1119 dbg.nospace() << "QTransform(type=" << typeStr[m.type()] << ','-
1120 << " 11=" << m.m11()-
1121 << " 12=" << m.m12()-
1122 << " 13=" << m.m13()-
1123 << " 21=" << m.m21()-
1124 << " 22=" << m.m22()-
1125 << " 23=" << m.m23()-
1126 << " 31=" << m.m31()-
1127 << " 32=" << m.m32()-
1128 << " 33=" << m.m33()-
1129 << ')';-
1130-
1131 return dbg;
never executed: return dbg;
0
1132}-
1133#endif-
1134-
1135/*!-
1136 \fn QPoint operator*(const QPoint &point, const QTransform &matrix)-
1137 \relates QTransform-
1138-
1139 This is the same as \a{matrix}.map(\a{point}).-
1140-
1141 \sa QTransform::map()-
1142*/-
1143QPoint QTransform::map(const QPoint &p) const-
1144{-
1145 qreal fx = p.x();-
1146 qreal fy = p.y();-
1147-
1148 qreal x = 0, y = 0;-
1149-
1150 TransformationType t = inline_type();-
1151 switch(t) {-
1152 case TxNone:
never executed: case TxNone:
0
1153 x = fx;-
1154 y = fy;-
1155 break;
never executed: break;
0
1156 case TxTranslate:
never executed: case TxTranslate:
0
1157 x = fx + affine._dx;-
1158 y = fy + affine._dy;-
1159 break;
never executed: break;
0
1160 case TxScale:
never executed: case TxScale:
0
1161 x = affine._m11 * fx + affine._dx;-
1162 y = affine._m22 * fy + affine._dy;-
1163 break;
never executed: break;
0
1164 case TxRotate:
never executed: case TxRotate:
0
1165 case TxShear:
never executed: case TxShear:
0
1166 case TxProject:
never executed: case TxProject:
0
1167 x = affine._m11 * fx + affine._m21 * fy + affine._dx;-
1168 y = affine._m12 * fx + affine._m22 * fy + affine._dy;-
1169 if (t == TxProject) {
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1170 qreal w = 1./(m_13 * fx + m_23 * fy + m_33);-
1171 x *= w;-
1172 y *= w;-
1173 }
never executed: end of block
0
1174 }
never executed: end of block
0
1175 return QPoint(qRound(x), qRound(y));
never executed: return QPoint(qRound(x), qRound(y));
0
1176}-
1177-
1178-
1179/*!-
1180 \fn QPointF operator*(const QPointF &point, const QTransform &matrix)-
1181 \relates QTransform-
1182-
1183 Same as \a{matrix}.map(\a{point}).-
1184-
1185 \sa QTransform::map()-
1186*/-
1187-
1188/*!-
1189 \overload-
1190-
1191 Creates and returns a QPointF object that is a copy of the given point,-
1192 \a p, mapped into the coordinate system defined by this matrix.-
1193*/-
1194QPointF QTransform::map(const QPointF &p) const-
1195{-
1196 qreal fx = p.x();-
1197 qreal fy = p.y();-
1198-
1199 qreal x = 0, y = 0;-
1200-
1201 TransformationType t = inline_type();-
1202 switch(t) {-
1203 case TxNone:
never executed: case TxNone:
0
1204 x = fx;-
1205 y = fy;-
1206 break;
never executed: break;
0
1207 case TxTranslate:
never executed: case TxTranslate:
0
1208 x = fx + affine._dx;-
1209 y = fy + affine._dy;-
1210 break;
never executed: break;
0
1211 case TxScale:
never executed: case TxScale:
0
1212 x = affine._m11 * fx + affine._dx;-
1213 y = affine._m22 * fy + affine._dy;-
1214 break;
never executed: break;
0
1215 case TxRotate:
never executed: case TxRotate:
0
1216 case TxShear:
never executed: case TxShear:
0
1217 case TxProject:
never executed: case TxProject:
0
1218 x = affine._m11 * fx + affine._m21 * fy + affine._dx;-
1219 y = affine._m12 * fx + affine._m22 * fy + affine._dy;-
1220 if (t == TxProject) {
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1221 qreal w = 1./(m_13 * fx + m_23 * fy + m_33);-
1222 x *= w;-
1223 y *= w;-
1224 }
never executed: end of block
0
1225 }
never executed: end of block
0
1226 return QPointF(x, y);
never executed: return QPointF(x, y);
0
1227}-
1228-
1229/*!-
1230 \fn QPoint QTransform::map(const QPoint &point) const-
1231 \overload-
1232-
1233 Creates and returns a QPoint object that is a copy of the given \a-
1234 point, mapped into the coordinate system defined by this-
1235 matrix. Note that the transformed coordinates are rounded to the-
1236 nearest integer.-
1237*/-
1238-
1239/*!-
1240 \fn QLineF operator*(const QLineF &line, const QTransform &matrix)-
1241 \relates QTransform-
1242-
1243 This is the same as \a{matrix}.map(\a{line}).-
1244-
1245 \sa QTransform::map()-
1246*/-
1247-
1248/*!-
1249 \fn QLine operator*(const QLine &line, const QTransform &matrix)-
1250 \relates QTransform-
1251-
1252 This is the same as \a{matrix}.map(\a{line}).-
1253-
1254 \sa QTransform::map()-
1255*/-
1256-
1257/*!-
1258 \overload-
1259-
1260 Creates and returns a QLineF object that is a copy of the given line,-
1261 \a l, mapped into the coordinate system defined by this matrix.-
1262*/-
1263QLine QTransform::map(const QLine &l) const-
1264{-
1265 qreal fx1 = l.x1();-
1266 qreal fy1 = l.y1();-
1267 qreal fx2 = l.x2();-
1268 qreal fy2 = l.y2();-
1269-
1270 qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0;-
1271-
1272 TransformationType t = inline_type();-
1273 switch(t) {-
1274 case TxNone:
never executed: case TxNone:
0
1275 x1 = fx1;-
1276 y1 = fy1;-
1277 x2 = fx2;-
1278 y2 = fy2;-
1279 break;
never executed: break;
0
1280 case TxTranslate:
never executed: case TxTranslate:
0
1281 x1 = fx1 + affine._dx;-
1282 y1 = fy1 + affine._dy;-
1283 x2 = fx2 + affine._dx;-
1284 y2 = fy2 + affine._dy;-
1285 break;
never executed: break;
0
1286 case TxScale:
never executed: case TxScale:
0
1287 x1 = affine._m11 * fx1 + affine._dx;-
1288 y1 = affine._m22 * fy1 + affine._dy;-
1289 x2 = affine._m11 * fx2 + affine._dx;-
1290 y2 = affine._m22 * fy2 + affine._dy;-
1291 break;
never executed: break;
0
1292 case TxRotate:
never executed: case TxRotate:
0
1293 case TxShear:
never executed: case TxShear:
0
1294 case TxProject:
never executed: case TxProject:
0
1295 x1 = affine._m11 * fx1 + affine._m21 * fy1 + affine._dx;-
1296 y1 = affine._m12 * fx1 + affine._m22 * fy1 + affine._dy;-
1297 x2 = affine._m11 * fx2 + affine._m21 * fy2 + affine._dx;-
1298 y2 = affine._m12 * fx2 + affine._m22 * fy2 + affine._dy;-
1299 if (t == TxProject) {
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1300 qreal w = 1./(m_13 * fx1 + m_23 * fy1 + m_33);-
1301 x1 *= w;-
1302 y1 *= w;-
1303 w = 1./(m_13 * fx2 + m_23 * fy2 + m_33);-
1304 x2 *= w;-
1305 y2 *= w;-
1306 }
never executed: end of block
0
1307 }
never executed: end of block
0
1308 return QLine(qRound(x1), qRound(y1), qRound(x2), qRound(y2));
never executed: return QLine(qRound(x1), qRound(y1), qRound(x2), qRound(y2));
0
1309}-
1310-
1311/*!-
1312 \overload-
1313-
1314 \fn QLineF QTransform::map(const QLineF &line) const-
1315-
1316 Creates and returns a QLine object that is a copy of the given \a-
1317 line, mapped into the coordinate system defined by this matrix.-
1318 Note that the transformed coordinates are rounded to the nearest-
1319 integer.-
1320*/-
1321-
1322QLineF QTransform::map(const QLineF &l) const-
1323{-
1324 qreal fx1 = l.x1();-
1325 qreal fy1 = l.y1();-
1326 qreal fx2 = l.x2();-
1327 qreal fy2 = l.y2();-
1328-
1329 qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0;-
1330-
1331 TransformationType t = inline_type();-
1332 switch(t) {-
1333 case TxNone:
never executed: case TxNone:
0
1334 x1 = fx1;-
1335 y1 = fy1;-
1336 x2 = fx2;-
1337 y2 = fy2;-
1338 break;
never executed: break;
0
1339 case TxTranslate:
never executed: case TxTranslate:
0
1340 x1 = fx1 + affine._dx;-
1341 y1 = fy1 + affine._dy;-
1342 x2 = fx2 + affine._dx;-
1343 y2 = fy2 + affine._dy;-
1344 break;
never executed: break;
0
1345 case TxScale:
never executed: case TxScale:
0
1346 x1 = affine._m11 * fx1 + affine._dx;-
1347 y1 = affine._m22 * fy1 + affine._dy;-
1348 x2 = affine._m11 * fx2 + affine._dx;-
1349 y2 = affine._m22 * fy2 + affine._dy;-
1350 break;
never executed: break;
0
1351 case TxRotate:
never executed: case TxRotate:
0
1352 case TxShear:
never executed: case TxShear:
0
1353 case TxProject:
never executed: case TxProject:
0
1354 x1 = affine._m11 * fx1 + affine._m21 * fy1 + affine._dx;-
1355 y1 = affine._m12 * fx1 + affine._m22 * fy1 + affine._dy;-
1356 x2 = affine._m11 * fx2 + affine._m21 * fy2 + affine._dx;-
1357 y2 = affine._m12 * fx2 + affine._m22 * fy2 + affine._dy;-
1358 if (t == TxProject) {
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1359 qreal w = 1./(m_13 * fx1 + m_23 * fy1 + m_33);-
1360 x1 *= w;-
1361 y1 *= w;-
1362 w = 1./(m_13 * fx2 + m_23 * fy2 + m_33);-
1363 x2 *= w;-
1364 y2 *= w;-
1365 }
never executed: end of block
0
1366 }
never executed: end of block
0
1367 return QLineF(x1, y1, x2, y2);
never executed: return QLineF(x1, y1, x2, y2);
0
1368}-
1369-
1370static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &poly)-
1371{-
1372 if (poly.size() == 0)
poly.size() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1373 return poly;
never executed: return poly;
0
1374-
1375 if (poly.size() == 1)
poly.size() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1376 return QPolygonF() << transform.map(poly.at(0));
never executed: return QPolygonF() << transform.map(poly.at(0));
0
1377-
1378 QPainterPath path;-
1379 path.addPolygon(poly);-
1380-
1381 path = transform.map(path);-
1382-
1383 QPolygonF result;-
1384 const int elementCount = path.elementCount();-
1385 result.reserve(elementCount);-
1386 for (int i = 0; i < elementCount; ++i)
i < elementCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
1387 result << path.elementAt(i);
never executed: result << path.elementAt(i);
0
1388 return result;
never executed: return result;
0
1389}-
1390-
1391-
1392/*!-
1393 \fn QPolygonF operator *(const QPolygonF &polygon, const QTransform &matrix)-
1394 \since 4.3-
1395 \relates QTransform-
1396-
1397 This is the same as \a{matrix}.map(\a{polygon}).-
1398-
1399 \sa QTransform::map()-
1400*/-
1401-
1402/*!-
1403 \fn QPolygon operator*(const QPolygon &polygon, const QTransform &matrix)-
1404 \relates QTransform-
1405-
1406 This is the same as \a{matrix}.map(\a{polygon}).-
1407-
1408 \sa QTransform::map()-
1409*/-
1410-
1411/*!-
1412 \fn QPolygonF QTransform::map(const QPolygonF &polygon) const-
1413 \overload-
1414-
1415 Creates and returns a QPolygonF object that is a copy of the given-
1416 \a polygon, mapped into the coordinate system defined by this-
1417 matrix.-
1418*/-
1419QPolygonF QTransform::map(const QPolygonF &a) const-
1420{-
1421 TransformationType t = inline_type();-
1422 if (t <= TxTranslate)
t <= TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1423 return a.translated(affine._dx, affine._dy);
never executed: return a.translated(affine._dx, affine._dy);
0
1424-
1425 if (t >= QTransform::TxProject)
t >= QTransform::TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1426 return mapProjective(*this, a);
never executed: return mapProjective(*this, a);
0
1427-
1428 int size = a.size();-
1429 int i;-
1430 QPolygonF p(size);-
1431 const QPointF *da = a.constData();-
1432 QPointF *dp = p.data();-
1433-
1434 for(i = 0; i < size; ++i) {
i < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1435 MAP(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1436 }
never executed: end of block
0
1437 return p;
never executed: return p;
0
1438}-
1439-
1440/*!-
1441 \fn QPolygon QTransform::map(const QPolygon &polygon) const-
1442 \overload-
1443-
1444 Creates and returns a QPolygon object that is a copy of the given-
1445 \a polygon, mapped into the coordinate system defined by this-
1446 matrix. Note that the transformed coordinates are rounded to the-
1447 nearest integer.-
1448*/-
1449QPolygon QTransform::map(const QPolygon &a) const-
1450{-
1451 TransformationType t = inline_type();-
1452 if (t <= TxTranslate)
t <= TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1453 return a.translated(qRound(affine._dx), qRound(affine._dy));
never executed: return a.translated(qRound(affine._dx), qRound(affine._dy));
0
1454-
1455 if (t >= QTransform::TxProject)
t >= QTransform::TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1456 return mapProjective(*this, QPolygonF(a)).toPolygon();
never executed: return mapProjective(*this, QPolygonF(a)).toPolygon();
0
1457-
1458 int size = a.size();-
1459 int i;-
1460 QPolygon p(size);-
1461 const QPoint *da = a.constData();-
1462 QPoint *dp = p.data();-
1463-
1464 for(i = 0; i < size; ++i) {
i < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1465 qreal nx = 0, ny = 0;-
1466 MAP(da[i].xp, da[i].yp, nx, ny);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1467 dp[i].xp = qRound(nx);-
1468 dp[i].yp = qRound(ny);-
1469 }
never executed: end of block
0
1470 return p;
never executed: return p;
0
1471}-
1472-
1473/*!-
1474 \fn QRegion operator*(const QRegion &region, const QTransform &matrix)-
1475 \relates QTransform-
1476-
1477 This is the same as \a{matrix}.map(\a{region}).-
1478-
1479 \sa QTransform::map()-
1480*/-
1481-
1482extern QPainterPath qt_regionToPath(const QRegion &region);-
1483-
1484/*!-
1485 \fn QRegion QTransform::map(const QRegion &region) const-
1486 \overload-
1487-
1488 Creates and returns a QRegion object that is a copy of the given-
1489 \a region, mapped into the coordinate system defined by this matrix.-
1490-
1491 Calling this method can be rather expensive if rotations or-
1492 shearing are used.-
1493*/-
1494QRegion QTransform::map(const QRegion &r) const-
1495{-
1496 TransformationType t = inline_type();-
1497 if (t == TxNone)
t == TxNoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
1498 return r;
never executed: return r;
0
1499-
1500 if (t == TxTranslate) {
t == TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1501 QRegion copy(r);-
1502 copy.translate(qRound(affine._dx), qRound(affine._dy));-
1503 return copy;
never executed: return copy;
0
1504 }-
1505-
1506 if (t == TxScale && r.rectCount() == 1)
t == TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
r.rectCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1507 return QRegion(mapRect(r.boundingRect()));
never executed: return QRegion(mapRect(r.boundingRect()));
0
1508-
1509 QPainterPath p = map(qt_regionToPath(r));-
1510 return p.toFillPolygon(QTransform()).toPolygon();
never executed: return p.toFillPolygon(QTransform()).toPolygon();
0
1511}-
1512-
1513struct QHomogeneousCoordinate-
1514{-
1515 qreal x;-
1516 qreal y;-
1517 qreal w;-
1518-
1519 QHomogeneousCoordinate() {}-
1520 QHomogeneousCoordinate(qreal x_, qreal y_, qreal w_) : x(x_), y(y_), w(w_) {}
never executed: end of block
0
1521-
1522 const QPointF toPoint() const {-
1523 qreal iw = 1. / w;-
1524 return QPointF(x * iw, y * iw);
never executed: return QPointF(x * iw, y * iw);
0
1525 }-
1526};-
1527-
1528static inline QHomogeneousCoordinate mapHomogeneous(const QTransform &transform, const QPointF &p)-
1529{-
1530 QHomogeneousCoordinate c;-
1531 c.x = transform.m11() * p.x() + transform.m21() * p.y() + transform.m31();-
1532 c.y = transform.m12() * p.x() + transform.m22() * p.y() + transform.m32();-
1533 c.w = transform.m13() * p.x() + transform.m23() * p.y() + transform.m33();-
1534 return c;
never executed: return c;
0
1535}-
1536-
1537static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b,-
1538 bool needsMoveTo, bool needsLineTo = true)-
1539{-
1540 QHomogeneousCoordinate ha = mapHomogeneous(transform, a);-
1541 QHomogeneousCoordinate hb = mapHomogeneous(transform, b);-
1542-
1543 if (ha.w < Q_NEAR_CLIP && hb.w < Q_NEAR_CLIP)
ha.w < (sizeof...0001 : 0.0001)Description
TRUEnever evaluated
FALSEnever evaluated
hb.w < (sizeof...0001 : 0.0001)Description
TRUEnever evaluated
FALSEnever evaluated
0
1544 return false;
never executed: return false;
0
1545-
1546 if (hb.w < Q_NEAR_CLIP) {
hb.w < (sizeof...0001 : 0.0001)Description
TRUEnever evaluated
FALSEnever evaluated
0
1547 const qreal t = (Q_NEAR_CLIP - hb.w) / (ha.w - hb.w);
sizeof(qreal) ...sizeof(double)Description
TRUEnever evaluated
FALSEnever evaluated
0
1548-
1549 hb.x += (ha.x - hb.x) * t;-
1550 hb.y += (ha.y - hb.y) * t;-
1551 hb.w = qreal(Q_NEAR_CLIP);-
1552 } else if (ha.w < Q_NEAR_CLIP) {
never executed: end of block
ha.w < (sizeof...0001 : 0.0001)Description
TRUEnever evaluated
FALSEnever evaluated
0
1553 const qreal t = (Q_NEAR_CLIP - ha.w) / (hb.w - ha.w);
sizeof(qreal) ...sizeof(double)Description
TRUEnever evaluated
FALSEnever evaluated
0
1554-
1555 ha.x += (hb.x - ha.x) * t;-
1556 ha.y += (hb.y - ha.y) * t;-
1557 ha.w = qreal(Q_NEAR_CLIP);-
1558-
1559 const QPointF p = ha.toPoint();-
1560 if (needsMoveTo) {
needsMoveToDescription
TRUEnever evaluated
FALSEnever evaluated
0
1561 path.moveTo(p);-
1562 needsMoveTo = false;-
1563 } else {
never executed: end of block
0
1564 path.lineTo(p);-
1565 }
never executed: end of block
0
1566 }-
1567-
1568 if (needsMoveTo)
needsMoveToDescription
TRUEnever evaluated
FALSEnever evaluated
0
1569 path.moveTo(ha.toPoint());
never executed: path.moveTo(ha.toPoint());
0
1570-
1571 if (needsLineTo)
needsLineToDescription
TRUEnever evaluated
FALSEnever evaluated
0
1572 path.lineTo(hb.toPoint());
never executed: path.lineTo(hb.toPoint());
0
1573-
1574 return true;
never executed: return true;
0
1575}-
1576Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);-
1577-
1578static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo)-
1579{-
1580 // Convert projective xformed curves to line-
1581 // segments so they can be transformed more accurately-
1582-
1583 qreal scale;-
1584 qt_scaleForTransform(transform, &scale);-
1585-
1586 qreal curveThreshold = scale == 0 ? qreal(0.25) : (qreal(0.25) / scale);
scale == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1587-
1588 QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon(curveThreshold);-
1589-
1590 for (int i = 0; i < segment.size() - 1; ++i)
i < segment.size() - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1591 if (lineTo_clipped(path, transform, segment.at(i), segment.at(i+1), needsMoveTo))
lineTo_clipped..., needsMoveTo)Description
TRUEnever evaluated
FALSEnever evaluated
0
1592 needsMoveTo = false;
never executed: needsMoveTo = false;
0
1593-
1594 return !needsMoveTo;
never executed: return !needsMoveTo;
0
1595}-
1596-
1597static QPainterPath mapProjective(const QTransform &transform, const QPainterPath &path)-
1598{-
1599 QPainterPath result;-
1600-
1601 QPointF last;-
1602 QPointF lastMoveTo;-
1603 bool needsMoveTo = true;-
1604 for (int i = 0; i < path.elementCount(); ++i) {
i < path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
1605 switch (path.elementAt(i).type) {-
1606 case QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
1607 if (i > 0 && lastMoveTo != last)
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
lastMoveTo != lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
1608 lineTo_clipped(result, transform, last, lastMoveTo, needsMoveTo);
never executed: lineTo_clipped(result, transform, last, lastMoveTo, needsMoveTo);
0
1609-
1610 lastMoveTo = path.elementAt(i);-
1611 last = path.elementAt(i);-
1612 needsMoveTo = true;-
1613 break;
never executed: break;
0
1614 case QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
1615 if (lineTo_clipped(result, transform, last, path.elementAt(i), needsMoveTo))
lineTo_clipped..., needsMoveTo)Description
TRUEnever evaluated
FALSEnever evaluated
0
1616 needsMoveTo = false;
never executed: needsMoveTo = false;
0
1617 last = path.elementAt(i);-
1618 break;
never executed: break;
0
1619 case QPainterPath::CurveToElement:
never executed: case QPainterPath::CurveToElement:
0
1620 if (cubicTo_clipped(result, transform, last, path.elementAt(i), path.elementAt(i+1), path.elementAt(i+2), needsMoveTo))
cubicTo_clippe..., needsMoveTo)Description
TRUEnever evaluated
FALSEnever evaluated
0
1621 needsMoveTo = false;
never executed: needsMoveTo = false;
0
1622 i += 2;-
1623 last = path.elementAt(i);-
1624 break;
never executed: break;
0
1625 default:
never executed: default:
0
1626 Q_ASSERT(false);-
1627 }
never executed: end of block
0
1628 }-
1629-
1630 if (path.elementCount() > 0 && lastMoveTo != last)
path.elementCount() > 0Description
TRUEnever evaluated
FALSEnever evaluated
lastMoveTo != lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
1631 lineTo_clipped(result, transform, last, lastMoveTo, needsMoveTo, false);
never executed: lineTo_clipped(result, transform, last, lastMoveTo, needsMoveTo, false);
0
1632-
1633 result.setFillRule(path.fillRule());-
1634 return result;
never executed: return result;
0
1635}-
1636-
1637/*!-
1638 \fn QPainterPath operator *(const QPainterPath &path, const QTransform &matrix)-
1639 \since 4.3-
1640 \relates QTransform-
1641-
1642 This is the same as \a{matrix}.map(\a{path}).-
1643-
1644 \sa QTransform::map()-
1645*/-
1646-
1647/*!-
1648 \overload-
1649-
1650 Creates and returns a QPainterPath object that is a copy of the-
1651 given \a path, mapped into the coordinate system defined by this-
1652 matrix.-
1653*/-
1654QPainterPath QTransform::map(const QPainterPath &path) const-
1655{-
1656 TransformationType t = inline_type();-
1657 if (t == TxNone || path.elementCount() == 0)
t == TxNoneDescription
TRUEnever evaluated
FALSEnever evaluated
path.elementCount() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1658 return path;
never executed: return path;
0
1659-
1660 if (t >= TxProject)
t >= TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1661 return mapProjective(*this, path);
never executed: return mapProjective(*this, path);
0
1662-
1663 QPainterPath copy = path;-
1664-
1665 if (t == TxTranslate) {
t == TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1666 copy.translate(affine._dx, affine._dy);-
1667 } else {
never executed: end of block
0
1668 copy.detach();-
1669 // Full xform-
1670 for (int i=0; i<path.elementCount(); ++i) {
i<path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
1671 QPainterPath::Element &e = copy.d_ptr->elements[i];-
1672 MAP(e.x, e.y, e.x, e.y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1673 }
never executed: end of block
0
1674 }
never executed: end of block
0
1675-
1676 return copy;
never executed: return copy;
0
1677}-
1678-
1679/*!-
1680 \fn QPolygon QTransform::mapToPolygon(const QRect &rectangle) const-
1681-
1682 Creates and returns a QPolygon representation of the given \a-
1683 rectangle, mapped into the coordinate system defined by this-
1684 matrix.-
1685-
1686 The rectangle's coordinates are transformed using the following-
1687 formulas:-
1688-
1689 \snippet code/src_gui_painting_qtransform.cpp 1-
1690-
1691 Polygons and rectangles behave slightly differently when-
1692 transformed (due to integer rounding), so-
1693 \c{matrix.map(QPolygon(rectangle))} is not always the same as-
1694 \c{matrix.mapToPolygon(rectangle)}.-
1695-
1696 \sa mapRect(), {QTransform#Basic Matrix Operations}{Basic Matrix-
1697 Operations}-
1698*/-
1699QPolygon QTransform::mapToPolygon(const QRect &rect) const-
1700{-
1701 TransformationType t = inline_type();-
1702-
1703 QPolygon a(4);-
1704 qreal x[4] = { 0, 0, 0, 0 }, y[4] = { 0, 0, 0, 0 };-
1705 if (t <= TxScale) {
t <= TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1706 x[0] = affine._m11*rect.x() + affine._dx;-
1707 y[0] = affine._m22*rect.y() + affine._dy;-
1708 qreal w = affine._m11*rect.width();-
1709 qreal h = affine._m22*rect.height();-
1710 if (w < 0) {
w < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1711 w = -w;-
1712 x[0] -= w;-
1713 }
never executed: end of block
0
1714 if (h < 0) {
h < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1715 h = -h;-
1716 y[0] -= h;-
1717 }
never executed: end of block
0
1718 x[1] = x[0]+w;-
1719 x[2] = x[1];-
1720 x[3] = x[0];-
1721 y[1] = y[0];-
1722 y[2] = y[0]+h;-
1723 y[3] = y[2];-
1724 } else {
never executed: end of block
0
1725 qreal right = rect.x() + rect.width();-
1726 qreal bottom = rect.y() + rect.height();-
1727 MAP(rect.x(), rect.y(), x[0], y[0]);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1728 MAP(right, rect.y(), x[1], y[1]);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1729 MAP(right, bottom, x[2], y[2]);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1730 MAP(rect.x(), bottom, x[3], y[3]);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1731 }
never executed: end of block
0
1732-
1733 // all coordinates are correctly, tranform to a pointarray-
1734 // (rounding to the next integer)-
1735 a.setPoints(4, qRound(x[0]), qRound(y[0]),-
1736 qRound(x[1]), qRound(y[1]),-
1737 qRound(x[2]), qRound(y[2]),-
1738 qRound(x[3]), qRound(y[3]));-
1739 return a;
never executed: return a;
0
1740}-
1741-
1742/*!-
1743 Creates a transformation matrix, \a trans, that maps a unit square-
1744 to a four-sided polygon, \a quad. Returns \c true if the transformation-
1745 is constructed or false if such a transformation does not exist.-
1746-
1747 \sa quadToSquare(), quadToQuad()-
1748*/-
1749bool QTransform::squareToQuad(const QPolygonF &quad, QTransform &trans)-
1750{-
1751 if (quad.count() != 4)
quad.count() != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1752 return false;
never executed: return false;
0
1753-
1754 qreal dx0 = quad[0].x();-
1755 qreal dx1 = quad[1].x();-
1756 qreal dx2 = quad[2].x();-
1757 qreal dx3 = quad[3].x();-
1758-
1759 qreal dy0 = quad[0].y();-
1760 qreal dy1 = quad[1].y();-
1761 qreal dy2 = quad[2].y();-
1762 qreal dy3 = quad[3].y();-
1763-
1764 double ax = dx0 - dx1 + dx2 - dx3;-
1765 double ay = dy0 - dy1 + dy2 - dy3;-
1766-
1767 if (!ax && !ay) { //afine transform
!axDescription
TRUEnever evaluated
FALSEnever evaluated
!ayDescription
TRUEnever evaluated
FALSEnever evaluated
0
1768 trans.setMatrix(dx1 - dx0, dy1 - dy0, 0,-
1769 dx2 - dx1, dy2 - dy1, 0,-
1770 dx0, dy0, 1);-
1771 } else {
never executed: end of block
0
1772 double ax1 = dx1 - dx2;-
1773 double ax2 = dx3 - dx2;-
1774 double ay1 = dy1 - dy2;-
1775 double ay2 = dy3 - dy2;-
1776-
1777 /*determinants */-
1778 double gtop = ax * ay2 - ax2 * ay;-
1779 double htop = ax1 * ay - ax * ay1;-
1780 double bottom = ax1 * ay2 - ax2 * ay1;-
1781-
1782 double a, b, c, d, e, f, g, h; /*i is always 1*/-
1783-
1784 if (!bottom)
!bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1785 return false;
never executed: return false;
0
1786-
1787 g = gtop/bottom;-
1788 h = htop/bottom;-
1789-
1790 a = dx1 - dx0 + g * dx1;-
1791 b = dx3 - dx0 + h * dx3;-
1792 c = dx0;-
1793 d = dy1 - dy0 + g * dy1;-
1794 e = dy3 - dy0 + h * dy3;-
1795 f = dy0;-
1796-
1797 trans.setMatrix(a, d, g,-
1798 b, e, h,-
1799 c, f, 1.0);-
1800 }
never executed: end of block
0
1801-
1802 return true;
never executed: return true;
0
1803}-
1804-
1805/*!-
1806 \fn bool QTransform::quadToSquare(const QPolygonF &quad, QTransform &trans)-
1807-
1808 Creates a transformation matrix, \a trans, that maps a four-sided polygon,-
1809 \a quad, to a unit square. Returns \c true if the transformation is constructed-
1810 or false if such a transformation does not exist.-
1811-
1812 \sa squareToQuad(), quadToQuad()-
1813*/-
1814bool QTransform::quadToSquare(const QPolygonF &quad, QTransform &trans)-
1815{-
1816 if (!squareToQuad(quad, trans))
!squareToQuad(quad, trans)Description
TRUEnever evaluated
FALSEnever evaluated
0
1817 return false;
never executed: return false;
0
1818-
1819 bool invertible = false;-
1820 trans = trans.inverted(&invertible);-
1821-
1822 return invertible;
never executed: return invertible;
0
1823}-
1824-
1825/*!-
1826 Creates a transformation matrix, \a trans, that maps a four-sided-
1827 polygon, \a one, to another four-sided polygon, \a two.-
1828 Returns \c true if the transformation is possible; otherwise returns-
1829 false.-
1830-
1831 This is a convenience method combining quadToSquare() and-
1832 squareToQuad() methods. It allows the input quad to be-
1833 transformed into any other quad.-
1834-
1835 \sa squareToQuad(), quadToSquare()-
1836*/-
1837bool QTransform::quadToQuad(const QPolygonF &one,-
1838 const QPolygonF &two,-
1839 QTransform &trans)-
1840{-
1841 QTransform stq;-
1842 if (!quadToSquare(one, trans))
!quadToSquare(one, trans)Description
TRUEnever evaluated
FALSEnever evaluated
0
1843 return false;
never executed: return false;
0
1844 if (!squareToQuad(two, stq))
!squareToQuad(two, stq)Description
TRUEnever evaluated
FALSEnever evaluated
0
1845 return false;
never executed: return false;
0
1846 trans *= stq;-
1847 //qDebug()<<"Final = "<<trans;-
1848 return true;
never executed: return true;
0
1849}-
1850-
1851/*!-
1852 Sets the matrix elements to the specified values, \a m11,-
1853 \a m12, \a m13 \a m21, \a m22, \a m23 \a m31, \a m32 and-
1854 \a m33. Note that this function replaces the previous values.-
1855 QTransform provides the translate(), rotate(), scale() and shear()-
1856 convenience functions to manipulate the various matrix elements-
1857 based on the currently defined coordinate system.-
1858-
1859 \sa QTransform()-
1860*/-
1861-
1862void QTransform::setMatrix(qreal m11, qreal m12, qreal m13,-
1863 qreal m21, qreal m22, qreal m23,-
1864 qreal m31, qreal m32, qreal m33)-
1865{-
1866 affine._m11 = m11; affine._m12 = m12; m_13 = m13;-
1867 affine._m21 = m21; affine._m22 = m22; m_23 = m23;-
1868 affine._dx = m31; affine._dy = m32; m_33 = m33;-
1869 m_type = TxNone;-
1870 m_dirty = TxProject;-
1871}
never executed: end of block
0
1872-
1873static inline bool needsPerspectiveClipping(const QRectF &rect, const QTransform &transform)-
1874{-
1875 const qreal wx = qMin(transform.m13() * rect.left(), transform.m13() * rect.right());-
1876 const qreal wy = qMin(transform.m23() * rect.top(), transform.m23() * rect.bottom());-
1877-
1878 return wx + wy + transform.m33() < Q_NEAR_CLIP;
never executed: return wx + wy + transform.m33() < (sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001);
0
1879}-
1880-
1881QRect QTransform::mapRect(const QRect &rect) const-
1882{-
1883 TransformationType t = inline_type();-
1884 if (t <= TxTranslate)
t <= TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1885 return rect.translated(qRound(affine._dx), qRound(affine._dy));
never executed: return rect.translated(qRound(affine._dx), qRound(affine._dy));
0
1886-
1887 if (t <= TxScale) {
t <= TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1888 int x = qRound(affine._m11*rect.x() + affine._dx);-
1889 int y = qRound(affine._m22*rect.y() + affine._dy);-
1890 int w = qRound(affine._m11*rect.width());-
1891 int h = qRound(affine._m22*rect.height());-
1892 if (w < 0) {
w < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1893 w = -w;-
1894 x -= w;-
1895 }
never executed: end of block
0
1896 if (h < 0) {
h < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1897 h = -h;-
1898 y -= h;-
1899 }
never executed: end of block
0
1900 return QRect(x, y, w, h);
never executed: return QRect(x, y, w, h);
0
1901 } else if (t < TxProject || !needsPerspectiveClipping(rect, *this)) {
t < TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
!needsPerspect...g(rect, *this)Description
TRUEnever evaluated
FALSEnever evaluated
0
1902 // see mapToPolygon for explanations of the algorithm.-
1903 qreal x = 0, y = 0;-
1904 MAP(rect.left(), rect.top(), x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1905 qreal xmin = x;-
1906 qreal ymin = y;-
1907 qreal xmax = x;-
1908 qreal ymax = y;-
1909 MAP(rect.right() + 1, rect.top(), x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1910 xmin = qMin(xmin, x);-
1911 ymin = qMin(ymin, y);-
1912 xmax = qMax(xmax, x);-
1913 ymax = qMax(ymax, y);-
1914 MAP(rect.right() + 1, rect.bottom() + 1, x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1915 xmin = qMin(xmin, x);-
1916 ymin = qMin(ymin, y);-
1917 xmax = qMax(xmax, x);-
1918 ymax = qMax(ymax, y);-
1919 MAP(rect.left(), rect.bottom() + 1, x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1920 xmin = qMin(xmin, x);-
1921 ymin = qMin(ymin, y);-
1922 xmax = qMax(xmax, x);-
1923 ymax = qMax(ymax, y);-
1924 return QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin));
never executed: return QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin));
0
1925 } else {-
1926 QPainterPath path;-
1927 path.addRect(rect);-
1928 return map(path).boundingRect().toRect();
never executed: return map(path).boundingRect().toRect();
0
1929 }-
1930}-
1931-
1932/*!-
1933 \fn QRectF QTransform::mapRect(const QRectF &rectangle) const-
1934-
1935 Creates and returns a QRectF object that is a copy of the given \a-
1936 rectangle, mapped into the coordinate system defined by this-
1937 matrix.-
1938-
1939 The rectangle's coordinates are transformed using the following-
1940 formulas:-
1941-
1942 \snippet code/src_gui_painting_qtransform.cpp 2-
1943-
1944 If rotation or shearing has been specified, this function returns-
1945 the \e bounding rectangle. To retrieve the exact region the given-
1946 \a rectangle maps to, use the mapToPolygon() function instead.-
1947-
1948 \sa mapToPolygon(), {QTransform#Basic Matrix Operations}{Basic Matrix-
1949 Operations}-
1950*/-
1951QRectF QTransform::mapRect(const QRectF &rect) const-
1952{-
1953 TransformationType t = inline_type();-
1954 if (t <= TxTranslate)
t <= TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1955 return rect.translated(affine._dx, affine._dy);
never executed: return rect.translated(affine._dx, affine._dy);
0
1956-
1957 if (t <= TxScale) {
t <= TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1958 qreal x = affine._m11*rect.x() + affine._dx;-
1959 qreal y = affine._m22*rect.y() + affine._dy;-
1960 qreal w = affine._m11*rect.width();-
1961 qreal h = affine._m22*rect.height();-
1962 if (w < 0) {
w < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1963 w = -w;-
1964 x -= w;-
1965 }
never executed: end of block
0
1966 if (h < 0) {
h < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1967 h = -h;-
1968 y -= h;-
1969 }
never executed: end of block
0
1970 return QRectF(x, y, w, h);
never executed: return QRectF(x, y, w, h);
0
1971 } else if (t < TxProject || !needsPerspectiveClipping(rect, *this)) {
t < TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
!needsPerspect...g(rect, *this)Description
TRUEnever evaluated
FALSEnever evaluated
0
1972 qreal x = 0, y = 0;-
1973 MAP(rect.x(), rect.y(), x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1974 qreal xmin = x;-
1975 qreal ymin = y;-
1976 qreal xmax = x;-
1977 qreal ymax = y;-
1978 MAP(rect.x() + rect.width(), rect.y(), x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1979 xmin = qMin(xmin, x);-
1980 ymin = qMin(ymin, y);-
1981 xmax = qMax(xmax, x);-
1982 ymax = qMax(ymax, y);-
1983 MAP(rect.x() + rect.width(), rect.y() + rect.height(), x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1984 xmin = qMin(xmin, x);-
1985 ymin = qMin(ymin, y);-
1986 xmax = qMax(xmax, x);-
1987 ymax = qMax(ymax, y);-
1988 MAP(rect.x(), rect.y() + rect.height(), x, y);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
1989 xmin = qMin(xmin, x);-
1990 ymin = qMin(ymin, y);-
1991 xmax = qMax(xmax, x);-
1992 ymax = qMax(ymax, y);-
1993 return QRectF(xmin, ymin, xmax-xmin, ymax - ymin);
never executed: return QRectF(xmin, ymin, xmax-xmin, ymax - ymin);
0
1994 } else {-
1995 QPainterPath path;-
1996 path.addRect(rect);-
1997 return map(path).boundingRect();
never executed: return map(path).boundingRect();
0
1998 }-
1999}-
2000-
2001/*!-
2002 \fn QRect QTransform::mapRect(const QRect &rectangle) const-
2003 \overload-
2004-
2005 Creates and returns a QRect object that is a copy of the given \a-
2006 rectangle, mapped into the coordinate system defined by this-
2007 matrix. Note that the transformed coordinates are rounded to the-
2008 nearest integer.-
2009*/-
2010-
2011/*!-
2012 Maps the given coordinates \a x and \a y into the coordinate-
2013 system defined by this matrix. The resulting values are put in *\a-
2014 tx and *\a ty, respectively.-
2015-
2016 The coordinates are transformed using the following formulas:-
2017-
2018 \snippet code/src_gui_painting_qtransform.cpp 3-
2019-
2020 The point (x, y) is the original point, and (x', y') is the-
2021 transformed point.-
2022-
2023 \sa {QTransform#Basic Matrix Operations}{Basic Matrix Operations}-
2024*/-
2025void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const-
2026{-
2027 TransformationType t = inline_type();-
2028 MAP(x, y, *tx, *ty);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
2029}
never executed: end of block
0
2030-
2031/*!-
2032 \overload-
2033-
2034 Maps the given coordinates \a x and \a y into the coordinate-
2035 system defined by this matrix. The resulting values are put in *\a-
2036 tx and *\a ty, respectively. Note that the transformed coordinates-
2037 are rounded to the nearest integer.-
2038*/-
2039void QTransform::map(int x, int y, int *tx, int *ty) const-
2040{-
2041 TransformationType t = inline_type();-
2042 qreal fx = 0, fy = 0;-
2043 MAP(x, y, fx, fy);
never executed: break;
never executed: break;
never executed: break;
never executed: w = qreal((sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001));
never executed: end of block
never executed: end of block
t == TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
w < qreal((siz...001 : 0.0001))Description
TRUEnever evaluated
FALSEnever evaluated
never executed: case TxNone:
never executed: case TxTranslate:
never executed: case TxScale:
never executed: case TxRotate:
never executed: case TxShear:
never executed: case TxProject:
0
2044 *tx = qRound(fx);-
2045 *ty = qRound(fy);-
2046}
never executed: end of block
0
2047-
2048/*!-
2049 Returns the QTransform as an affine matrix.-
2050-
2051 \warning If a perspective transformation has been specified,-
2052 then the conversion will cause loss of data.-
2053*/-
2054const QMatrix &QTransform::toAffine() const-
2055{-
2056 return affine;
never executed: return affine;
0
2057}-
2058-
2059/*!-
2060 Returns the transformation type of this matrix.-
2061-
2062 The transformation type is the highest enumeration value-
2063 capturing all of the matrix's transformations. For example,-
2064 if the matrix both scales and shears, the type would be \c TxShear,-
2065 because \c TxShear has a higher enumeration value than \c TxScale.-
2066-
2067 Knowing the transformation type of a matrix is useful for optimization:-
2068 you can often handle specific types more optimally than handling-
2069 the generic case.-
2070 */-
2071QTransform::TransformationType QTransform::type() const-
2072{-
2073 if(m_dirty == TxNone || m_dirty < m_type)
m_dirty == TxNoneDescription
TRUEnever evaluated
FALSEnever evaluated
m_dirty < m_typeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2074 return static_cast<TransformationType>(m_type);
never executed: return static_cast<TransformationType>(m_type);
0
2075-
2076 switch (static_cast<TransformationType>(m_dirty)) {-
2077 case TxProject:
never executed: case TxProject:
0
2078 if (!qFuzzyIsNull(m_13) || !qFuzzyIsNull(m_23) || !qFuzzyIsNull(m_33 - 1)) {
!qFuzzyIsNull(m_13)Description
TRUEnever evaluated
FALSEnever evaluated
!qFuzzyIsNull(m_23)Description
TRUEnever evaluated
FALSEnever evaluated
!qFuzzyIsNull(m_33 - 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2079 m_type = TxProject;-
2080 break;
never executed: break;
0
2081 }-
2082 case TxShear:
code before this statement never executed: case TxShear:
never executed: case TxShear:
0
2083 case TxRotate:
never executed: case TxRotate:
0
2084 if (!qFuzzyIsNull(affine._m12) || !qFuzzyIsNull(affine._m21)) {
!qFuzzyIsNull(affine._m12)Description
TRUEnever evaluated
FALSEnever evaluated
!qFuzzyIsNull(affine._m21)Description
TRUEnever evaluated
FALSEnever evaluated
0
2085 const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22;-
2086 if (qFuzzyIsNull(dot))
qFuzzyIsNull(dot)Description
TRUEnever evaluated
FALSEnever evaluated
0
2087 m_type = TxRotate;
never executed: m_type = TxRotate;
0
2088 else-
2089 m_type = TxShear;
never executed: m_type = TxShear;
0
2090 break;
never executed: break;
0
2091 }-
2092 case TxScale:
code before this statement never executed: case TxScale:
never executed: case TxScale:
0
2093 if (!qFuzzyIsNull(affine._m11 - 1) || !qFuzzyIsNull(affine._m22 - 1)) {
!qFuzzyIsNull(affine._m11 - 1)Description
TRUEnever evaluated
FALSEnever evaluated
!qFuzzyIsNull(affine._m22 - 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2094 m_type = TxScale;-
2095 break;
never executed: break;
0
2096 }-
2097 case TxTranslate:
code before this statement never executed: case TxTranslate:
never executed: case TxTranslate:
0
2098 if (!qFuzzyIsNull(affine._dx) || !qFuzzyIsNull(affine._dy)) {
!qFuzzyIsNull(affine._dx)Description
TRUEnever evaluated
FALSEnever evaluated
!qFuzzyIsNull(affine._dy)Description
TRUEnever evaluated
FALSEnever evaluated
0
2099 m_type = TxTranslate;-
2100 break;
never executed: break;
0
2101 }-
2102 case TxNone:
code before this statement never executed: case TxNone:
never executed: case TxNone:
0
2103 m_type = TxNone;-
2104 break;
never executed: break;
0
2105 }-
2106-
2107 m_dirty = TxNone;-
2108 return static_cast<TransformationType>(m_type);
never executed: return static_cast<TransformationType>(m_type);
0
2109}-
2110-
2111/*!-
2112-
2113 Returns the transform as a QVariant.-
2114*/-
2115QTransform::operator QVariant() const-
2116{-
2117 return QVariant(QVariant::Transform, this);
never executed: return QVariant(QVariant::Transform, this);
0
2118}-
2119-
2120-
2121/*!-
2122 \fn bool QTransform::isInvertible() const-
2123-
2124 Returns \c true if the matrix is invertible, otherwise returns \c false.-
2125-
2126 \sa inverted()-
2127*/-
2128-
2129/*!-
2130 \fn qreal QTransform::det() const-
2131 \obsolete-
2132-
2133 Returns the matrix's determinant. Use determinant() instead.-
2134*/-
2135-
2136-
2137/*!-
2138 \fn qreal QTransform::m11() const-
2139-
2140 Returns the horizontal scaling factor.-
2141-
2142 \sa scale(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2143 Operations}-
2144*/-
2145-
2146/*!-
2147 \fn qreal QTransform::m12() const-
2148-
2149 Returns the vertical shearing factor.-
2150-
2151 \sa shear(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2152 Operations}-
2153*/-
2154-
2155/*!-
2156 \fn qreal QTransform::m21() const-
2157-
2158 Returns the horizontal shearing factor.-
2159-
2160 \sa shear(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2161 Operations}-
2162*/-
2163-
2164/*!-
2165 \fn qreal QTransform::m22() const-
2166-
2167 Returns the vertical scaling factor.-
2168-
2169 \sa scale(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2170 Operations}-
2171*/-
2172-
2173/*!-
2174 \fn qreal QTransform::dx() const-
2175-
2176 Returns the horizontal translation factor.-
2177-
2178 \sa m31(), translate(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2179 Operations}-
2180*/-
2181-
2182/*!-
2183 \fn qreal QTransform::dy() const-
2184-
2185 Returns the vertical translation factor.-
2186-
2187 \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2188 Operations}-
2189*/-
2190-
2191-
2192/*!-
2193 \fn qreal QTransform::m13() const-
2194-
2195 Returns the horizontal projection factor.-
2196-
2197 \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2198 Operations}-
2199*/-
2200-
2201-
2202/*!-
2203 \fn qreal QTransform::m23() const-
2204-
2205 Returns the vertical projection factor.-
2206-
2207 \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2208 Operations}-
2209*/-
2210-
2211/*!-
2212 \fn qreal QTransform::m31() const-
2213-
2214 Returns the horizontal translation factor.-
2215-
2216 \sa dx(), translate(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2217 Operations}-
2218*/-
2219-
2220/*!-
2221 \fn qreal QTransform::m32() const-
2222-
2223 Returns the vertical translation factor.-
2224-
2225 \sa dy(), translate(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2226 Operations}-
2227*/-
2228-
2229/*!-
2230 \fn qreal QTransform::m33() const-
2231-
2232 Returns the division factor.-
2233-
2234 \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix-
2235 Operations}-
2236*/-
2237-
2238/*!-
2239 \fn qreal QTransform::determinant() const-
2240-
2241 Returns the matrix's determinant.-
2242*/-
2243-
2244/*!-
2245 \fn bool QTransform::isIdentity() const-
2246-
2247 Returns \c true if the matrix is the identity matrix, otherwise-
2248 returns \c false.-
2249-
2250 \sa reset()-
2251*/-
2252-
2253/*!-
2254 \fn bool QTransform::isAffine() const-
2255-
2256 Returns \c true if the matrix represent an affine transformation,-
2257 otherwise returns \c false.-
2258*/-
2259-
2260/*!-
2261 \fn bool QTransform::isScaling() const-
2262-
2263 Returns \c true if the matrix represents a scaling-
2264 transformation, otherwise returns \c false.-
2265-
2266 \sa reset()-
2267*/-
2268-
2269/*!-
2270 \fn bool QTransform::isRotating() const-
2271-
2272 Returns \c true if the matrix represents some kind of a-
2273 rotating transformation, otherwise returns \c false.-
2274-
2275 \note A rotation transformation of 180 degrees and/or 360 degrees is treated as a scaling transformation.-
2276-
2277 \sa reset()-
2278*/-
2279-
2280/*!-
2281 \fn bool QTransform::isTranslating() const-
2282-
2283 Returns \c true if the matrix represents a translating-
2284 transformation, otherwise returns \c false.-
2285-
2286 \sa reset()-
2287*/-
2288-
2289/*!-
2290 \fn bool qFuzzyCompare(const QTransform& t1, const QTransform& t2)-
2291-
2292 \relates QTransform-
2293 \since 4.6-
2294-
2295 Returns \c true if \a t1 and \a t2 are equal, allowing for a small-
2296 fuzziness factor for floating-point comparisons; false otherwise.-
2297*/-
2298-
2299-
2300// returns true if the transform is uniformly scaling-
2301// (same scale in x and y direction)-
2302// scale is set to the max of x and y scaling factors-
2303Q_GUI_EXPORT-
2304bool qt_scaleForTransform(const QTransform &transform, qreal *scale)-
2305{-
2306 const QTransform::TransformationType type = transform.type();-
2307 if (type <= QTransform::TxTranslate) {
type <= QTrans...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
2308 if (scale)
scaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2309 *scale = 1;
never executed: *scale = 1;
0
2310 return true;
never executed: return true;
0
2311 } else if (type == QTransform::TxScale) {
type == QTransform::TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2312 const qreal xScale = qAbs(transform.m11());-
2313 const qreal yScale = qAbs(transform.m22());-
2314 if (scale)
scaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2315 *scale = qMax(xScale, yScale);
never executed: *scale = qMax(xScale, yScale);
0
2316 return qFuzzyCompare(xScale, yScale);
never executed: return qFuzzyCompare(xScale, yScale);
0
2317 }-
2318-
2319 // rotate then scale: compare columns-
2320 const qreal xScale1 = transform.m11() * transform.m11()-
2321 + transform.m21() * transform.m21();-
2322 const qreal yScale1 = transform.m12() * transform.m12()-
2323 + transform.m22() * transform.m22();-
2324-
2325 // scale then rotate: compare rows-
2326 const qreal xScale2 = transform.m11() * transform.m11()-
2327 + transform.m12() * transform.m12();-
2328 const qreal yScale2 = transform.m21() * transform.m21()-
2329 + transform.m22() * transform.m22();-
2330-
2331 // decide the order of rotate and scale operations-
2332 if (qAbs(xScale1 - yScale1) > qAbs(xScale2 - yScale2)) {
qAbs(xScale1 -...le2 - yScale2)Description
TRUEnever evaluated
FALSEnever evaluated
0
2333 if (scale)
scaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2334 *scale = qSqrt(qMax(xScale1, yScale1));
never executed: *scale = qSqrt(qMax(xScale1, yScale1));
0
2335-
2336 return type == QTransform::TxRotate && qFuzzyCompare(xScale1, yScale1);
never executed: return type == QTransform::TxRotate && qFuzzyCompare(xScale1, yScale1);
type == QTransform::TxRotateDescription
TRUEnever evaluated
FALSEnever evaluated
qFuzzyCompare(...ale1, yScale1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2337 } else {-
2338 if (scale)
scaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2339 *scale = qSqrt(qMax(xScale2, yScale2));
never executed: *scale = qSqrt(qMax(xScale2, yScale2));
0
2340-
2341 return type == QTransform::TxRotate && qFuzzyCompare(xScale2, yScale2);
never executed: return type == QTransform::TxRotate && qFuzzyCompare(xScale2, yScale2);
type == QTransform::TxRotateDescription
TRUEnever evaluated
FALSEnever evaluated
qFuzzyCompare(...ale2, yScale2)Description
TRUEnever evaluated
FALSEnever evaluated
0
2342 }-
2343}-
2344-
2345QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9