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