1// Copyright (C) 2022 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
4#include "qsize.h"
5#include "qdatastream.h"
6
7#include <private/qdebug_p.h>
8
9QT_BEGIN_NAMESPACE
10
11/*!
12 \class QSize
13 \inmodule QtCore
14 \ingroup painting
15
16 \brief The QSize class defines the size of a two-dimensional
17 object using integer point precision.
18
19 A size is specified by a width() and a height(). It can be set in
20 the constructor and changed using the setWidth(), setHeight(), or
21 scale() functions, or using arithmetic operators. A size can also
22 be manipulated directly by retrieving references to the width and
23 height using the rwidth() and rheight() functions. Finally, the
24 width and height can be swapped using the transpose() function.
25
26 The isValid() function determines if a size is valid (a valid size
27 has both width and height greater than or equal to zero). The isEmpty()
28 function returns \c true if either of the width and height is less
29 than, or equal to, zero, while the isNull() function returns \c true
30 only if both the width and the height is zero.
31
32 Use the expandedTo() function to retrieve a size which holds the
33 maximum height and width of \e this size and a given
34 size. Similarly, the boundedTo() function returns a size which
35 holds the minimum height and width of \e this size and a given
36 size.
37
38 QSize objects can be streamed as well as compared.
39
40 \sa QSizeF, QPoint, QRect
41*/
42
43
44/*****************************************************************************
45 QSize member functions
46 *****************************************************************************/
47
48/*!
49 \fn QSize::QSize()
50
51 Constructs a size with an invalid width and height (i.e., isValid()
52 returns \c false).
53
54 \sa isValid()
55*/
56
57/*!
58 \fn QSize::QSize(int width, int height)
59
60 Constructs a size with the given \a width and \a height.
61
62 \sa setWidth(), setHeight()
63*/
64
65/*!
66 \fn bool QSize::isNull() const
67
68 Returns \c true if both the width and height is 0; otherwise returns
69 false.
70
71 \sa isValid(), isEmpty()
72*/
73
74/*!
75 \fn bool QSize::isEmpty() const
76
77 Returns \c true if either of the width and height is less than or
78 equal to 0; otherwise returns \c false.
79
80 \sa isNull(), isValid()
81*/
82
83/*!
84 \fn bool QSize::isValid() const
85
86 Returns \c true if both the width and height is equal to or greater
87 than 0; otherwise returns \c false.
88
89 \sa isNull(), isEmpty()
90*/
91
92/*!
93 \fn int QSize::width() const
94
95 Returns the width.
96
97 \sa height(), setWidth()
98*/
99
100/*!
101 \fn int QSize::height() const
102
103 Returns the height.
104
105 \sa width(), setHeight()
106*/
107
108/*!
109 \fn void QSize::setWidth(int width)
110
111 Sets the width to the given \a width.
112
113 \sa rwidth(), width(), setHeight()
114*/
115
116/*!
117 \fn void QSize::setHeight(int height)
118
119 Sets the height to the given \a height.
120
121 \sa rheight(), height(), setWidth()
122*/
123
124/*!
125 Swaps the width and height values.
126
127 \sa setWidth(), setHeight(), transposed()
128*/
129
130void QSize::transpose() noexcept
131{
132 qSwap(value1&: wd, value2&: ht);
133}
134
135/*!
136 \fn QSize QSize::transposed() const
137 \since 5.0
138
139 Returns a QSize with width and height swapped.
140
141 \sa transpose()
142*/
143
144/*!
145 \fn void QSize::scale(int width, int height, Qt::AspectRatioMode mode)
146
147 Scales the size to a rectangle with the given \a width and \a
148 height, according to the specified \a mode:
149
150 \list
151 \li If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
152 \li If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
153 as large as possible inside (\a width, \a height), preserving the aspect ratio.
154 \li If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
155 as small as possible outside (\a width, \a height), preserving the aspect ratio.
156 \endlist
157
158 Example:
159 \snippet code/src_corelib_tools_qsize.cpp 0
160
161 \sa setWidth(), setHeight(), scaled()
162*/
163
164/*!
165 \fn void QSize::scale(const QSize &size, Qt::AspectRatioMode mode)
166 \overload
167
168 Scales the size to a rectangle with the given \a size, according to
169 the specified \a mode.
170*/
171
172/*!
173 \fn QSize QSize::scaled(int width, int height, Qt::AspectRatioMode mode) const
174 \since 5.0
175
176 Return a size scaled to a rectangle with the given \a width and \a
177 height, according to the specified \a mode.
178
179 \sa scale()
180*/
181
182/*!
183 \overload
184 \since 5.0
185
186 Return a size scaled to a rectangle with the given size \a s,
187 according to the specified \a mode.
188*/
189QSize QSize::scaled(const QSize &s, Qt::AspectRatioMode mode) const noexcept
190{
191 if (mode == Qt::IgnoreAspectRatio || wd == 0 || ht == 0) {
192 return s;
193 } else {
194 bool useHeight;
195 qint64 rw = qint64(s.ht) * qint64(wd) / qint64(ht);
196
197 if (mode == Qt::KeepAspectRatio) {
198 useHeight = (rw <= s.wd);
199 } else { // mode == Qt::KeepAspectRatioByExpanding
200 useHeight = (rw >= s.wd);
201 }
202
203 if (useHeight) {
204 return QSize(rw, s.ht);
205 } else {
206 return QSize(s.wd,
207 qint32(qint64(s.wd) * qint64(ht) / qint64(wd)));
208 }
209 }
210}
211
212/*!
213 \fn int &QSize::rwidth()
214
215 Returns a reference to the width.
216
217 Using a reference makes it possible to manipulate the width
218 directly. For example:
219
220 \snippet code/src_corelib_tools_qsize.cpp 1
221
222 \sa rheight(), setWidth()
223*/
224
225/*!
226 \fn int &QSize::rheight()
227
228 Returns a reference to the height.
229
230 Using a reference makes it possible to manipulate the height
231 directly. For example:
232
233 \snippet code/src_corelib_tools_qsize.cpp 2
234
235 \sa rwidth(), setHeight()
236*/
237
238/*!
239 \fn QSize &QSize::operator+=(const QSize &size)
240
241 Adds the given \a size to \e this size, and returns a reference to
242 this size. For example:
243
244 \snippet code/src_corelib_tools_qsize.cpp 3
245*/
246
247/*!
248 \fn QSize &QSize::operator-=(const QSize &size)
249
250 Subtracts the given \a size from \e this size, and returns a
251 reference to this size. For example:
252
253 \snippet code/src_corelib_tools_qsize.cpp 4
254*/
255
256/*!
257 \fn QSize &QSize::operator*=(qreal factor)
258 \overload
259
260 Multiplies both the width and height by the given \a factor, and
261 returns a reference to the size.
262
263 Note that the result is rounded to the nearest integer.
264
265 \sa scale()
266*/
267
268/*!
269 \fn bool QSize::operator==(const QSize &s1, const QSize &s2)
270
271 Returns \c true if \a s1 and \a s2 are equal; otherwise returns \c false.
272*/
273
274/*!
275 \fn bool QSize::operator!=(const QSize &s1, const QSize &s2)
276
277 Returns \c true if \a s1 and \a s2 are different; otherwise returns \c false.
278*/
279
280/*!
281 \fn QSize QSize::operator+(const QSize &s1, const QSize &s2)
282
283 Returns the sum of \a s1 and \a s2; each component is added separately.
284*/
285
286/*!
287 \fn QSize QSize::operator-(const QSize &s1, const QSize &s2)
288
289 Returns \a s2 subtracted from \a s1; each component is subtracted
290 separately.
291*/
292
293/*!
294 \fn QSize QSize::operator*(const QSize &size, qreal factor)
295
296 Multiplies the given \a size by the given \a factor, and returns
297 the result rounded to the nearest integer.
298
299 \sa QSize::scale()
300*/
301
302/*!
303 \fn QSize QSize::operator*(qreal factor, const QSize &size)
304 \overload
305
306 Multiplies the given \a size by the given \a factor, and returns
307 the result rounded to the nearest integer.
308*/
309
310/*!
311 \fn QSize &QSize::operator/=(qreal divisor)
312 \overload
313
314 Divides both the width and height by the given \a divisor, and
315 returns a reference to the size.
316
317 Note that the result is rounded to the nearest integer.
318
319 \sa QSize::scale()
320*/
321
322/*!
323 \fn QSize QSize::operator/(const QSize &size, qreal divisor)
324 \overload
325
326 Divides the given \a size by the given \a divisor, and returns the
327 result rounded to the nearest integer.
328
329 \sa QSize::scale()
330*/
331
332/*!
333 \fn QSize QSize::expandedTo(const QSize & otherSize) const
334
335 Returns a size holding the maximum width and height of this size
336 and the given \a otherSize.
337
338 \sa boundedTo(), scale()
339*/
340
341/*!
342 \fn QSize QSize::boundedTo(const QSize & otherSize) const
343
344 Returns a size holding the minimum width and height of this size
345 and the given \a otherSize.
346
347 \sa expandedTo(), scale()
348*/
349
350/*!
351 \fn QSize QSize::grownBy(QMargins margins) const
352 \fn QSizeF QSizeF::grownBy(QMarginsF margins) const
353 \since 5.14
354
355 Returns the size that results from growing this size by \a margins.
356
357 \sa shrunkBy()
358*/
359
360/*!
361 \fn QSize QSize::shrunkBy(QMargins margins) const
362 \fn QSizeF QSizeF::shrunkBy(QMarginsF margins) const
363 \since 5.14
364
365 Returns the size that results from shrinking this size by \a margins.
366
367 \sa grownBy()
368*/
369
370/*!
371 \fn QSize::toSizeF() const
372 \since 6.4
373
374 Returns this size as a size with floating point accuracy.
375
376 \sa QSizeF::toSize()
377*/
378
379/*****************************************************************************
380 QSize stream functions
381 *****************************************************************************/
382#ifndef QT_NO_DATASTREAM
383/*!
384 \fn QDataStream &operator<<(QDataStream &stream, const QSize &size)
385 \relates QSize
386
387 Writes the given \a size to the given \a stream, and returns a
388 reference to the stream.
389
390 \sa {Serializing Qt Data Types}
391*/
392
393QDataStream &operator<<(QDataStream &s, const QSize &sz)
394{
395 if (s.version() == 1)
396 s << (qint16)sz.width() << (qint16)sz.height();
397 else
398 s << (qint32)sz.width() << (qint32)sz.height();
399 return s;
400}
401
402/*!
403 \fn QDataStream &operator>>(QDataStream &stream, QSize &size)
404 \relates QSize
405
406 Reads a size from the given \a stream into the given \a size, and
407 returns a reference to the stream.
408
409 \sa {Serializing Qt Data Types}
410*/
411
412QDataStream &operator>>(QDataStream &s, QSize &sz)
413{
414 if (s.version() == 1) {
415 qint16 w, h;
416 s >> w; sz.rwidth() = w;
417 s >> h; sz.rheight() = h;
418 }
419 else {
420 qint32 w, h;
421 s >> w; sz.rwidth() = w;
422 s >> h; sz.rheight() = h;
423 }
424 return s;
425}
426#endif // QT_NO_DATASTREAM
427
428#ifndef QT_NO_DEBUG_STREAM
429QDebug operator<<(QDebug dbg, const QSize &s)
430{
431 QDebugStateSaver saver(dbg);
432 dbg.nospace();
433 dbg << "QSize(";
434 QtDebugUtils::formatQSize(debug&: dbg, size: s);
435 dbg << ')';
436 return dbg;
437}
438#endif
439
440
441
442/*!
443 \class QSizeF
444 \inmodule QtCore
445 \brief The QSizeF class defines the size of a two-dimensional object
446 using floating point precision.
447
448 \ingroup painting
449
450 A size is specified by a width() and a height(). It can be set in
451 the constructor and changed using the setWidth(), setHeight(), or
452 scale() functions, or using arithmetic operators. A size can also
453 be manipulated directly by retrieving references to the width and
454 height using the rwidth() and rheight() functions. Finally, the
455 width and height can be swapped using the transpose() function.
456
457 The isValid() function determines if a size is valid. A valid size
458 has both width and height greater than or equal to zero. The
459 isEmpty() function returns \c true if either of the width and height
460 is \e less than (or equal to) zero, while the isNull() function
461 returns \c true only if both the width and the height is zero.
462
463 Use the expandedTo() function to retrieve a size which holds the
464 maximum height and width of this size and a given
465 size. Similarly, the boundedTo() function returns a size which
466 holds the minimum height and width of this size and a given size.
467
468 The QSizeF class also provides the toSize() function returning a
469 QSize copy of this size, constructed by rounding the width and
470 height to the nearest integers.
471
472 QSizeF objects can be streamed as well as compared.
473
474 \sa QSize, QPointF, QRectF
475*/
476
477
478/*****************************************************************************
479 QSizeF member functions
480 *****************************************************************************/
481
482/*!
483 \fn QSizeF::QSizeF()
484
485 Constructs an invalid size.
486
487 \sa isValid()
488*/
489
490/*!
491 \fn QSizeF::QSizeF(const QSize &size)
492
493 Constructs a size with floating point accuracy from the given \a
494 size.
495
496 \sa toSize(), QSize::toSizeF()
497*/
498
499/*!
500 \fn QSizeF::QSizeF(qreal width, qreal height)
501
502 Constructs a size with the given finite \a width and \a height.
503*/
504
505/*!
506 \fn bool QSizeF::isNull() const
507
508 Returns \c true if both the width and height are 0.0 (ignoring the sign);
509 otherwise returns \c false.
510
511 \sa isValid(), isEmpty()
512*/
513
514/*!
515 \fn bool QSizeF::isEmpty() const
516
517 Returns \c true if either of the width and height is less than or
518 equal to 0; otherwise returns \c false.
519
520 \sa isNull(), isValid()
521*/
522
523/*!
524 \fn bool QSizeF::isValid() const
525
526 Returns \c true if both the width and height are equal to or greater
527 than 0; otherwise returns \c false.
528
529 \sa isNull(), isEmpty()
530*/
531
532/*!
533 \fn int QSizeF::width() const
534
535 Returns the width.
536
537 \sa height(), setWidth()
538*/
539
540/*!
541 \fn int QSizeF::height() const
542
543 Returns the height.
544
545 \sa width(), setHeight()
546*/
547
548/*!
549 \fn void QSizeF::setWidth(qreal width)
550
551 Sets the width to the given finite \a width.
552
553 \sa width(), rwidth(), setHeight()
554*/
555
556/*!
557 \fn void QSizeF::setHeight(qreal height)
558
559 Sets the height to the given finite \a height.
560
561 \sa height(), rheight(), setWidth()
562*/
563
564/*!
565 \fn QSize QSizeF::toSize() const
566
567 Returns an integer based copy of this size.
568
569 Note that the coordinates in the returned size will be rounded to
570 the nearest integer.
571
572 \sa QSizeF(), QSize::toSizeF()
573*/
574
575/*!
576 Swaps the width and height values.
577
578 \sa setWidth(), setHeight(), transposed()
579*/
580
581void QSizeF::transpose() noexcept
582{
583 qSwap(value1&: wd, value2&: ht);
584}
585
586/*!
587 \fn QSizeF QSizeF::transposed() const
588 \since 5.0
589
590 Returns the size with width and height values swapped.
591
592 \sa transpose()
593*/
594
595/*!
596 \fn void QSizeF::scale(qreal width, qreal height, Qt::AspectRatioMode mode)
597
598 Scales the size to a rectangle with the given \a width and \a
599 height, according to the specified \a mode.
600
601 \list
602 \li If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
603 \li If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
604 as large as possible inside (\a width, \a height), preserving the aspect ratio.
605 \li If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
606 as small as possible outside (\a width, \a height), preserving the aspect ratio.
607 \endlist
608
609 Example:
610 \snippet code/src_corelib_tools_qsize.cpp 5
611
612 \sa setWidth(), setHeight(), scaled()
613*/
614
615/*!
616 \fn void QSizeF::scale(const QSizeF &size, Qt::AspectRatioMode mode)
617 \overload
618
619 Scales the size to a rectangle with the given \a size, according to
620 the specified \a mode.
621*/
622
623/*!
624 \fn QSizeF QSizeF::scaled(qreal width, qreal height, Qt::AspectRatioMode mode) const
625 \since 5.0
626
627 Returns a size scaled to a rectangle with the given \a width and
628 \a height, according to the specified \a mode.
629
630 \sa scale()
631*/
632
633/*!
634 \overload
635 \since 5.0
636
637 Returns a size scaled to a rectangle with the given size \a s,
638 according to the specified \a mode.
639*/
640QSizeF QSizeF::scaled(const QSizeF &s, Qt::AspectRatioMode mode) const noexcept
641{
642 if (mode == Qt::IgnoreAspectRatio || qIsNull(d: wd) || qIsNull(d: ht)) {
643 return s;
644 } else {
645 bool useHeight;
646 qreal rw = s.ht * wd / ht;
647
648 if (mode == Qt::KeepAspectRatio) {
649 useHeight = (rw <= s.wd);
650 } else { // mode == Qt::KeepAspectRatioByExpanding
651 useHeight = (rw >= s.wd);
652 }
653
654 if (useHeight) {
655 return QSizeF(rw, s.ht);
656 } else {
657 return QSizeF(s.wd, s.wd * ht / wd);
658 }
659 }
660}
661
662/*!
663 \fn int &QSizeF::rwidth()
664
665 Returns a reference to the width.
666
667 Using a reference makes it possible to manipulate the width
668 directly. For example:
669
670 \snippet code/src_corelib_tools_qsize.cpp 6
671
672 \sa rheight(), setWidth()
673*/
674
675/*!
676 \fn int &QSizeF::rheight()
677
678 Returns a reference to the height.
679
680 Using a reference makes it possible to manipulate the height
681 directly. For example:
682
683 \snippet code/src_corelib_tools_qsize.cpp 7
684
685 \sa rwidth(), setHeight()
686*/
687
688/*!
689 \fn QSizeF &QSizeF::operator+=(const QSizeF &size)
690
691 Adds the given \a size to this size and returns a reference to
692 this size. For example:
693
694 \snippet code/src_corelib_tools_qsize.cpp 8
695*/
696
697/*!
698 \fn QSizeF &QSizeF::operator-=(const QSizeF &size)
699
700 Subtracts the given \a size from this size and returns a reference
701 to this size. For example:
702
703 \snippet code/src_corelib_tools_qsize.cpp 9
704*/
705
706/*!
707 \fn QSizeF &QSizeF::operator*=(qreal factor)
708 \overload
709
710 Multiplies both the width and height by the given finite \a factor and
711 returns a reference to the size.
712
713 \sa scale()
714*/
715
716/*!
717 \fn bool QSizeF::operator==(const QSizeF &s1, const QSizeF &s2)
718
719 Returns \c true if \a s1 and \a s2 are approximately equal; otherwise
720 returns false.
721
722 \warning This function does not check for strict equality; instead,
723 it uses a fuzzy comparison to compare the sizes' extents.
724
725 \sa qFuzzyCompare
726*/
727
728/*!
729 \fn bool QSizeF::operator!=(const QSizeF &s1, const QSizeF &s2)
730
731 Returns \c true if \a s1 and \a s2 are sufficiently different; otherwise
732 returns \c false.
733
734 \warning This function does not check for strict inequality; instead,
735 it uses a fuzzy comparison to compare the sizes' extents.
736*/
737
738/*!
739 \fn QSizeF QSizeF::operator+(const QSizeF &s1, const QSizeF &s2)
740
741 Returns the sum of \a s1 and \a s2; each component is added separately.
742*/
743
744/*!
745 \fn QSizeF QSizeF::operator-(const QSizeF &s1, const QSizeF &s2)
746
747 Returns \a s2 subtracted from \a s1; each component is subtracted
748 separately.
749*/
750
751/*!
752 \fn QSizeF QSizeF::operator*(const QSizeF &size, qreal factor)
753
754 \overload
755
756 Multiplies the given \a size by the given finite \a factor and returns
757 the result.
758
759 \sa QSizeF::scale()
760*/
761
762/*!
763 \fn QSizeF QSizeF::operator*(qreal factor, const QSizeF &size)
764
765 \overload
766
767 Multiplies the given \a size by the given finite \a factor and returns
768 the result.
769*/
770
771/*!
772 \fn QSizeF &QSizeF::operator/=(qreal divisor)
773
774 \overload
775
776 Divides both the width and height by the given \a divisor and returns a
777 reference to the size. The \a divisor must not be either zero or NaN.
778
779 \sa scale()
780*/
781
782/*!
783 \fn QSizeF QSizeF::operator/(const QSizeF &size, qreal divisor)
784
785 \overload
786
787 Divides the given \a size by the given \a divisor and returns the
788 result. The \a divisor must not be either zero or NaN.
789
790 \sa QSizeF::scale()
791*/
792
793/*!
794 \fn QSizeF QSizeF::expandedTo(const QSizeF & otherSize) const
795
796 Returns a size holding the maximum width and height of this size
797 and the given \a otherSize.
798
799 \sa boundedTo(), scale()
800*/
801
802/*!
803 \fn QSizeF QSizeF::boundedTo(const QSizeF & otherSize) const
804
805 Returns a size holding the minimum width and height of this size
806 and the given \a otherSize.
807
808 \sa expandedTo(), scale()
809*/
810
811
812
813/*****************************************************************************
814 QSizeF stream functions
815 *****************************************************************************/
816#ifndef QT_NO_DATASTREAM
817/*!
818 \fn QDataStream &operator<<(QDataStream &stream, const QSizeF &size)
819 \relates QSizeF
820
821 Writes the given \a size to the given \a stream and returns a
822 reference to the stream.
823
824 \sa {Serializing Qt Data Types}
825*/
826
827QDataStream &operator<<(QDataStream &s, const QSizeF &sz)
828{
829 s << double(sz.width()) << double(sz.height());
830 return s;
831}
832
833/*!
834 \fn QDataStream &operator>>(QDataStream &stream, QSizeF &size)
835 \relates QSizeF
836
837 Reads a size from the given \a stream into the given \a size and
838 returns a reference to the stream.
839
840 \sa {Serializing Qt Data Types}
841*/
842
843QDataStream &operator>>(QDataStream &s, QSizeF &sz)
844{
845 double w, h;
846 s >> w;
847 s >> h;
848 sz.setWidth(qreal(w));
849 sz.setHeight(qreal(h));
850 return s;
851}
852#endif // QT_NO_DATASTREAM
853
854#ifndef QT_NO_DEBUG_STREAM
855QDebug operator<<(QDebug dbg, const QSizeF &s)
856{
857 QDebugStateSaver saver(dbg);
858 dbg.nospace();
859 dbg << "QSizeF(";
860 QtDebugUtils::formatQSize(debug&: dbg, size: s);
861 dbg << ')';
862 return dbg;
863}
864#endif
865
866QT_END_NAMESPACE
867

source code of qtbase/src/corelib/tools/qsize.cpp