Coverage Report

Created: 2026-03-31 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/prefix/include/QtGui/qtransform.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
#ifndef QTRANSFORM_H
5
#define QTRANSFORM_H
6
7
#include <QtGui/qtguiglobal.h>
8
#include <QtGui/qpolygon.h>
9
#include <QtGui/qregion.h>
10
#include <QtGui/qwindowdefs.h>
11
#include <QtCore/qline.h>
12
#include <QtCore/qpoint.h>
13
#include <QtCore/qrect.h>
14
15
QT_BEGIN_NAMESPACE
16
17
class QVariant;
18
class QPainterPath;
19
20
class Q_GUI_EXPORT QTransform
21
{
22
public:
23
    enum TransformationType {
24
        TxNone      = 0x00,
25
        TxTranslate = 0x01,
26
        TxScale     = 0x02,
27
        TxRotate    = 0x04,
28
        TxShear     = 0x08,
29
        TxProject   = 0x10
30
    };
31
32
0
    inline explicit QTransform(Qt::Initialization) {}
33
    inline QTransform()
34
        : m_matrix{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }
35
        , m_type(TxNone)
36
0
        , m_dirty(TxNone) {}
37
    QTransform(qreal h11, qreal h12, qreal h13,
38
               qreal h21, qreal h22, qreal h23,
39
               qreal h31, qreal h32, qreal h33)
40
        : m_matrix{ {h11, h12, h13}, {h21, h22, h23}, {h31, h32, h33} }
41
        , m_type(TxNone)
42
0
        , m_dirty(TxProject) {}
43
    QTransform(qreal h11, qreal h12, qreal h21,
44
               qreal h22, qreal dx, qreal dy)
45
        : m_matrix{ {h11, h12, 0}, {h21, h22, 0}, {dx, dy, 1} }
46
        , m_type(TxNone)
47
0
        , m_dirty(TxShear) {}
48
49
    QTransform &operator=(QTransform &&other) noexcept = default;
50
    QTransform &operator=(const QTransform &) noexcept = default;
51
    QTransform(QTransform &&other) noexcept = default;
52
    QTransform(const QTransform &other) noexcept = default;
53
54
    bool isAffine() const;
55
    bool isIdentity() const;
56
    bool isInvertible() const;
57
    bool isScaling() const;
58
    bool isRotating() const;
59
    bool isTranslating() const;
60
61
    TransformationType type() const;
62
63
    inline qreal determinant() const;
64
65
    qreal m11() const;
66
    qreal m12() const;
67
    qreal m13() const;
68
    qreal m21() const;
69
    qreal m22() const;
70
    qreal m23() const;
71
    qreal m31() const;
72
    qreal m32() const;
73
    qreal m33() const;
74
    qreal dx() const;
75
    qreal dy() const;
76
77
    void setMatrix(qreal m11, qreal m12, qreal m13,
78
                   qreal m21, qreal m22, qreal m23,
79
                   qreal m31, qreal m32, qreal m33);
80
81
    [[nodiscard]] QTransform inverted(bool *invertible = nullptr) const;
82
    [[nodiscard]] QTransform adjoint() const;
83
    [[nodiscard]] QTransform transposed() const;
84
85
    QTransform &translate(qreal dx, qreal dy);
86
    QTransform &scale(qreal sx, qreal sy);
87
    QTransform &shear(qreal sh, qreal sv);
88
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
89
    QTransform &rotate(qreal a, Qt::Axis axis, qreal distanceToPlane);
90
    // ### Qt7: Remove
91
    QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis);
92
    QTransform &rotateRadians(qreal a, Qt::Axis axis, qreal distanceToPlane);
93
    // ### Qt7: Remove
94
    QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis);
95
#else
96
    QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis, qreal distanceToPlane = 1024.0f);
97
    QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis, qreal distanceToPlane = 1024.0f);
98
#endif
99
100
    static bool squareToQuad(const QPolygonF &square, QTransform &result);
101
    static bool quadToSquare(const QPolygonF &quad, QTransform &result);
102
    static bool quadToQuad(const QPolygonF &one,
103
                           const QPolygonF &two,
104
                           QTransform &result);
105
106
    bool operator==(const QTransform &) const;
107
    bool operator!=(const QTransform &) const;
108
109
    QTransform &operator*=(const QTransform &);
110
    QTransform operator*(const QTransform &o) const;
111
112
    operator QVariant() const;
113
114
    void reset();
115
    QPoint       map(const QPoint &p) const;
116
    QPointF      map(const QPointF &p) const;
117
    QLine        map(const QLine &l) const;
118
    QLineF       map(const QLineF &l) const;
119
    QPolygonF    map(const QPolygonF &a) const;
120
    QPolygon     map(const QPolygon &a) const;
121
    QRegion      map(const QRegion &r) const;
122
    QPainterPath map(const QPainterPath &p) const;
123
    QPolygon     mapToPolygon(const QRect &r) const;
124
    QRect mapRect(const QRect &) const;
125
    QRectF mapRect(const QRectF &) const;
126
    void map(int x, int y, int *tx, int *ty) const;
127
    void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
128
129
    QTransform &operator*=(qreal div);
130
    QTransform &operator/=(qreal div);
131
    QTransform &operator+=(qreal div);
132
    QTransform &operator-=(qreal div);
133
134
    static QTransform fromTranslate(qreal dx, qreal dy);
135
    static QTransform fromScale(qreal dx, qreal dy);
136
137
private:
138
    struct Affine {
139
             qreal (& m_matrix)[3][3];
140
        };
141
142
public:
143
0
    auto asAffineMatrix() { return Affine { m_matrix }; }
144
    friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &s, Affine &m);
145
    friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &s, const Affine &m);
146
147
private:
148
    inline TransformationType inline_type() const;
149
    void do_map(qreal x, qreal y, qreal &nx, qreal &ny) const;
150
    qreal m_matrix[3][3];
151
152
    mutable uint m_type : 5;
153
    mutable uint m_dirty : 5;
154
};
155
Q_DECLARE_TYPEINFO(QTransform, Q_RELOCATABLE_TYPE);
156
157
Q_GUI_EXPORT Q_DECL_CONST_FUNCTION size_t qHash(const QTransform &key, size_t seed = 0) noexcept;
158
159
/******* inlines *****/
160
inline QTransform::TransformationType QTransform::inline_type() const
161
0
{
162
0
    if (m_dirty == TxNone)
163
0
        return static_cast<TransformationType>(m_type);
164
0
    return type();
165
0
}
166
167
inline bool QTransform::isAffine() const
168
0
{
169
0
    return inline_type() < TxProject;
170
0
}
171
inline bool QTransform::isIdentity() const
172
0
{
173
0
    return inline_type() == TxNone;
174
0
}
175
176
inline bool QTransform::isInvertible() const
177
0
{
178
0
    return !qFuzzyIsNull(determinant());
179
0
}
180
181
inline bool QTransform::isScaling() const
182
0
{
183
0
    return type() >= TxScale;
184
0
}
185
inline bool QTransform::isRotating() const
186
0
{
187
0
    return inline_type() >= TxRotate;
188
0
}
189
190
inline bool QTransform::isTranslating() const
191
0
{
192
0
    return inline_type() >= TxTranslate;
193
0
}
194
195
inline qreal QTransform::determinant() const
196
0
{
197
0
    return m_matrix[0][0] * (m_matrix[2][2] * m_matrix[1][1] - m_matrix[2][1] * m_matrix[1][2]) -
198
0
           m_matrix[1][0] * (m_matrix[2][2] * m_matrix[0][1] - m_matrix[2][1] * m_matrix[0][2]) +
199
0
           m_matrix[2][0] * (m_matrix[1][2] * m_matrix[0][1] - m_matrix[1][1] * m_matrix[0][2]);
200
0
}
201
inline qreal QTransform::m11() const
202
0
{
203
0
    return m_matrix[0][0];
204
0
}
205
inline qreal QTransform::m12() const
206
0
{
207
0
    return m_matrix[0][1];
208
0
}
209
inline qreal QTransform::m13() const
210
0
{
211
0
    return m_matrix[0][2];
212
0
}
213
inline qreal QTransform::m21() const
214
0
{
215
0
    return m_matrix[1][0];
216
0
}
217
inline qreal QTransform::m22() const
218
0
{
219
0
    return m_matrix[1][1];
220
0
}
221
inline qreal QTransform::m23() const
222
0
{
223
0
    return m_matrix[1][2];
224
0
}
225
inline qreal QTransform::m31() const
226
0
{
227
0
    return m_matrix[2][0];
228
0
}
229
inline qreal QTransform::m32() const
230
0
{
231
0
    return m_matrix[2][1];
232
0
}
233
inline qreal QTransform::m33() const
234
0
{
235
0
    return m_matrix[2][2];
236
0
}
237
inline qreal QTransform::dx() const
238
0
{
239
0
    return m_matrix[2][0];
240
0
}
241
inline qreal QTransform::dy() const
242
0
{
243
0
    return m_matrix[2][1];
244
0
}
245
246
QT_WARNING_PUSH
247
QT_WARNING_DISABLE_FLOAT_COMPARE
248
249
inline QTransform &QTransform::operator*=(qreal num)
250
0
{
251
0
    if (num == 1.)
252
0
        return *this;
253
0
    m_matrix[0][0] *= num;
254
0
    m_matrix[0][1] *= num;
255
0
    m_matrix[0][2] *= num;
256
0
    m_matrix[1][0] *= num;
257
0
    m_matrix[1][1] *= num;
258
0
    m_matrix[1][2] *= num;
259
0
    m_matrix[2][0] *= num;
260
0
    m_matrix[2][1] *= num;
261
0
    m_matrix[2][2] *= num;
262
0
    if (m_dirty < TxScale)
263
0
        m_dirty = TxScale;
264
0
    return *this;
265
0
}
266
inline QTransform &QTransform::operator/=(qreal div)
267
0
{
268
0
    if (div == 0)
269
0
        return *this;
270
0
    div = 1/div;
271
0
    return operator*=(div);
272
0
}
273
inline QTransform &QTransform::operator+=(qreal num)
274
0
{
275
0
    if (num == 0)
276
0
        return *this;
277
0
    m_matrix[0][0] += num;
278
0
    m_matrix[0][1] += num;
279
0
    m_matrix[0][2] += num;
280
0
    m_matrix[1][0] += num;
281
0
    m_matrix[1][1] += num;
282
0
    m_matrix[1][2] += num;
283
0
    m_matrix[2][0] += num;
284
0
    m_matrix[2][1] += num;
285
0
    m_matrix[2][2] += num;
286
0
    m_dirty     = TxProject;
287
0
    return *this;
288
0
}
289
inline QTransform &QTransform::operator-=(qreal num)
290
0
{
291
0
    if (num == 0)
292
0
        return *this;
293
0
    m_matrix[0][0] -= num;
294
0
    m_matrix[0][1] -= num;
295
0
    m_matrix[0][2] -= num;
296
0
    m_matrix[1][0] -= num;
297
0
    m_matrix[1][1] -= num;
298
0
    m_matrix[1][2] -= num;
299
0
    m_matrix[2][0] -= num;
300
0
    m_matrix[2][1] -= num;
301
0
    m_matrix[2][2] -= num;
302
0
    m_dirty     = TxProject;
303
0
    return *this;
304
0
}
305
306
QT_WARNING_POP
307
308
inline bool qFuzzyCompare(const QTransform& t1, const QTransform& t2) noexcept
309
0
{
310
0
    return qFuzzyCompare(t1.m11(), t2.m11())
311
0
        && qFuzzyCompare(t1.m12(), t2.m12())
312
0
        && qFuzzyCompare(t1.m13(), t2.m13())
313
0
        && qFuzzyCompare(t1.m21(), t2.m21())
314
0
        && qFuzzyCompare(t1.m22(), t2.m22())
315
0
        && qFuzzyCompare(t1.m23(), t2.m23())
316
0
        && qFuzzyCompare(t1.m31(), t2.m31())
317
0
        && qFuzzyCompare(t1.m32(), t2.m32())
318
0
        && qFuzzyCompare(t1.m33(), t2.m33());
319
0
}
320
321
322
/****** stream functions *******************/
323
#ifndef QT_NO_DATASTREAM
324
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &);
325
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &);
326
#endif
327
328
#ifndef QT_NO_DEBUG_STREAM
329
Q_GUI_EXPORT QDebug operator<<(QDebug, const QTransform &);
330
#endif
331
/****** end stream functions *******************/
332
333
// mathematical semantics
334
inline QPoint operator*(const QPoint &p, const QTransform &m)
335
0
{ return m.map(p); }
336
inline QPointF operator*(const QPointF &p, const QTransform &m)
337
0
{ return m.map(p); }
338
inline QLineF operator*(const QLineF &l, const QTransform &m)
339
0
{ return m.map(l); }
340
inline QLine operator*(const QLine &l, const QTransform &m)
341
0
{ return m.map(l); }
342
inline QPolygon operator *(const QPolygon &a, const QTransform &m)
343
0
{ return m.map(a); }
344
inline QPolygonF operator *(const QPolygonF &a, const QTransform &m)
345
0
{ return m.map(a); }
346
inline QRegion operator *(const QRegion &r, const QTransform &m)
347
0
{ return m.map(r); }
348
349
inline QTransform operator *(const QTransform &a, qreal n)
350
0
{ QTransform t(a); t *= n; return t; }
351
inline QTransform operator /(const QTransform &a, qreal n)
352
0
{ QTransform t(a); t /= n; return t; }
353
inline QTransform operator +(const QTransform &a, qreal n)
354
0
{ QTransform t(a); t += n; return t; }
355
inline QTransform operator -(const QTransform &a, qreal n)
356
0
{ QTransform t(a); t -= n; return t; }
357
358
QT_END_NAMESPACE
359
360
#endif // QTRANSFORM_H