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