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) |
46 | struct CGPoint; |
47 | #endif |
48 | |
49 | QT_BEGIN_NAMESPACE |
50 | |
51 | class QPoint |
52 | { |
53 | public: |
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 | |
114 | private: |
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 | |
132 | Q_DECLARE_TYPEINFO(QPoint, Q_PRIMITIVE_TYPE); |
133 | |
134 | /***************************************************************************** |
135 | QPoint stream functions |
136 | *****************************************************************************/ |
137 | #ifndef QT_NO_DATASTREAM |
138 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPoint &); |
139 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPoint &); |
140 | #endif |
141 | |
142 | /***************************************************************************** |
143 | QPoint inline functions |
144 | *****************************************************************************/ |
145 | |
146 | constexpr inline QPoint::QPoint() noexcept : xp(0), yp(0) {} |
147 | |
148 | constexpr inline QPoint::QPoint(int xpos, int ypos) noexcept : xp(xpos), yp(ypos) {} |
149 | |
150 | constexpr inline bool QPoint::isNull() const noexcept |
151 | { |
152 | return xp == 0 && yp == 0; |
153 | } |
154 | |
155 | constexpr inline int QPoint::x() const noexcept |
156 | { |
157 | return xp; |
158 | } |
159 | |
160 | constexpr inline int QPoint::y() const noexcept |
161 | { |
162 | return yp; |
163 | } |
164 | |
165 | constexpr inline void QPoint::setX(int xpos) noexcept |
166 | { |
167 | xp = xpos; |
168 | } |
169 | |
170 | constexpr inline void QPoint::setY(int ypos) noexcept |
171 | { |
172 | yp = ypos; |
173 | } |
174 | |
175 | inline int constexpr QPoint::manhattanLength() const |
176 | { |
177 | return qAbs(x()) + qAbs(y()); |
178 | } |
179 | |
180 | constexpr inline int &QPoint::rx() noexcept |
181 | { |
182 | return xp; |
183 | } |
184 | |
185 | constexpr inline int &QPoint::ry() noexcept |
186 | { |
187 | return yp; |
188 | } |
189 | |
190 | constexpr inline QPoint &QPoint::operator+=(const QPoint &p) |
191 | { |
192 | xp += p.xp; |
193 | yp += p.yp; |
194 | return *this; |
195 | } |
196 | |
197 | constexpr inline QPoint &QPoint::operator-=(const QPoint &p) |
198 | { |
199 | xp -= p.xp; |
200 | yp -= p.yp; |
201 | return *this; |
202 | } |
203 | |
204 | constexpr inline QPoint &QPoint::operator*=(float factor) |
205 | { |
206 | xp = qRound(xp * factor); |
207 | yp = qRound(yp * factor); |
208 | return *this; |
209 | } |
210 | |
211 | constexpr inline QPoint &QPoint::operator*=(double factor) |
212 | { |
213 | xp = qRound(xp * factor); |
214 | yp = qRound(yp * factor); |
215 | return *this; |
216 | } |
217 | |
218 | constexpr inline QPoint &QPoint::operator*=(int factor) |
219 | { |
220 | xp = xp * factor; |
221 | yp = yp * factor; |
222 | return *this; |
223 | } |
224 | |
225 | constexpr 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 |
233 | Q_CORE_EXPORT QDebug operator<<(QDebug, const QPoint &); |
234 | #endif |
235 | |
236 | Q_CORE_EXPORT size_t qHash(QPoint key, size_t seed = 0) noexcept; |
237 | |
238 | |
239 | |
240 | |
241 | class QPointF |
242 | { |
243 | public: |
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 | |
310 | private: |
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 | |
329 | Q_DECLARE_TYPEINFO(QPointF, Q_PRIMITIVE_TYPE); |
330 | |
331 | size_t qHash(QPointF, size_t seed = 0) = delete; |
332 | |
333 | /***************************************************************************** |
334 | QPointF stream functions |
335 | *****************************************************************************/ |
336 | #ifndef QT_NO_DATASTREAM |
337 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPointF &); |
338 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPointF &); |
339 | #endif |
340 | |
341 | /***************************************************************************** |
342 | QPointF inline functions |
343 | *****************************************************************************/ |
344 | |
345 | constexpr inline QPointF::QPointF() noexcept : xp(0), yp(0) { } |
346 | |
347 | constexpr inline QPointF::QPointF(qreal xpos, qreal ypos) noexcept : xp(xpos), yp(ypos) { } |
348 | |
349 | constexpr inline QPointF::QPointF(const QPoint &p) noexcept : xp(p.x()), yp(p.y()) { } |
350 | |
351 | constexpr inline qreal QPointF::manhattanLength() const |
352 | { |
353 | return qAbs(x()) + qAbs(y()); |
354 | } |
355 | |
356 | inline bool QPointF::isNull() const noexcept |
357 | { |
358 | return qIsNull(xp) && qIsNull(yp); |
359 | } |
360 | |
361 | constexpr inline qreal QPointF::x() const noexcept |
362 | { |
363 | return xp; |
364 | } |
365 | |
366 | constexpr inline qreal QPointF::y() const noexcept |
367 | { |
368 | return yp; |
369 | } |
370 | |
371 | constexpr inline void QPointF::setX(qreal xpos) noexcept |
372 | { |
373 | xp = xpos; |
374 | } |
375 | |
376 | constexpr inline void QPointF::setY(qreal ypos) noexcept |
377 | { |
378 | yp = ypos; |
379 | } |
380 | |
381 | constexpr inline qreal &QPointF::rx() noexcept |
382 | { |
383 | return xp; |
384 | } |
385 | |
386 | constexpr inline qreal &QPointF::ry() noexcept |
387 | { |
388 | return yp; |
389 | } |
390 | |
391 | constexpr inline QPointF &QPointF::operator+=(const QPointF &p) |
392 | { |
393 | xp += p.xp; |
394 | yp += p.yp; |
395 | return *this; |
396 | } |
397 | |
398 | constexpr inline QPointF &QPointF::operator-=(const QPointF &p) |
399 | { |
400 | xp -= p.xp; |
401 | yp -= p.yp; |
402 | return *this; |
403 | } |
404 | |
405 | constexpr inline QPointF &QPointF::operator*=(qreal c) |
406 | { |
407 | xp *= c; |
408 | yp *= c; |
409 | return *this; |
410 | } |
411 | |
412 | constexpr 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 | |
420 | constexpr inline QPoint QPointF::toPoint() const |
421 | { |
422 | return QPoint(qRound(xp), qRound(yp)); |
423 | } |
424 | |
425 | #ifndef QT_NO_DEBUG_STREAM |
426 | Q_CORE_EXPORT QDebug operator<<(QDebug d, const QPointF &p); |
427 | #endif |
428 | |
429 | QT_END_NAMESPACE |
430 | |
431 | /***************************************************************************** |
432 | QPoint/QPointF tuple protocol |
433 | *****************************************************************************/ |
434 | |
435 | namespace 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 | |