1 /*
2  * DQt - D bindings for the Qt Toolkit
3  *
4  * GNU Lesser General Public License Usage
5  * This file may be used under the terms of the GNU Lesser
6  * General Public License version 3 as published by the Free Software
7  * Foundation and appearing in the file LICENSE.LGPL3 included in the
8  * packaging of this file. Please review the following information to
9  * ensure the GNU Lesser General Public License version 3 requirements
10  * will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
11  */
12 module qt.gui.transform;
13 extern(C++):
14 
15 import qt.config;
16 import qt.core.global;
17 import qt.core.line;
18 import qt.core.namespace;
19 import qt.core.point;
20 import qt.core.rect;
21 import qt.core.typeinfo;
22 import qt.core.variant;
23 import qt.gui.painterpath;
24 import qt.gui.polygon;
25 import qt.gui.region;
26 import qt.helpers;
27 
28 
29 /// Binding for C++ class [QTransform](https://doc.qt.io/qt-6/qtransform.html).
30 @Q_RELOCATABLE_TYPE extern(C++, class) struct /+ Q_GUI_EXPORT +/ QTransform
31 {
32 public:
33     enum TransformationType {
34         TxNone      = 0x00,
35         TxTranslate = 0x01,
36         TxScale     = 0x02,
37         TxRotate    = 0x04,
38         TxShear     = 0x08,
39         TxProject   = 0x10
40     }
41 
42     /+ explicit +/pragma(inline, true) this(/+ Qt:: +/qt.core.namespace.Initialization) {}
43     /+pragma(inline, true) this()
44     {
45         this.m_matrix = [ {1, 0, 0}, {0, 1, 0}, {0, 0, 1}] ;
46         this.m_type = TransformationType.TxNone;
47         this.m_dirty = TransformationType.TxNone;
48     }+/
49     this(qreal h11, qreal h12, qreal h13,
50                    qreal h21, qreal h22, qreal h23,
51                    qreal h31, qreal h32, qreal h33)
52     {
53         this.m_matrix = [ [h11, h12, h13], [h21, h22, h23], [h31, h32, h33]] ;
54         this.m_type = TransformationType.TxNone;
55         this.m_dirty = TransformationType.TxProject;
56     }
57     this(qreal h11, qreal h12, qreal h21,
58                    qreal h22, qreal dx, qreal dy)
59     {
60         this.m_matrix = [ [h11, h12, 0], [h21, h22, 0], [dx, dy, 1]] ;
61         this.m_type = TransformationType.TxNone;
62         this.m_dirty = TransformationType.TxShear;
63     }
64 
65     /+ QTransform &operator=(QTransform &&other) noexcept = default; +/
66     /+ QTransform &operator=(const QTransform &) noexcept = default; +/
67     /+ QTransform(QTransform &&other) noexcept = default; +/
68     /+ QTransform(const QTransform &other) noexcept = default; +/
69 
70     pragma(inline, true) bool isAffine() const
71     {
72         return inline_type() < TransformationType.TxProject;
73     }
74     pragma(inline, true) bool isIdentity() const
75     {
76         return inline_type() == TransformationType.TxNone;
77     }
78     pragma(inline, true) bool isInvertible() const
79     {
80         return !qFuzzyIsNull(determinant());
81     }
82     pragma(inline, true) bool isScaling() const
83     {
84         return type() >= TransformationType.TxScale;
85     }
86     pragma(inline, true) bool isRotating() const
87     {
88         return inline_type() >= TransformationType.TxRotate;
89     }
90     pragma(inline, true) bool isTranslating() const
91     {
92         return inline_type() >= TransformationType.TxTranslate;
93     }
94 
95     TransformationType type() const;
96 
97     pragma(inline, true) qreal determinant() const
98     {
99         return m_matrix[0][0] * (m_matrix[2][2] * m_matrix[1][1] - m_matrix[2][1] * m_matrix[1][2]) -
100                m_matrix[1][0] * (m_matrix[2][2] * m_matrix[0][1] - m_matrix[2][1] * m_matrix[0][2]) +
101                m_matrix[2][0] * (m_matrix[1][2] * m_matrix[0][1] - m_matrix[1][1] * m_matrix[0][2]);
102     }
103 
104     pragma(inline, true) qreal m11() const
105     {
106         return m_matrix[0][0];
107     }
108     pragma(inline, true) qreal m12() const
109     {
110         return m_matrix[0][1];
111     }
112     pragma(inline, true) qreal m13() const
113     {
114         return m_matrix[0][2];
115     }
116     pragma(inline, true) qreal m21() const
117     {
118         return m_matrix[1][0];
119     }
120     pragma(inline, true) qreal m22() const
121     {
122         return m_matrix[1][1];
123     }
124     pragma(inline, true) qreal m23() const
125     {
126         return m_matrix[1][2];
127     }
128     pragma(inline, true) qreal m31() const
129     {
130         return m_matrix[2][0];
131     }
132     pragma(inline, true) qreal m32() const
133     {
134         return m_matrix[2][1];
135     }
136     pragma(inline, true) qreal m33() const
137     {
138         return m_matrix[2][2];
139     }
140     pragma(inline, true) qreal dx() const
141     {
142         return m_matrix[2][0];
143     }
144     pragma(inline, true) qreal dy() const
145     {
146         return m_matrix[2][1];
147     }
148 
149     void setMatrix(qreal m11, qreal m12, qreal m13,
150                        qreal m21, qreal m22, qreal m23,
151                        qreal m31, qreal m32, qreal m33);
152 
153     /+ [[nodiscard]] +/ QTransform inverted(bool* invertible = null) const;
154     /+ [[nodiscard]] +/ QTransform adjoint() const;
155     /+ [[nodiscard]] +/ QTransform transposed() const;
156 
157     ref QTransform translate(qreal dx, qreal dy);
158     ref QTransform scale(qreal sx, qreal sy);
159     ref QTransform shear(qreal sh, qreal sv);
160     ref QTransform rotate(qreal a, /+ Qt:: +/qt.core.namespace.Axis axis = /+ Qt:: +/qt.core.namespace.Axis.ZAxis);
161     ref QTransform rotateRadians(qreal a, /+ Qt:: +/qt.core.namespace.Axis axis = /+ Qt:: +/qt.core.namespace.Axis.ZAxis);
162 
163     static bool squareToQuad(ref const(QPolygonF) square, ref QTransform result);
164     static bool quadToSquare(ref const(QPolygonF) quad, ref QTransform result);
165     static bool quadToQuad(ref const(QPolygonF) one,
166                                ref const(QPolygonF) two,
167                                ref QTransform result);
168 
169     /+bool operator ==(ref const(QTransform) ) const;+/
170     /+bool operator !=(ref const(QTransform) ) const;+/
171 
172     /+ref QTransform operator *=(ref const(QTransform) );+/
173     /+QTransform operator *(ref const(QTransform) o) const;+/
174 
175     /+auto opCast(T : QVariant)() const;+/
176 
177     void reset();
178     QPoint       map(ref const(QPoint) p) const;
179     QPointF      map(ref const(QPointF) p) const;
180     QLine        map(ref const(QLine) l) const;
181     QLineF       map(ref const(QLineF) l) const;
182     QPolygonF    map(ref const(QPolygonF) a) const;
183     QPolygon     map(ref const(QPolygon) a) const;
184     QRegion      map(ref const(QRegion) r) const;
185     QPainterPath map(ref const(QPainterPath) p) const;
186     QPolygon     mapToPolygon(ref const(QRect) r) const;
187     QRect mapRect(ref const(QRect) ) const;
188     QRectF mapRect(ref const(QRectF) ) const;
189     void map(int x, int y, int* tx, int* ty) const;
190     void map(qreal x, qreal y, qreal* tx, qreal* ty) const;
191 
192     /+pragma(inline, true) ref QTransform operator *=(qreal num)
193     {
194         if (num == 1.)
195             return this;
196         m_matrix[0][0] *= num;
197         m_matrix[0][1] *= num;
198         m_matrix[0][2] *= num;
199         m_matrix[1][0] *= num;
200         m_matrix[1][1] *= num;
201         m_matrix[1][2] *= num;
202         m_matrix[2][0] *= num;
203         m_matrix[2][1] *= num;
204         m_matrix[2][2] *= num;
205         if (m_dirty < TransformationType.TxScale)
206             m_dirty = TransformationType.TxScale;
207         return this;
208     }+/
209     /+pragma(inline, true) ref QTransform operator /=(qreal div)
210     {
211         if (div == 0)
212             return this;
213         div = 1/div;
214         return operator*=(div);
215     }+/
216     pragma(inline, true) ref QTransform opOpAssign(string op)(qreal num) if(op == "+")
217     {
218         if (num == 0)
219             return this;
220         m_matrix[0][0] += num;
221         m_matrix[0][1] += num;
222         m_matrix[0][2] += num;
223         m_matrix[1][0] += num;
224         m_matrix[1][1] += num;
225         m_matrix[1][2] += num;
226         m_matrix[2][0] += num;
227         m_matrix[2][1] += num;
228         m_matrix[2][2] += num;
229         m_dirty     = TransformationType.TxProject;
230         return this;
231     }
232     pragma(inline, true) ref QTransform opOpAssign(string op)(qreal num) if(op == "-")
233     {
234         if (num == 0)
235             return this;
236         m_matrix[0][0] -= num;
237         m_matrix[0][1] -= num;
238         m_matrix[0][2] -= num;
239         m_matrix[1][0] -= num;
240         m_matrix[1][1] -= num;
241         m_matrix[1][2] -= num;
242         m_matrix[2][0] -= num;
243         m_matrix[2][1] -= num;
244         m_matrix[2][2] -= num;
245         m_dirty     = TransformationType.TxProject;
246         return this;
247     }
248 
249     static QTransform fromTranslate(qreal dx, qreal dy);
250     static QTransform fromScale(qreal dx, qreal dy);
251 
252 private:
253     /+ struct Affine {
254              ref qreal[3][3]  m_matrix;
255         } +/
256 
257 public:
258     //auto asAffineMatrix() { return Affine (m_matrix) ; }
259     /+ friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &s, Affine &m); +/
260     /+ friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &s, const Affine &m); +/
261 
262 private:
263     /******* inlines *****/
264     pragma(inline, true) TransformationType inline_type() const
265     {
266         if (m_dirty == TransformationType.TxNone)
267             return static_cast!(TransformationType)(m_type);
268         return type();
269     }
270     qreal[3][3] m_matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
271 
272     /+ mutable uint m_type : 5; +/
273     ushort bitfieldData_m_type = TransformationType.TxNone | (TransformationType.TxNone << 5);
274     final uint m_type() const
275     {
276         return (bitfieldData_m_type >> 0) & 0x1f;
277     }
278     final uint m_type(uint value)
279     {
280         bitfieldData_m_type = (bitfieldData_m_type & ~0x1f) | ((value & 0x1f) << 0);
281         return value;
282     }
283     /+ mutable uint m_dirty : 5; +/
284     final uint m_dirty() const
285     {
286         return (bitfieldData_m_type >> 5) & 0x1f;
287     }
288     final uint m_dirty(uint value)
289     {
290         bitfieldData_m_type = (bitfieldData_m_type & ~0x3e0) | ((value & 0x1f) << 5);
291         return value;
292     }
293     mixin(CREATE_CONVENIENCE_WRAPPERS);
294 }
295 /+ Q_DECLARE_TYPEINFO(QTransform, Q_RELOCATABLE_TYPE);
296 
297 Q_GUI_EXPORT Q_DECL_CONST_FUNCTION size_t qHash(const QTransform &key, size_t seed = 0) noexcept;
298 
299 QT_WARNING_PUSH
300 QT_WARNING_DISABLE_FLOAT_COMPARE
301 
302 QT_WARNING_POP +/
303 
304 pragma(inline, true) bool qFuzzyCompare(ref const(QTransform) t1, ref const(QTransform) t2)
305 {
306     return qt.core.global.qFuzzyCompare(t1.m11(), t2.m11())
307         && qt.core.global.qFuzzyCompare(t1.m12(), t2.m12())
308         && qt.core.global.qFuzzyCompare(t1.m13(), t2.m13())
309         && qt.core.global.qFuzzyCompare(t1.m21(), t2.m21())
310         && qt.core.global.qFuzzyCompare(t1.m22(), t2.m22())
311         && qt.core.global.qFuzzyCompare(t1.m23(), t2.m23())
312         && qt.core.global.qFuzzyCompare(t1.m31(), t2.m31())
313         && qt.core.global.qFuzzyCompare(t1.m32(), t2.m32())
314         && qt.core.global.qFuzzyCompare(t1.m33(), t2.m33());
315 }
316 
317 
318 /****** stream functions *******************/
319 /+ #ifndef QT_NO_DATASTREAM
320 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &);
321 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &);
322 #endif
323 
324 #ifndef QT_NO_DEBUG_STREAM
325 Q_GUI_EXPORT QDebug operator<<(QDebug, const QTransform &);
326 #endif +/
327 /****** end stream functions *******************/
328 
329 // mathematical semantics
330 /+pragma(inline, true) QPoint operator *(ref const(QPoint) p, ref const(QTransform) m)
331 { return m.map(p); }+/
332 /+pragma(inline, true) QPointF operator *(ref const(QPointF) p, ref const(QTransform) m)
333 { return m.map(p); }+/
334 /+pragma(inline, true) QLineF operator *(ref const(QLineF) l, ref const(QTransform) m)
335 { return m.map(l); }+/
336 /+pragma(inline, true) QLine operator *(ref const(QLine) l, ref const(QTransform) m)
337 { return m.map(l); }+/
338 /+pragma(inline, true) QPolygon operator *(ref const(QPolygon) a, ref const(QTransform) m)
339 { return m.map(a); }+/
340 /+pragma(inline, true) QPolygonF operator *(ref const(QPolygonF) a, ref const(QTransform) m)
341 { return m.map(a); }+/
342 /+pragma(inline, true) QRegion operator *(ref const(QRegion) r, ref const(QTransform) m)
343 { return m.map(r); }+/
344 
345 /+pragma(inline, true) QTransform operator *(ref const(QTransform) a, qreal n)
346 { auto t = QTransform(a); t *= n; return t; }+/
347 /+pragma(inline, true) QTransform operator /(ref const(QTransform) a, qreal n)
348 { auto t = QTransform(a); t /= n; return t; }+/
349 /+pragma(inline, true) QTransform operator +(ref const(QTransform) a, qreal n)
350 { auto t = QTransform(a); t += n; return t; }+/
351 /+pragma(inline, true) QTransform operator -(ref const(QTransform) a, qreal n)
352 { auto t = QTransform(a); t -= n; return t; }+/
353