1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE: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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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
57 QT_BEGIN_HEADER
58
59 QT_BEGIN_NAMESPACE
60
QT_MODULE(Gui)61 QT_MODULE(Gui)
62
63 class QVariant;
64
65 class Q_GUI_EXPORT QTransform
66 {
67 public:
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
165 private:
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 };
190 Q_DECLARE_TYPEINFO(QTransform, Q_MOVABLE_TYPE);
191
192 /******* inlines *****/
inline_type()193 inline QTransform::TransformationType QTransform::inline_type() const
194 {
195 if (m_dirty == TxNone)
196 return static_cast<TransformationType>(m_type);
197 return type();
198 }
199
isAffine()200 inline bool QTransform::isAffine() const
201 {
202 return inline_type() < TxProject;
203 }
isIdentity()204 inline bool QTransform::isIdentity() const
205 {
206 return inline_type() == TxNone;
207 }
208
isInvertible()209 inline bool QTransform::isInvertible() const
210 {
211 return !qFuzzyIsNull(determinant());
212 }
213
isScaling()214 inline bool QTransform::isScaling() const
215 {
216 return type() >= TxScale;
217 }
isRotating()218 inline bool QTransform::isRotating() const
219 {
220 return inline_type() >= TxRotate;
221 }
222
isTranslating()223 inline bool QTransform::isTranslating() const
224 {
225 return inline_type() >= TxTranslate;
226 }
227
determinant()228 inline 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 }
det()233 inline qreal QTransform::det() const
234 {
235 return determinant();
236 }
m11()237 inline qreal QTransform::m11() const
238 {
239 return affine._m11;
240 }
m12()241 inline qreal QTransform::m12() const
242 {
243 return affine._m12;
244 }
m13()245 inline qreal QTransform::m13() const
246 {
247 return m_13;
248 }
m21()249 inline qreal QTransform::m21() const
250 {
251 return affine._m21;
252 }
m22()253 inline qreal QTransform::m22() const
254 {
255 return affine._m22;
256 }
m23()257 inline qreal QTransform::m23() const
258 {
259 return m_23;
260 }
m31()261 inline qreal QTransform::m31() const
262 {
263 return affine._dx;
264 }
m32()265 inline qreal QTransform::m32() const
266 {
267 return affine._dy;
268 }
m33()269 inline qreal QTransform::m33() const
270 {
271 return m_33;
272 }
dx()273 inline qreal QTransform::dx() const
274 {
275 return affine._dx;
276 }
dy()277 inline qreal QTransform::dy() const
278 {
279 return affine._dy;
280 }
281
282 inline 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 }
299 inline QTransform &QTransform::operator/=(qreal div)
300 {
301 if (div == 0)
302 return *this;
303 div = 1/div;
304 return operator*=(div);
305 }
306 inline 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 }
322 inline 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
qFuzzyCompare(const QTransform & t1,const QTransform & t2)339 inline 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
355 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &);
356 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &);
357 #endif
358
359 #ifndef QT_NO_DEBUG_STREAM
360 Q_GUI_EXPORT QDebug operator<<(QDebug, const QTransform &);
361 #endif
362 /****** end stream functions *******************/
363
364 // mathematical semantics
365 Q_GUI_EXPORT_INLINE QPoint operator*(const QPoint &p, const QTransform &m)
366 { return m.map(p); }
367 Q_GUI_EXPORT_INLINE QPointF operator*(const QPointF &p, const QTransform &m)
368 { return m.map(p); }
369 Q_GUI_EXPORT_INLINE QLineF operator*(const QLineF &l, const QTransform &m)
370 { return m.map(l); }
371 Q_GUI_EXPORT_INLINE QLine operator*(const QLine &l, const QTransform &m)
372 { return m.map(l); }
373 Q_GUI_EXPORT_INLINE QPolygon operator *(const QPolygon &a, const QTransform &m)
374 { return m.map(a); }
375 Q_GUI_EXPORT_INLINE QPolygonF operator *(const QPolygonF &a, const QTransform &m)
376 { return m.map(a); }
377 Q_GUI_EXPORT_INLINE QRegion operator *(const QRegion &r, const QTransform &m)
378 { return m.map(r); }
379 Q_GUI_EXPORT_INLINE QPainterPath operator *(const QPainterPath &p, const QTransform &m)
380 { return m.map(p); }
381
382 Q_GUI_EXPORT_INLINE QTransform operator *(const QTransform &a, qreal n)
383 { QTransform t(a); t *= n; return t; }
384 Q_GUI_EXPORT_INLINE QTransform operator /(const QTransform &a, qreal n)
385 { QTransform t(a); t /= n; return t; }
386 Q_GUI_EXPORT_INLINE QTransform operator +(const QTransform &a, qreal n)
387 { QTransform t(a); t += n; return t; }
388 Q_GUI_EXPORT_INLINE QTransform operator -(const QTransform &a, qreal n)
389 { QTransform t(a); t -= n; return t; }
390
391 QT_END_NAMESPACE
392
393 QT_END_HEADER
394
395 #endif
396