qtransform.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  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. #ifndef QTRANSFORM_H
  40. #define QTRANSFORM_H
  41. #include <QtGui/qmatrix.h>
  42. #include <QtGui/qpainterpath.h>
  43. #include <QtGui/qpolygon.h>
  44. #include <QtGui/qregion.h>
  45. #include <QtGui/qwindowdefs.h>
  46. #include <QtCore/qline.h>
  47. #include <QtCore/qpoint.h>
  48. #include <QtCore/qrect.h>
  49. QT_BEGIN_NAMESPACE
  50. class QVariant;
  51. class Q_GUI_EXPORT QTransform
  52. {
  53. public:
  54. enum TransformationType {
  55. TxNone = 0x00,
  56. TxTranslate = 0x01,
  57. TxScale = 0x02,
  58. TxRotate = 0x04,
  59. TxShear = 0x08,
  60. TxProject = 0x10
  61. };
  62. inline explicit QTransform(Qt::Initialization) : affine(Qt::Uninitialized) {}
  63. QTransform();
  64. QTransform(qreal h11, qreal h12, qreal h13,
  65. qreal h21, qreal h22, qreal h23,
  66. qreal h31, qreal h32, qreal h33 = 1.0);
  67. QTransform(qreal h11, qreal h12, qreal h21,
  68. qreal h22, qreal dx, qreal dy);
  69. explicit QTransform(const QMatrix &mtx);
  70. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  71. // ### Qt 6: remove; the compiler-generated ones are fine!
  72. QTransform &operator=(QTransform &&other) Q_DECL_NOTHROW // = default
  73. { memcpy(this, &other, sizeof(QTransform)); return *this; }
  74. QTransform &operator=(const QTransform &) Q_DECL_NOTHROW; // = default
  75. QTransform(QTransform &&other) Q_DECL_NOTHROW // = default
  76. : affine(Qt::Uninitialized)
  77. { memcpy(this, &other, sizeof(QTransform)); }
  78. QTransform(const QTransform &other) Q_DECL_NOTHROW // = default
  79. : affine(Qt::Uninitialized)
  80. { memcpy(this, &other, sizeof(QTransform)); }
  81. #endif
  82. bool isAffine() const;
  83. bool isIdentity() const;
  84. bool isInvertible() const;
  85. bool isScaling() const;
  86. bool isRotating() const;
  87. bool isTranslating() const;
  88. TransformationType type() const;
  89. inline qreal determinant() const;
  90. qreal det() const;
  91. qreal m11() const;
  92. qreal m12() const;
  93. qreal m13() const;
  94. qreal m21() const;
  95. qreal m22() const;
  96. qreal m23() const;
  97. qreal m31() const;
  98. qreal m32() const;
  99. qreal m33() const;
  100. qreal dx() const;
  101. qreal dy() const;
  102. void setMatrix(qreal m11, qreal m12, qreal m13,
  103. qreal m21, qreal m22, qreal m23,
  104. qreal m31, qreal m32, qreal m33);
  105. QTransform inverted(bool *invertible = Q_NULLPTR) const Q_REQUIRED_RESULT;
  106. QTransform adjoint() const Q_REQUIRED_RESULT;
  107. QTransform transposed() const Q_REQUIRED_RESULT;
  108. QTransform &translate(qreal dx, qreal dy);
  109. QTransform &scale(qreal sx, qreal sy);
  110. QTransform &shear(qreal sh, qreal sv);
  111. QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis);
  112. QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis);
  113. static bool squareToQuad(const QPolygonF &square, QTransform &result);
  114. static bool quadToSquare(const QPolygonF &quad, QTransform &result);
  115. static bool quadToQuad(const QPolygonF &one,
  116. const QPolygonF &two,
  117. QTransform &result);
  118. bool operator==(const QTransform &) const;
  119. bool operator!=(const QTransform &) const;
  120. QTransform &operator*=(const QTransform &);
  121. QTransform operator*(const QTransform &o) const;
  122. operator QVariant() const;
  123. void reset();
  124. QPoint map(const QPoint &p) const;
  125. QPointF map(const QPointF &p) const;
  126. QLine map(const QLine &l) const;
  127. QLineF map(const QLineF &l) const;
  128. QPolygonF map(const QPolygonF &a) const;
  129. QPolygon map(const QPolygon &a) const;
  130. QRegion map(const QRegion &r) const;
  131. QPainterPath map(const QPainterPath &p) const;
  132. QPolygon mapToPolygon(const QRect &r) const;
  133. QRect mapRect(const QRect &) const;
  134. QRectF mapRect(const QRectF &) const;
  135. void map(int x, int y, int *tx, int *ty) const;
  136. void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
  137. const QMatrix &toAffine() const;
  138. QTransform &operator*=(qreal div);
  139. QTransform &operator/=(qreal div);
  140. QTransform &operator+=(qreal div);
  141. QTransform &operator-=(qreal div);
  142. static QTransform fromTranslate(qreal dx, qreal dy);
  143. static QTransform fromScale(qreal dx, qreal dy);
  144. private:
  145. inline QTransform(qreal h11, qreal h12, qreal h13,
  146. qreal h21, qreal h22, qreal h23,
  147. qreal h31, qreal h32, qreal h33, bool)
  148. : affine(h11, h12, h21, h22, h31, h32, true)
  149. , m_13(h13), m_23(h23), m_33(h33)
  150. , m_type(TxNone)
  151. , m_dirty(TxProject)
  152. , d(Q_NULLPTR)
  153. {
  154. }
  155. inline QTransform(bool)
  156. : affine(true)
  157. , m_13(0), m_23(0), m_33(1)
  158. , m_type(TxNone)
  159. , m_dirty(TxNone)
  160. , d(Q_NULLPTR)
  161. {
  162. }
  163. inline TransformationType inline_type() const;
  164. QMatrix affine;
  165. qreal m_13;
  166. qreal m_23;
  167. qreal m_33;
  168. mutable uint m_type : 5;
  169. mutable uint m_dirty : 5;
  170. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  171. class Private;
  172. Private *d;
  173. #endif
  174. };
  175. Q_DECLARE_TYPEINFO(QTransform, Q_MOVABLE_TYPE);
  176. Q_GUI_EXPORT Q_DECL_CONST_FUNCTION uint qHash(const QTransform &key, uint seed = 0) Q_DECL_NOTHROW;
  177. /******* inlines *****/
  178. inline QTransform::TransformationType QTransform::inline_type() const
  179. {
  180. if (m_dirty == TxNone)
  181. return static_cast<TransformationType>(m_type);
  182. return type();
  183. }
  184. inline bool QTransform::isAffine() const
  185. {
  186. return inline_type() < TxProject;
  187. }
  188. inline bool QTransform::isIdentity() const
  189. {
  190. return inline_type() == TxNone;
  191. }
  192. inline bool QTransform::isInvertible() const
  193. {
  194. return !qFuzzyIsNull(determinant());
  195. }
  196. inline bool QTransform::isScaling() const
  197. {
  198. return type() >= TxScale;
  199. }
  200. inline bool QTransform::isRotating() const
  201. {
  202. return inline_type() >= TxRotate;
  203. }
  204. inline bool QTransform::isTranslating() const
  205. {
  206. return inline_type() >= TxTranslate;
  207. }
  208. inline qreal QTransform::determinant() const
  209. {
  210. return affine._m11*(m_33*affine._m22-affine._dy*m_23) -
  211. affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13);
  212. }
  213. inline qreal QTransform::det() const
  214. {
  215. return determinant();
  216. }
  217. inline qreal QTransform::m11() const
  218. {
  219. return affine._m11;
  220. }
  221. inline qreal QTransform::m12() const
  222. {
  223. return affine._m12;
  224. }
  225. inline qreal QTransform::m13() const
  226. {
  227. return m_13;
  228. }
  229. inline qreal QTransform::m21() const
  230. {
  231. return affine._m21;
  232. }
  233. inline qreal QTransform::m22() const
  234. {
  235. return affine._m22;
  236. }
  237. inline qreal QTransform::m23() const
  238. {
  239. return m_23;
  240. }
  241. inline qreal QTransform::m31() const
  242. {
  243. return affine._dx;
  244. }
  245. inline qreal QTransform::m32() const
  246. {
  247. return affine._dy;
  248. }
  249. inline qreal QTransform::m33() const
  250. {
  251. return m_33;
  252. }
  253. inline qreal QTransform::dx() const
  254. {
  255. return affine._dx;
  256. }
  257. inline qreal QTransform::dy() const
  258. {
  259. return affine._dy;
  260. }
  261. inline QTransform &QTransform::operator*=(qreal num)
  262. {
  263. if (num == 1.)
  264. return *this;
  265. affine._m11 *= num;
  266. affine._m12 *= num;
  267. m_13 *= num;
  268. affine._m21 *= num;
  269. affine._m22 *= num;
  270. m_23 *= num;
  271. affine._dx *= num;
  272. affine._dy *= num;
  273. m_33 *= num;
  274. if (m_dirty < TxScale)
  275. m_dirty = TxScale;
  276. return *this;
  277. }
  278. inline QTransform &QTransform::operator/=(qreal div)
  279. {
  280. if (div == 0)
  281. return *this;
  282. div = 1/div;
  283. return operator*=(div);
  284. }
  285. inline QTransform &QTransform::operator+=(qreal num)
  286. {
  287. if (num == 0)
  288. return *this;
  289. affine._m11 += num;
  290. affine._m12 += num;
  291. m_13 += num;
  292. affine._m21 += num;
  293. affine._m22 += num;
  294. m_23 += num;
  295. affine._dx += num;
  296. affine._dy += num;
  297. m_33 += num;
  298. m_dirty = TxProject;
  299. return *this;
  300. }
  301. inline QTransform &QTransform::operator-=(qreal num)
  302. {
  303. if (num == 0)
  304. return *this;
  305. affine._m11 -= num;
  306. affine._m12 -= num;
  307. m_13 -= num;
  308. affine._m21 -= num;
  309. affine._m22 -= num;
  310. m_23 -= num;
  311. affine._dx -= num;
  312. affine._dy -= num;
  313. m_33 -= num;
  314. m_dirty = TxProject;
  315. return *this;
  316. }
  317. inline bool qFuzzyCompare(const QTransform& t1, const QTransform& t2)
  318. {
  319. return qFuzzyCompare(t1.m11(), t2.m11())
  320. && qFuzzyCompare(t1.m12(), t2.m12())
  321. && qFuzzyCompare(t1.m13(), t2.m13())
  322. && qFuzzyCompare(t1.m21(), t2.m21())
  323. && qFuzzyCompare(t1.m22(), t2.m22())
  324. && qFuzzyCompare(t1.m23(), t2.m23())
  325. && qFuzzyCompare(t1.m31(), t2.m31())
  326. && qFuzzyCompare(t1.m32(), t2.m32())
  327. && qFuzzyCompare(t1.m33(), t2.m33());
  328. }
  329. /****** stream functions *******************/
  330. #ifndef QT_NO_DATASTREAM
  331. Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &);
  332. Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &);
  333. #endif
  334. #ifndef QT_NO_DEBUG_STREAM
  335. Q_GUI_EXPORT QDebug operator<<(QDebug, const QTransform &);
  336. #endif
  337. /****** end stream functions *******************/
  338. // mathematical semantics
  339. inline QPoint operator*(const QPoint &p, const QTransform &m)
  340. { return m.map(p); }
  341. inline QPointF operator*(const QPointF &p, const QTransform &m)
  342. { return m.map(p); }
  343. inline QLineF operator*(const QLineF &l, const QTransform &m)
  344. { return m.map(l); }
  345. inline QLine operator*(const QLine &l, const QTransform &m)
  346. { return m.map(l); }
  347. inline QPolygon operator *(const QPolygon &a, const QTransform &m)
  348. { return m.map(a); }
  349. inline QPolygonF operator *(const QPolygonF &a, const QTransform &m)
  350. { return m.map(a); }
  351. inline QRegion operator *(const QRegion &r, const QTransform &m)
  352. { return m.map(r); }
  353. inline QPainterPath operator *(const QPainterPath &p, const QTransform &m)
  354. { return m.map(p); }
  355. inline QTransform operator *(const QTransform &a, qreal n)
  356. { QTransform t(a); t *= n; return t; }
  357. inline QTransform operator /(const QTransform &a, qreal n)
  358. { QTransform t(a); t /= n; return t; }
  359. inline QTransform operator +(const QTransform &a, qreal n)
  360. { QTransform t(a); t += n; return t; }
  361. inline QTransform operator -(const QTransform &a, qreal n)
  362. { QTransform t(a); t -= n; return t; }
  363. QT_END_NAMESPACE
  364. #endif // QTRANSFORM_H