1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41#ifndef QTRANSFORM_H
42#define QTRANSFORM_H
43
44#include <QtGui/qmatrix.h>
45#include <QtGui/qpainterpath.h>
46#include <QtGui/qpolygon.h>
47#include <QtGui/qregion.h>
48#include <QtGui/qwindowdefs.h>
49#include <QtCore/qline.h>
50#include <QtCore/qpoint.h>
51#include <QtCore/qrect.h>
52
53#if defined(Q_OS_VXWORKS) && defined(m_type)
54# undef m_type
55#endif
56
57QT_BEGIN_HEADER
58
59QT_BEGIN_NAMESPACE
60
61QT_MODULE(Gui)
62
63class QVariant;
64
65class Q_GUI_EXPORT QTransform
66{
67public:
68 enum TransformationType {
69 TxNone = 0x00,
70 TxTranslate = 0x01,
71 TxScale = 0x02,
72 TxRotate = 0x04,
73 TxShear = 0x08,
74 TxProject = 0x10
75 };
76
77 inline explicit QTransform(Qt::Initialization) : affine(Qt::Uninitialized) {}
78 QTransform();
79 QTransform(qreal h11, qreal h12, qreal h13,
80 qreal h21, qreal h22, qreal h23,
81 qreal h31, qreal h32, qreal h33 = 1.0);
82 QTransform(qreal h11, qreal h12, qreal h21,
83 qreal h22, qreal dx, qreal dy);
84 explicit QTransform(const QMatrix &mtx);
85
86 bool isAffine() const;
87 bool isIdentity() const;
88 bool isInvertible() const;
89 bool isScaling() const;
90 bool isRotating() const;
91 bool isTranslating() const;
92
93 TransformationType type() const;
94
95 inline qreal determinant() const;
96 qreal det() const;
97
98 qreal m11() const;
99 qreal m12() const;
100 qreal m13() const;
101 qreal m21() const;
102 qreal m22() const;
103 qreal m23() const;
104 qreal m31() const;
105 qreal m32() const;
106 qreal m33() const;
107 qreal dx() const;
108 qreal dy() const;
109
110 void setMatrix(qreal m11, qreal m12, qreal m13,
111 qreal m21, qreal m22, qreal m23,
112 qreal m31, qreal m32, qreal m33);
113
114 QTransform inverted(bool *invertible = 0) const;
115 QTransform adjoint() const;
116 QTransform transposed() const;
117
118 QTransform &translate(qreal dx, qreal dy);
119 QTransform &scale(qreal sx, qreal sy);
120 QTransform &shear(qreal sh, qreal sv);
121 QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis);
122 QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis);
123
124 static bool squareToQuad(const QPolygonF &square, QTransform &result);
125 static bool quadToSquare(const QPolygonF &quad, QTransform &result);
126 static bool quadToQuad(const QPolygonF &one,
127 const QPolygonF &two,
128 QTransform &result);
129
130 bool operator==(const QTransform &) const;
131 bool operator!=(const QTransform &) const;
132
133 QTransform &operator*=(const QTransform &);
134 QTransform operator*(const QTransform &o) const;
135
136 QTransform &operator=(const QTransform &);
137
138 operator QVariant() const;
139
140 void reset();
141 QPoint map(const QPoint &p) const;
142 QPointF map(const QPointF &p) const;
143 QLine map(const QLine &l) const;
144 QLineF map(const QLineF &l) const;
145 QPolygonF map(const QPolygonF &a) const;
146 QPolygon map(const QPolygon &a) const;
147 QRegion map(const QRegion &r) const;
148 QPainterPath map(const QPainterPath &p) const;
149 QPolygon mapToPolygon(const QRect &r) const;
150 QRect mapRect(const QRect &) const;
151 QRectF mapRect(const QRectF &) const;
152 void map(int x, int y, int *tx, int *ty) const;
153 void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
154
155 const QMatrix &toAffine() const;
156
157 QTransform &operator*=(qreal div);
158 QTransform &operator/=(qreal div);
159 QTransform &operator+=(qreal div);
160 QTransform &operator-=(qreal div);
161
162 static QTransform fromTranslate(qreal dx, qreal dy);
163 static QTransform fromScale(qreal dx, qreal dy);
164
165private:
166 inline QTransform(qreal h11, qreal h12, qreal h13,
167 qreal h21, qreal h22, qreal h23,
168 qreal h31, qreal h32, qreal h33, bool)
169 : affine(h11, h12, h21, h22, h31, h32, true)
170 , m_13(h13), m_23(h23), m_33(h33)
171 , m_type(TxNone)
172 , m_dirty(TxProject) {}
173 inline QTransform(bool)
174 : affine(true)
175 , m_13(0), m_23(0), m_33(1)
176 , m_type(TxNone)
177 , m_dirty(TxNone) {}
178 inline TransformationType inline_type() const;
179 QMatrix affine;
180 qreal m_13;
181 qreal m_23;
182 qreal m_33;
183
184 mutable uint m_type : 5;
185 mutable uint m_dirty : 5;
186
187 class Private;
188 Private *d;
189};
190Q_DECLARE_TYPEINFO(QTransform, Q_MOVABLE_TYPE);
191
192/******* inlines *****/
193inline QTransform::TransformationType QTransform::inline_type() const
194{
195 if (m_dirty == TxNone)
196 return static_cast<TransformationType>(m_type);
197 return type();
198}
199
200inline bool QTransform::isAffine() const
201{
202 return inline_type() < TxProject;
203}
204inline bool QTransform::isIdentity() const
205{
206 return inline_type() == TxNone;
207}
208
209inline bool QTransform::isInvertible() const
210{
211 return !qFuzzyIsNull(determinant());
212}
213
214inline bool QTransform::isScaling() const
215{
216 return type() >= TxScale;
217}
218inline bool QTransform::isRotating() const
219{
220 return inline_type() >= TxRotate;
221}
222
223inline bool QTransform::isTranslating() const
224{
225 return inline_type() >= TxTranslate;
226}
227
228inline qreal QTransform::determinant() const
229{
230 return affine._m11*(m_33*affine._m22-affine._dy*m_23) -
231 affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13);
232}
233inline qreal QTransform::det() const
234{
235 return determinant();
236}
237inline qreal QTransform::m11() const
238{
239 return affine._m11;
240}
241inline qreal QTransform::m12() const
242{
243 return affine._m12;
244}
245inline qreal QTransform::m13() const
246{
247 return m_13;
248}
249inline qreal QTransform::m21() const
250{
251 return affine._m21;
252}
253inline qreal QTransform::m22() const
254{
255 return affine._m22;
256}
257inline qreal QTransform::m23() const
258{
259 return m_23;
260}
261inline qreal QTransform::m31() const
262{
263 return affine._dx;
264}
265inline qreal QTransform::m32() const
266{
267 return affine._dy;
268}
269inline qreal QTransform::m33() const
270{
271 return m_33;
272}
273inline qreal QTransform::dx() const
274{
275 return affine._dx;
276}
277inline qreal QTransform::dy() const
278{
279 return affine._dy;
280}
281
282inline QTransform &QTransform::operator*=(qreal num)
283{
284 if (num == 1.)
285 return *this;
286 affine._m11 *= num;
287 affine._m12 *= num;
288 m_13 *= num;
289 affine._m21 *= num;
290 affine._m22 *= num;
291 m_23 *= num;
292 affine._dx *= num;
293 affine._dy *= num;
294 m_33 *= num;
295 if (m_dirty < TxScale)
296 m_dirty = TxScale;
297 return *this;
298}
299inline QTransform &QTransform::operator/=(qreal div)
300{
301 if (div == 0)
302 return *this;
303 div = 1/div;
304 return operator*=(div);
305}
306inline QTransform &QTransform::operator+=(qreal num)
307{
308 if (num == 0)
309 return *this;
310 affine._m11 += num;
311 affine._m12 += num;
312 m_13 += num;
313 affine._m21 += num;
314 affine._m22 += num;
315 m_23 += num;
316 affine._dx += num;
317 affine._dy += num;
318 m_33 += num;
319 m_dirty = TxProject;
320 return *this;
321}
322inline QTransform &QTransform::operator-=(qreal num)
323{
324 if (num == 0)
325 return *this;
326 affine._m11 -= num;
327 affine._m12 -= num;
328 m_13 -= num;
329 affine._m21 -= num;
330 affine._m22 -= num;
331 m_23 -= num;
332 affine._dx -= num;
333 affine._dy -= num;
334 m_33 -= num;
335 m_dirty = TxProject;
336 return *this;
337}
338
339inline bool qFuzzyCompare(const QTransform& t1, const QTransform& t2)
340{
341 return qFuzzyCompare(t1.m11(), t2.m11())
342 && qFuzzyCompare(t1.m12(), t2.m12())
343 && qFuzzyCompare(t1.m13(), t2.m13())
344 && qFuzzyCompare(t1.m21(), t2.m21())
345 && qFuzzyCompare(t1.m22(), t2.m22())
346 && qFuzzyCompare(t1.m23(), t2.m23())
347 && qFuzzyCompare(t1.m31(), t2.m31())
348 && qFuzzyCompare(t1.m32(), t2.m32())
349 && qFuzzyCompare(t1.m33(), t2.m33());
350}
351
352
353/****** stream functions *******************/
354#ifndef QT_NO_DATASTREAM
355Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &);
356Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &);
357#endif
358
359#ifndef QT_NO_DEBUG_STREAM
360Q_GUI_EXPORT QDebug operator<<(QDebug, const QTransform &);
361#endif
362/****** end stream functions *******************/
363
364// mathematical semantics
365Q_GUI_EXPORT_INLINE QPoint operator*(const QPoint &p, const QTransform &m)
366{ return m.map(p); }
367Q_GUI_EXPORT_INLINE QPointF operator*(const QPointF &p, const QTransform &m)
368{ return m.map(p); }
369Q_GUI_EXPORT_INLINE QLineF operator*(const QLineF &l, const QTransform &m)
370{ return m.map(l); }
371Q_GUI_EXPORT_INLINE QLine operator*(const QLine &l, const QTransform &m)
372{ return m.map(l); }
373Q_GUI_EXPORT_INLINE QPolygon operator *(const QPolygon &a, const QTransform &m)
374{ return m.map(a); }
375Q_GUI_EXPORT_INLINE QPolygonF operator *(const QPolygonF &a, const QTransform &m)
376{ return m.map(a); }
377Q_GUI_EXPORT_INLINE QRegion operator *(const QRegion &r, const QTransform &m)
378{ return m.map(r); }
379Q_GUI_EXPORT_INLINE QPainterPath operator *(const QPainterPath &p, const QTransform &m)
380{ return m.map(p); }
381
382Q_GUI_EXPORT_INLINE QTransform operator *(const QTransform &a, qreal n)
383{ QTransform t(a); t *= n; return t; }
384Q_GUI_EXPORT_INLINE QTransform operator /(const QTransform &a, qreal n)
385{ QTransform t(a); t /= n; return t; }
386Q_GUI_EXPORT_INLINE QTransform operator +(const QTransform &a, qreal n)
387{ QTransform t(a); t += n; return t; }
388Q_GUI_EXPORT_INLINE QTransform operator -(const QTransform &a, qreal n)
389{ QTransform t(a); t -= n; return t; }
390
391QT_END_NAMESPACE
392
393QT_END_HEADER
394
395#endif
396