File indexing completed on 2025-09-18 09:27:40
0001
0002
0003 #ifndef QTRANSFORM_H
0004 #define QTRANSFORM_H
0005
0006 #include <QtGui/qtguiglobal.h>
0007 #include <QtGui/qpolygon.h>
0008 #include <QtGui/qregion.h>
0009 #include <QtGui/qwindowdefs.h>
0010 #include <QtCore/qline.h>
0011 #include <QtCore/qpoint.h>
0012 #include <QtCore/qrect.h>
0013
0014 QT_BEGIN_NAMESPACE
0015
0016 class QVariant;
0017 class QPainterPath;
0018
0019 class Q_GUI_EXPORT QTransform
0020 {
0021 public:
0022 enum TransformationType {
0023 TxNone = 0x00,
0024 TxTranslate = 0x01,
0025 TxScale = 0x02,
0026 TxRotate = 0x04,
0027 TxShear = 0x08,
0028 TxProject = 0x10
0029 };
0030
0031 inline explicit QTransform(Qt::Initialization) {}
0032 inline QTransform()
0033 : m_matrix{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }
0034 , m_type(TxNone)
0035 , m_dirty(TxNone) {}
0036 QTransform(qreal h11, qreal h12, qreal h13,
0037 qreal h21, qreal h22, qreal h23,
0038 qreal h31, qreal h32, qreal h33)
0039 : m_matrix{ {h11, h12, h13}, {h21, h22, h23}, {h31, h32, h33} }
0040 , m_type(TxNone)
0041 , m_dirty(TxProject) {}
0042 QTransform(qreal h11, qreal h12, qreal h21,
0043 qreal h22, qreal dx, qreal dy)
0044 : m_matrix{ {h11, h12, 0}, {h21, h22, 0}, {dx, dy, 1} }
0045 , m_type(TxNone)
0046 , m_dirty(TxShear) {}
0047
0048 QTransform &operator=(QTransform &&other) noexcept = default;
0049 QTransform &operator=(const QTransform &) noexcept = default;
0050 QTransform(QTransform &&other) noexcept = default;
0051 QTransform(const QTransform &other) noexcept = default;
0052
0053 bool isAffine() const;
0054 bool isIdentity() const;
0055 bool isInvertible() const;
0056 bool isScaling() const;
0057 bool isRotating() const;
0058 bool isTranslating() const;
0059
0060 TransformationType type() const;
0061
0062 inline qreal determinant() const;
0063
0064 qreal m11() const;
0065 qreal m12() const;
0066 qreal m13() const;
0067 qreal m21() const;
0068 qreal m22() const;
0069 qreal m23() const;
0070 qreal m31() const;
0071 qreal m32() const;
0072 qreal m33() const;
0073 qreal dx() const;
0074 qreal dy() const;
0075
0076 void setMatrix(qreal m11, qreal m12, qreal m13,
0077 qreal m21, qreal m22, qreal m23,
0078 qreal m31, qreal m32, qreal m33);
0079
0080 [[nodiscard]] QTransform inverted(bool *invertible = nullptr) const;
0081 [[nodiscard]] QTransform adjoint() const;
0082 [[nodiscard]] QTransform transposed() const;
0083
0084 QTransform &translate(qreal dx, qreal dy);
0085 QTransform &scale(qreal sx, qreal sy);
0086 QTransform &shear(qreal sh, qreal sv);
0087 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
0088 QTransform &rotate(qreal a, Qt::Axis axis, qreal distanceToPlane);
0089
0090 QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis);
0091 QTransform &rotateRadians(qreal a, Qt::Axis axis, qreal distanceToPlane);
0092
0093 QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis);
0094 #else
0095 QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis, qreal distanceToPlane = 1024.0f);
0096 QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis, qreal distanceToPlane = 1024.0f);
0097 #endif
0098
0099 static bool squareToQuad(const QPolygonF &square, QTransform &result);
0100 static bool quadToSquare(const QPolygonF &quad, QTransform &result);
0101 static bool quadToQuad(const QPolygonF &one,
0102 const QPolygonF &two,
0103 QTransform &result);
0104
0105 bool operator==(const QTransform &) const;
0106 bool operator!=(const QTransform &) const;
0107
0108 QTransform &operator*=(const QTransform &);
0109 QTransform operator*(const QTransform &o) const;
0110
0111 operator QVariant() const;
0112
0113 void reset();
0114 QPoint map(const QPoint &p) const;
0115 QPointF map(const QPointF &p) const;
0116 QLine map(const QLine &l) const;
0117 QLineF map(const QLineF &l) const;
0118 QPolygonF map(const QPolygonF &a) const;
0119 QPolygon map(const QPolygon &a) const;
0120 QRegion map(const QRegion &r) const;
0121 QPainterPath map(const QPainterPath &p) const;
0122 QPolygon mapToPolygon(const QRect &r) const;
0123 QRect mapRect(const QRect &) const;
0124 QRectF mapRect(const QRectF &) const;
0125 void map(int x, int y, int *tx, int *ty) const;
0126 void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
0127
0128 QTransform &operator*=(qreal div);
0129 QTransform &operator/=(qreal div);
0130 QTransform &operator+=(qreal div);
0131 QTransform &operator-=(qreal div);
0132
0133 static QTransform fromTranslate(qreal dx, qreal dy);
0134 static QTransform fromScale(qreal dx, qreal dy);
0135
0136 private:
0137 struct Affine {
0138 qreal (& m_matrix)[3][3];
0139 };
0140
0141 public:
0142 auto asAffineMatrix() { return Affine { m_matrix }; }
0143 friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &s, Affine &m);
0144 friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &s, const Affine &m);
0145
0146 private:
0147 inline TransformationType inline_type() const;
0148 void do_map(qreal x, qreal y, qreal &nx, qreal &ny) const;
0149 qreal m_matrix[3][3];
0150
0151 mutable uint m_type : 5;
0152 mutable uint m_dirty : 5;
0153 };
0154 Q_DECLARE_TYPEINFO(QTransform, Q_RELOCATABLE_TYPE);
0155
0156 Q_GUI_EXPORT Q_DECL_CONST_FUNCTION size_t qHash(const QTransform &key, size_t seed = 0) noexcept;
0157
0158
0159 inline QTransform::TransformationType QTransform::inline_type() const
0160 {
0161 if (m_dirty == TxNone)
0162 return static_cast<TransformationType>(m_type);
0163 return type();
0164 }
0165
0166 inline bool QTransform::isAffine() const
0167 {
0168 return inline_type() < TxProject;
0169 }
0170 inline bool QTransform::isIdentity() const
0171 {
0172 return inline_type() == TxNone;
0173 }
0174
0175 inline bool QTransform::isInvertible() const
0176 {
0177 return !qFuzzyIsNull(determinant());
0178 }
0179
0180 inline bool QTransform::isScaling() const
0181 {
0182 return type() >= TxScale;
0183 }
0184 inline bool QTransform::isRotating() const
0185 {
0186 return inline_type() >= TxRotate;
0187 }
0188
0189 inline bool QTransform::isTranslating() const
0190 {
0191 return inline_type() >= TxTranslate;
0192 }
0193
0194 inline qreal QTransform::determinant() const
0195 {
0196 return m_matrix[0][0] * (m_matrix[2][2] * m_matrix[1][1] - m_matrix[2][1] * m_matrix[1][2]) -
0197 m_matrix[1][0] * (m_matrix[2][2] * m_matrix[0][1] - m_matrix[2][1] * m_matrix[0][2]) +
0198 m_matrix[2][0] * (m_matrix[1][2] * m_matrix[0][1] - m_matrix[1][1] * m_matrix[0][2]);
0199 }
0200 inline qreal QTransform::m11() const
0201 {
0202 return m_matrix[0][0];
0203 }
0204 inline qreal QTransform::m12() const
0205 {
0206 return m_matrix[0][1];
0207 }
0208 inline qreal QTransform::m13() const
0209 {
0210 return m_matrix[0][2];
0211 }
0212 inline qreal QTransform::m21() const
0213 {
0214 return m_matrix[1][0];
0215 }
0216 inline qreal QTransform::m22() const
0217 {
0218 return m_matrix[1][1];
0219 }
0220 inline qreal QTransform::m23() const
0221 {
0222 return m_matrix[1][2];
0223 }
0224 inline qreal QTransform::m31() const
0225 {
0226 return m_matrix[2][0];
0227 }
0228 inline qreal QTransform::m32() const
0229 {
0230 return m_matrix[2][1];
0231 }
0232 inline qreal QTransform::m33() const
0233 {
0234 return m_matrix[2][2];
0235 }
0236 inline qreal QTransform::dx() const
0237 {
0238 return m_matrix[2][0];
0239 }
0240 inline qreal QTransform::dy() const
0241 {
0242 return m_matrix[2][1];
0243 }
0244
0245 QT_WARNING_PUSH
0246 QT_WARNING_DISABLE_FLOAT_COMPARE
0247
0248 inline QTransform &QTransform::operator*=(qreal num)
0249 {
0250 if (num == 1.)
0251 return *this;
0252 m_matrix[0][0] *= num;
0253 m_matrix[0][1] *= num;
0254 m_matrix[0][2] *= num;
0255 m_matrix[1][0] *= num;
0256 m_matrix[1][1] *= num;
0257 m_matrix[1][2] *= num;
0258 m_matrix[2][0] *= num;
0259 m_matrix[2][1] *= num;
0260 m_matrix[2][2] *= num;
0261 if (m_dirty < TxScale)
0262 m_dirty = TxScale;
0263 return *this;
0264 }
0265 inline QTransform &QTransform::operator/=(qreal div)
0266 {
0267 if (div == 0)
0268 return *this;
0269 div = 1/div;
0270 return operator*=(div);
0271 }
0272 inline QTransform &QTransform::operator+=(qreal num)
0273 {
0274 if (num == 0)
0275 return *this;
0276 m_matrix[0][0] += num;
0277 m_matrix[0][1] += num;
0278 m_matrix[0][2] += num;
0279 m_matrix[1][0] += num;
0280 m_matrix[1][1] += num;
0281 m_matrix[1][2] += num;
0282 m_matrix[2][0] += num;
0283 m_matrix[2][1] += num;
0284 m_matrix[2][2] += num;
0285 m_dirty = TxProject;
0286 return *this;
0287 }
0288 inline QTransform &QTransform::operator-=(qreal num)
0289 {
0290 if (num == 0)
0291 return *this;
0292 m_matrix[0][0] -= num;
0293 m_matrix[0][1] -= num;
0294 m_matrix[0][2] -= num;
0295 m_matrix[1][0] -= num;
0296 m_matrix[1][1] -= num;
0297 m_matrix[1][2] -= num;
0298 m_matrix[2][0] -= num;
0299 m_matrix[2][1] -= num;
0300 m_matrix[2][2] -= num;
0301 m_dirty = TxProject;
0302 return *this;
0303 }
0304
0305 QT_WARNING_POP
0306
0307 inline bool qFuzzyCompare(const QTransform& t1, const QTransform& t2) noexcept
0308 {
0309 return qFuzzyCompare(t1.m11(), t2.m11())
0310 && qFuzzyCompare(t1.m12(), t2.m12())
0311 && qFuzzyCompare(t1.m13(), t2.m13())
0312 && qFuzzyCompare(t1.m21(), t2.m21())
0313 && qFuzzyCompare(t1.m22(), t2.m22())
0314 && qFuzzyCompare(t1.m23(), t2.m23())
0315 && qFuzzyCompare(t1.m31(), t2.m31())
0316 && qFuzzyCompare(t1.m32(), t2.m32())
0317 && qFuzzyCompare(t1.m33(), t2.m33());
0318 }
0319
0320
0321
0322 #ifndef QT_NO_DATASTREAM
0323 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &);
0324 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &);
0325 #endif
0326
0327 #ifndef QT_NO_DEBUG_STREAM
0328 Q_GUI_EXPORT QDebug operator<<(QDebug, const QTransform &);
0329 #endif
0330
0331
0332
0333 inline QPoint operator*(const QPoint &p, const QTransform &m)
0334 { return m.map(p); }
0335 inline QPointF operator*(const QPointF &p, const QTransform &m)
0336 { return m.map(p); }
0337 inline QLineF operator*(const QLineF &l, const QTransform &m)
0338 { return m.map(l); }
0339 inline QLine operator*(const QLine &l, const QTransform &m)
0340 { return m.map(l); }
0341 inline QPolygon operator *(const QPolygon &a, const QTransform &m)
0342 { return m.map(a); }
0343 inline QPolygonF operator *(const QPolygonF &a, const QTransform &m)
0344 { return m.map(a); }
0345 inline QRegion operator *(const QRegion &r, const QTransform &m)
0346 { return m.map(r); }
0347
0348 inline QTransform operator *(const QTransform &a, qreal n)
0349 { QTransform t(a); t *= n; return t; }
0350 inline QTransform operator /(const QTransform &a, qreal n)
0351 { QTransform t(a); t /= n; return t; }
0352 inline QTransform operator +(const QTransform &a, qreal n)
0353 { QTransform t(a); t += n; return t; }
0354 inline QTransform operator -(const QTransform &a, qreal n)
0355 { QTransform t(a); t -= n; return t; }
0356
0357 QT_END_NAMESPACE
0358
0359 #endif