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 QtCore 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
40#ifndef QPOINT_H
41#define QPOINT_H
42
43#include <QtCore/qnamespace.h>
44
45#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
46struct CGPoint;
47#endif
48
49QT_BEGIN_NAMESPACE
50
51class QPoint
52{
53public:
54 constexpr QPoint() noexcept;
55 constexpr QPoint(int xpos, int ypos) noexcept;
56
57 constexpr inline bool isNull() const noexcept;
58
59 constexpr inline int x() const noexcept;
60 constexpr inline int y() const noexcept;
61 constexpr inline void setX(int x) noexcept;
62 constexpr inline void setY(int y) noexcept;
63
64 constexpr inline int manhattanLength() const;
65
66 constexpr QPoint transposed() const noexcept { return {yp, xp}; }
67
68 constexpr inline int &rx() noexcept;
69 constexpr inline int &ry() noexcept;
70
71 constexpr inline QPoint &operator+=(const QPoint &p);
72 constexpr inline QPoint &operator-=(const QPoint &p);
73
74 constexpr inline QPoint &operator*=(float factor);
75 constexpr inline QPoint &operator*=(double factor);
76 constexpr inline QPoint &operator*=(int factor);
77
78 constexpr inline QPoint &operator/=(qreal divisor);
79
80 constexpr static inline int dotProduct(const QPoint &p1, const QPoint &p2)
81 { return p1.xp * p2.xp + p1.yp * p2.yp; }
82
83 friend constexpr inline bool operator==(const QPoint &p1, const QPoint &p2) noexcept
84 { return p1.xp == p2.xp && p1.yp == p2.yp; }
85 friend constexpr inline bool operator!=(const QPoint &p1, const QPoint &p2) noexcept
86 { return p1.xp != p2.xp || p1.yp != p2.yp; }
87 friend constexpr inline QPoint operator+(const QPoint &p1, const QPoint &p2) noexcept
88 { return QPoint(p1.xp + p2.xp, p1.yp + p2.yp); }
89 friend constexpr inline QPoint operator-(const QPoint &p1, const QPoint &p2) noexcept
90 { return QPoint(p1.xp - p2.xp, p1.yp - p2.yp); }
91 friend constexpr inline QPoint operator*(const QPoint &p, float factor)
92 { return QPoint(qRound(p.xp * factor), qRound(p.yp * factor)); }
93 friend constexpr inline QPoint operator*(const QPoint &p, double factor)
94 { return QPoint(qRound(p.xp * factor), qRound(p.yp * factor)); }
95 friend constexpr inline QPoint operator*(const QPoint &p, int factor) noexcept
96 { return QPoint(p.xp * factor, p.yp * factor); }
97 friend constexpr inline QPoint operator*(float factor, const QPoint &p)
98 { return QPoint(qRound(p.xp * factor), qRound(p.yp * factor)); }
99 friend constexpr inline QPoint operator*(double factor, const QPoint &p)
100 { return QPoint(qRound(p.xp * factor), qRound(p.yp * factor)); }
101 friend constexpr inline QPoint operator*(int factor, const QPoint &p) noexcept
102 { return QPoint(p.xp * factor, p.yp * factor); }
103 friend constexpr inline QPoint operator+(const QPoint &p) noexcept
104 { return p; }
105 friend constexpr inline QPoint operator-(const QPoint &p) noexcept
106 { return QPoint(-p.xp, -p.yp); }
107 friend constexpr inline QPoint operator/(const QPoint &p, qreal c)
108 { return QPoint(qRound(p.xp / c), qRound(p.yp / c)); }
109
110#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
111 [[nodiscard]] Q_CORE_EXPORT CGPoint toCGPoint() const noexcept;
112#endif
113
114private:
115 friend class QTransform;
116 int xp;
117 int yp;
118
119 template <std::size_t I,
120 typename P,
121 std::enable_if_t<(I < 2), bool> = true,
122 std::enable_if_t<std::is_same_v<std::decay_t<P>, QPoint>, bool> = true>
123 friend constexpr decltype(auto) get(P &&p) noexcept
124 {
125 if constexpr (I == 0)
126 return (std::forward<P>(p).xp);
127 else if constexpr (I == 1)
128 return (std::forward<P>(p).yp);
129 }
130};
131
132Q_DECLARE_TYPEINFO(QPoint, Q_PRIMITIVE_TYPE);
133
134/*****************************************************************************
135 QPoint stream functions
136 *****************************************************************************/
137#ifndef QT_NO_DATASTREAM
138Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPoint &);
139Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPoint &);
140#endif
141
142/*****************************************************************************
143 QPoint inline functions
144 *****************************************************************************/
145
146constexpr inline QPoint::QPoint() noexcept : xp(0), yp(0) {}
147
148constexpr inline QPoint::QPoint(int xpos, int ypos) noexcept : xp(xpos), yp(ypos) {}
149
150constexpr inline bool QPoint::isNull() const noexcept
151{
152 return xp == 0 && yp == 0;
153}
154
155constexpr inline int QPoint::x() const noexcept
156{
157 return xp;
158}
159
160constexpr inline int QPoint::y() const noexcept
161{
162 return yp;
163}
164
165constexpr inline void QPoint::setX(int xpos) noexcept
166{
167 xp = xpos;
168}
169
170constexpr inline void QPoint::setY(int ypos) noexcept
171{
172 yp = ypos;
173}
174
175inline int constexpr QPoint::manhattanLength() const
176{
177 return qAbs(x()) + qAbs(y());
178}
179
180constexpr inline int &QPoint::rx() noexcept
181{
182 return xp;
183}
184
185constexpr inline int &QPoint::ry() noexcept
186{
187 return yp;
188}
189
190constexpr inline QPoint &QPoint::operator+=(const QPoint &p)
191{
192 xp += p.xp;
193 yp += p.yp;
194 return *this;
195}
196
197constexpr inline QPoint &QPoint::operator-=(const QPoint &p)
198{
199 xp -= p.xp;
200 yp -= p.yp;
201 return *this;
202}
203
204constexpr inline QPoint &QPoint::operator*=(float factor)
205{
206 xp = qRound(xp * factor);
207 yp = qRound(yp * factor);
208 return *this;
209}
210
211constexpr inline QPoint &QPoint::operator*=(double factor)
212{
213 xp = qRound(xp * factor);
214 yp = qRound(yp * factor);
215 return *this;
216}
217
218constexpr inline QPoint &QPoint::operator*=(int factor)
219{
220 xp = xp * factor;
221 yp = yp * factor;
222 return *this;
223}
224
225constexpr inline QPoint &QPoint::operator/=(qreal c)
226{
227 xp = qRound(xp / c);
228 yp = qRound(yp / c);
229 return *this;
230}
231
232#ifndef QT_NO_DEBUG_STREAM
233Q_CORE_EXPORT QDebug operator<<(QDebug, const QPoint &);
234#endif
235
236Q_CORE_EXPORT size_t qHash(QPoint key, size_t seed = 0) noexcept;
237
238
239
240
241class QPointF
242{
243public:
244 constexpr QPointF() noexcept;
245 constexpr QPointF(const QPoint &p) noexcept;
246 constexpr QPointF(qreal xpos, qreal ypos) noexcept;
247
248 constexpr inline qreal manhattanLength() const;
249
250 inline bool isNull() const noexcept;
251
252 constexpr inline qreal x() const noexcept;
253 constexpr inline qreal y() const noexcept;
254 constexpr inline void setX(qreal x) noexcept;
255 constexpr inline void setY(qreal y) noexcept;
256
257 constexpr QPointF transposed() const noexcept { return {yp, xp}; }
258
259 constexpr inline qreal &rx() noexcept;
260 constexpr inline qreal &ry() noexcept;
261
262 constexpr inline QPointF &operator+=(const QPointF &p);
263 constexpr inline QPointF &operator-=(const QPointF &p);
264 constexpr inline QPointF &operator*=(qreal c);
265 constexpr inline QPointF &operator/=(qreal c);
266
267 constexpr static inline qreal dotProduct(const QPointF &p1, const QPointF &p2)
268 {
269 return p1.xp * p2.xp + p1.yp * p2.yp;
270 }
271
272 QT_WARNING_PUSH
273 QT_WARNING_DISABLE_FLOAT_COMPARE
274 friend constexpr inline bool operator==(const QPointF &p1, const QPointF &p2)
275 {
276 return ((!p1.xp || !p2.xp) ? qFuzzyIsNull(p1.xp - p2.xp) : qFuzzyCompare(p1.xp, p2.xp))
277 && ((!p1.yp || !p2.yp) ? qFuzzyIsNull(p1.yp - p2.yp) : qFuzzyCompare(p1.yp, p2.yp));
278 }
279 friend constexpr inline bool operator!=(const QPointF &p1, const QPointF &p2)
280 {
281 return !(p1 == p2);
282 }
283 QT_WARNING_POP
284
285 friend constexpr inline QPointF operator+(const QPointF &p1, const QPointF &p2)
286 { return QPointF(p1.xp + p2.xp, p1.yp + p2.yp); }
287 friend constexpr inline QPointF operator-(const QPointF &p1, const QPointF &p2)
288 { return QPointF(p1.xp - p2.xp, p1.yp - p2.yp); }
289 friend constexpr inline QPointF operator*(const QPointF &p, qreal c)
290 { return QPointF(p.xp * c, p.yp * c); }
291 friend constexpr inline QPointF operator*(qreal c, const QPointF &p)
292 { return QPointF(p.xp * c, p.yp * c); }
293 friend constexpr inline QPointF operator+(const QPointF &p)
294 { return p; }
295 friend constexpr inline QPointF operator-(const QPointF &p)
296 { return QPointF(-p.xp, -p.yp); }
297 friend constexpr inline QPointF operator/(const QPointF &p, qreal divisor)
298 {
299 Q_ASSERT(divisor < 0 || divisor > 0);
300 return QPointF(p.xp / divisor, p.yp / divisor);
301 }
302
303 constexpr QPoint toPoint() const;
304
305#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
306 [[nodiscard]] Q_CORE_EXPORT static QPointF fromCGPoint(CGPoint point) noexcept;
307 [[nodiscard]] Q_CORE_EXPORT CGPoint toCGPoint() const noexcept;
308#endif
309
310private:
311 friend class QTransform;
312
313 qreal xp;
314 qreal yp;
315
316 template <std::size_t I,
317 typename P,
318 std::enable_if_t<(I < 2), bool> = true,
319 std::enable_if_t<std::is_same_v<std::decay_t<P>, QPointF>, bool> = true>
320 friend constexpr decltype(auto) get(P &&p) noexcept
321 {
322 if constexpr (I == 0)
323 return (std::forward<P>(p).xp);
324 else if constexpr (I == 1)
325 return (std::forward<P>(p).yp);
326 }
327};
328
329Q_DECLARE_TYPEINFO(QPointF, Q_PRIMITIVE_TYPE);
330
331size_t qHash(QPointF, size_t seed = 0) = delete;
332
333/*****************************************************************************
334 QPointF stream functions
335 *****************************************************************************/
336#ifndef QT_NO_DATASTREAM
337Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPointF &);
338Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPointF &);
339#endif
340
341/*****************************************************************************
342 QPointF inline functions
343 *****************************************************************************/
344
345constexpr inline QPointF::QPointF() noexcept : xp(0), yp(0) { }
346
347constexpr inline QPointF::QPointF(qreal xpos, qreal ypos) noexcept : xp(xpos), yp(ypos) { }
348
349constexpr inline QPointF::QPointF(const QPoint &p) noexcept : xp(p.x()), yp(p.y()) { }
350
351constexpr inline qreal QPointF::manhattanLength() const
352{
353 return qAbs(x()) + qAbs(y());
354}
355
356inline bool QPointF::isNull() const noexcept
357{
358 return qIsNull(xp) && qIsNull(yp);
359}
360
361constexpr inline qreal QPointF::x() const noexcept
362{
363 return xp;
364}
365
366constexpr inline qreal QPointF::y() const noexcept
367{
368 return yp;
369}
370
371constexpr inline void QPointF::setX(qreal xpos) noexcept
372{
373 xp = xpos;
374}
375
376constexpr inline void QPointF::setY(qreal ypos) noexcept
377{
378 yp = ypos;
379}
380
381constexpr inline qreal &QPointF::rx() noexcept
382{
383 return xp;
384}
385
386constexpr inline qreal &QPointF::ry() noexcept
387{
388 return yp;
389}
390
391constexpr inline QPointF &QPointF::operator+=(const QPointF &p)
392{
393 xp += p.xp;
394 yp += p.yp;
395 return *this;
396}
397
398constexpr inline QPointF &QPointF::operator-=(const QPointF &p)
399{
400 xp -= p.xp;
401 yp -= p.yp;
402 return *this;
403}
404
405constexpr inline QPointF &QPointF::operator*=(qreal c)
406{
407 xp *= c;
408 yp *= c;
409 return *this;
410}
411
412constexpr inline QPointF &QPointF::operator/=(qreal divisor)
413{
414 Q_ASSERT(divisor > 0 || divisor < 0);
415 xp /= divisor;
416 yp /= divisor;
417 return *this;
418}
419
420constexpr inline QPoint QPointF::toPoint() const
421{
422 return QPoint(qRound(xp), qRound(yp));
423}
424
425#ifndef QT_NO_DEBUG_STREAM
426Q_CORE_EXPORT QDebug operator<<(QDebug d, const QPointF &p);
427#endif
428
429QT_END_NAMESPACE
430
431/*****************************************************************************
432 QPoint/QPointF tuple protocol
433 *****************************************************************************/
434
435namespace std {
436 template <>
437 class tuple_size<QT_PREPEND_NAMESPACE(QPoint)> : public integral_constant<size_t, 2> {};
438 template <>
439 class tuple_element<0, QT_PREPEND_NAMESPACE(QPoint)> { public: using type = int; };
440 template <>
441 class tuple_element<1, QT_PREPEND_NAMESPACE(QPoint)> { public: using type = int; };
442
443 template <>
444 class tuple_size<QT_PREPEND_NAMESPACE(QPointF)> : public integral_constant<size_t, 2> {};
445 template <>
446 class tuple_element<0, QT_PREPEND_NAMESPACE(QPointF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
447 template <>
448 class tuple_element<1, QT_PREPEND_NAMESPACE(QPointF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
449}
450
451#endif // QPOINT_H
452