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