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

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