QtBase  v6.3.1
qpagelayout.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 John Layt <jlayt@kde.org>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui 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 
41 #include "qpagelayout.h"
42 
43 #include <QtCore/qpoint.h>
44 #include <QtCore/qrect.h>
45 #include <QtCore/qsize.h>
46 
47 #include <qdebug.h>
48 
50 
51 // Multiplier for converting units to points.
53 {
54  switch (unit) {
56  return 2.83464566929;
57  case QPageLayout::Point:
58  return 1.0;
59  case QPageLayout::Inch:
60  return 72.0;
61  case QPageLayout::Pica:
62  return 12;
63  case QPageLayout::Didot:
64  return 1.065826771;
66  return 12.789921252;
67  }
68  return 1.0;
69 }
70 
71 // Multiplier for converting pixels to points.
72 extern qreal qt_pixelMultiplier(int resolution);
73 
75 {
76  // If the size have the same units, or are all 0, then don't need to convert
77  if (fromUnits == toUnits || xy.isNull())
78  return xy;
79 
80  // If converting to points then convert and round to 0 decimal places
81  if (toUnits == QPageLayout::Point) {
82  const qreal multiplier = qt_pointMultiplier(fromUnits);
83  return QPointF(qRound(xy.x() * multiplier),
84  qRound(xy.y() * multiplier));
85  }
86 
87  // If converting to other units, need to convert to unrounded points first
88  QPointF pointXy = (fromUnits == QPageLayout::Point) ? xy : xy * qt_pointMultiplier(fromUnits);
89 
90  // Then convert from points to required units rounded to 2 decimal places
91  const qreal multiplier = qt_pointMultiplier(toUnits);
92  return QPointF(qRound(pointXy.x() * 100 / multiplier) / 100.0,
93  qRound(pointXy.y() * 100 / multiplier) / 100.0);
94 }
95 
96 Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
97 {
98  // If the margins have the same units, or are all 0, then don't need to convert
99  if (fromUnits == toUnits || margins.isNull())
100  return margins;
101 
102  // If converting to points then convert and round to 0 decimal places
103  if (toUnits == QPageLayout::Point) {
104  const qreal multiplier = qt_pointMultiplier(fromUnits);
105  return QMarginsF(qRound(margins.left() * multiplier),
106  qRound(margins.top() * multiplier),
107  qRound(margins.right() * multiplier),
108  qRound(margins.bottom() * multiplier));
109  }
110 
111  // If converting to other units, need to convert to unrounded points first
112  QMarginsF pointMargins = fromUnits == QPageLayout::Point ? margins : margins * qt_pointMultiplier(fromUnits);
113 
114  // Then convert from points to required units rounded to 2 decimal places
115  const qreal multiplier = qt_pointMultiplier(toUnits);
116  return QMarginsF(qRound(pointMargins.left() * 100 / multiplier) / 100.0,
117  qRound(pointMargins.top() * 100 / multiplier) / 100.0,
118  qRound(pointMargins.right() * 100 / multiplier) / 100.0,
119  qRound(pointMargins.bottom() * 100 / multiplier) / 100.0);
120 }
121 
123 {
124 public:
125 
126  QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation,
128  const QMarginsF &minMargins);
130 
131  bool operator==(const QPageLayoutPrivate &other) const;
132  bool isEquivalentTo(const QPageLayoutPrivate &other) const;
133 
134  bool isValid() const;
135 
136  void clampMargins(const QMarginsF &margins);
137 
139  QMargins marginsPoints() const;
140  QMargins marginsPixels(int resolution) const;
141 
142  void setDefaultMargins(const QMarginsF &minMargins);
143 
144  QSizeF paintSize() const;
145 
146  QRectF fullRect() const;
148  QRect fullRectPoints() const;
149  QRect fullRectPixels(int resolution) const;
150 
151  QRectF paintRect() const;
152 
153 private:
154  friend class QPageLayout;
155 
156  QSizeF fullSizeUnits(QPageLayout::Unit units) const;
157 
158  QPageSize m_pageSize;
159  QPageLayout::Orientation m_orientation;
160  QPageLayout::Mode m_mode;
161  QPageLayout::Unit m_units;
162  QSizeF m_fullSize;
163  QMarginsF m_margins;
164  QMarginsF m_minMargins;
165  QMarginsF m_maxMargins;
166 };
167 
170  const QMarginsF &minMargins)
171  : m_pageSize(pageSize),
172  m_orientation(orientation),
173  m_mode(QPageLayout::StandardMode),
174  m_units(units),
175  m_margins(margins)
176 {
177  m_fullSize = fullSizeUnits(m_units);
178  setDefaultMargins(minMargins);
179 }
180 
182 {
183 }
184 
186 {
187  return m_pageSize == other.m_pageSize
188  && m_orientation == other.m_orientation
189  && m_units == other.m_units
190  && m_margins == other.m_margins
191  && m_minMargins == other.m_minMargins
192  && m_maxMargins == other.m_maxMargins;
193 }
194 
196 {
197  return m_pageSize.isEquivalentTo(other.m_pageSize)
198  && m_orientation == other.m_orientation
199  && qt_convertMargins(m_margins, m_units, QPageLayout::Point)
200  == qt_convertMargins(other.m_margins, other.m_units, QPageLayout::Point);
201 }
202 
204 {
205  return m_pageSize.isValid();
206 }
207 
209 {
210  m_margins = QMarginsF(qBound(m_minMargins.left(), margins.left(), m_maxMargins.left()),
211  qBound(m_minMargins.top(), margins.top(), m_maxMargins.top()),
212  qBound(m_minMargins.right(), margins.right(), m_maxMargins.right()),
213  qBound(m_minMargins.bottom(), margins.bottom(), m_maxMargins.bottom()));
214 }
215 
217 {
218  return qt_convertMargins(m_margins, m_units, units);
219 }
220 
222 {
223  return qt_convertMargins(m_margins, m_units, QPageLayout::Point).toMargins();
224 }
225 
227 {
228  return marginsPoints() / qt_pixelMultiplier(resolution);
229 }
230 
232 {
233  m_minMargins = minMargins;
234  m_maxMargins = QMarginsF(qMax(m_fullSize.width() - m_minMargins.right(), qreal(0)),
235  qMax(m_fullSize.height() - m_minMargins.bottom(), qreal(0)),
236  qMax(m_fullSize.width() - m_minMargins.left(), qreal(0)),
237  qMax(m_fullSize.height() - m_minMargins.top(), qreal(0)));
238  if (m_mode == QPageLayout::StandardMode)
239  clampMargins(m_margins);
240 }
241 
242 QSizeF QPageLayoutPrivate::fullSizeUnits(QPageLayout::Unit units) const
243 {
244  QSizeF fullPageSize = m_pageSize.size(QPageSize::Unit(units));
245  return m_orientation == QPageLayout::Landscape ? fullPageSize.transposed() : fullPageSize;
246 }
247 
249 {
250  return QRectF(QPointF(0, 0), m_fullSize);
251 }
252 
254 {
255  return units == m_units ? fullRect() : QRectF(QPointF(0, 0), fullSizeUnits(units));
256 }
257 
259 {
260  if (m_orientation == QPageLayout::Landscape)
261  return QRect(QPoint(0, 0), m_pageSize.sizePoints().transposed());
262  else
263  return QRect(QPoint(0, 0), m_pageSize.sizePoints());
264 }
265 
267 {
268  if (m_orientation == QPageLayout::Landscape)
269  return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution).transposed());
270  else
271  return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution));
272 }
273 
275 {
276  return m_mode == QPageLayout::FullPageMode ? fullRect() : fullRect() - m_margins;
277 }
278 
279 
353 {
354 }
355 
370  const QMarginsF &margins, Unit units,
371  const QMarginsF &minMargins)
372  : d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins))
373 {
374 }
375 
381  : d(other.d)
382 {
383 }
384 
390 {
391 }
392 
398 {
399  d = other.d;
400  return *this;
401 }
402 
446 bool QPageLayout::equals(const QPageLayout &other) const
447 {
448  return d == other.d || *d == *other.d;
449 }
450 
451 
458 {
459  return d && other.d && d->isEquivalentTo(*other.d);
460 }
461 
467 {
468  return d->isValid();
469 }
470 
476 {
477  d.detach();
478  d->m_mode = mode;
479 }
480 
486 {
487  return d->m_mode;
488 }
489 
502 void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins)
503 {
504  if (!pageSize.isValid())
505  return;
506  d.detach();
507  d->m_pageSize = pageSize;
508  d->m_fullSize = d->fullSizeUnits(d->m_units);
509  d->setDefaultMargins(minMargins);
510 }
511 
521 {
522  return d->m_pageSize;
523 }
524 
533 {
534  if (orientation != d->m_orientation) {
535  d.detach();
536  d->m_orientation = orientation;
537  d->m_fullSize = d->fullSizeUnits(d->m_units);
538  // Adust the max margins to reflect change in max page size
539  const qreal change = d->m_fullSize.width() - d->m_fullSize.height();
540  d->m_maxMargins.setLeft(d->m_maxMargins.left() + change);
541  d->m_maxMargins.setRight(d->m_maxMargins.right() + change);
542  d->m_maxMargins.setTop(d->m_maxMargins.top() - change);
543  d->m_maxMargins.setBottom(d->m_maxMargins.bottom() - change);
544  }
545 }
546 
552 {
553  return d->m_orientation;
554 }
555 
561 {
562  if (units != d->m_units) {
563  d.detach();
564  d->m_margins = qt_convertMargins(d->m_margins, d->m_units, units);
565  d->m_minMargins = qt_convertMargins(d->m_minMargins, d->m_units, units);
566  d->m_maxMargins = qt_convertMargins(d->m_maxMargins, d->m_units, units);
567  d->m_units = units;
568  d->m_fullSize = d->fullSizeUnits(d->m_units);
569  }
570 }
571 
577 {
578  return d->m_units;
579 }
580 
598 {
599  if (d->m_mode == FullPageMode) {
600  d.detach();
601  d->m_margins = margins;
602  return true;
603  } else if (margins.left() >= d->m_minMargins.left()
604  && margins.right() >= d->m_minMargins.right()
605  && margins.top() >= d->m_minMargins.top()
606  && margins.bottom() >= d->m_minMargins.bottom()
607  && margins.left() <= d->m_maxMargins.left()
608  && margins.right() <= d->m_maxMargins.right()
609  && margins.top() <= d->m_maxMargins.top()
610  && margins.bottom() <= d->m_maxMargins.bottom()) {
611  d.detach();
612  d->m_margins = margins;
613  return true;
614  }
615  return false;
616 }
617 
635 {
636  if (d->m_mode == FullPageMode
637  || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) {
638  d.detach();
639  d->m_margins.setLeft(leftMargin);
640  return true;
641  }
642  return false;
643 }
644 
662 {
663  if (d->m_mode == FullPageMode
664  || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) {
665  d.detach();
666  d->m_margins.setRight(rightMargin);
667  return true;
668  }
669  return false;
670 }
671 
689 {
690  if (d->m_mode == FullPageMode
691  || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) {
692  d.detach();
693  d->m_margins.setTop(topMargin);
694  return true;
695  }
696  return false;
697 }
698 
716 {
717  if (d->m_mode == FullPageMode
718  || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) {
719  d.detach();
720  d->m_margins.setBottom(bottomMargin);
721  return true;
722  }
723  return false;
724 }
725 
733 {
734  return d->m_margins;
735 }
736 
744 {
745  return d->margins(units);
746 }
747 
755 {
756  return d->marginsPoints();
757 }
758 
766 {
767  return d->marginsPixels(resolution);
768 }
769 
784 {
785  d.detach();
786  d->setDefaultMargins(minMargins);
787 }
788 
796 {
797  return d->m_minMargins;
798 }
799 
813 {
814  return d->m_maxMargins;
815 }
816 
827 {
828  return isValid() ? d->fullRect() : QRect();
829 }
830 
841 {
842  return isValid() ? d->fullRect(units) : QRect();
843 }
844 
855 {
856  return isValid() ? d->fullRectPoints() : QRect();
857 }
858 
868 QRect QPageLayout::fullRectPixels(int resolution) const
869 {
870  return isValid() ? d->fullRectPixels(resolution) : QRect();
871 }
872 
884 {
885  return isValid() ? d->paintRect() : QRectF();
886 }
887 
899 {
900  if (!isValid())
901  return QRectF();
902  if (units == d->m_units)
903  return d->paintRect();
904  return d->m_mode == FullPageMode ? d->fullRect(units)
905  : d->fullRect(units) - d->margins(units);
906 }
907 
919 {
920  if (!isValid())
921  return QRect();
922  return d->m_mode == FullPageMode ? d->fullRectPoints()
923  : d->fullRectPoints() - d->marginsPoints();
924 }
925 
936 QRect QPageLayout::paintRectPixels(int resolution) const
937 {
938  if (!isValid())
939  return QRect();
940  return d->m_mode == FullPageMode ? d->fullRectPixels(resolution)
941  : d->fullRectPixels(resolution) - d->marginsPixels(resolution);
942 }
943 
944 #ifndef QT_NO_DEBUG_STREAM
946 {
947  QDebugStateSaver saver(dbg);
948  dbg.nospace();
949  dbg.noquote();
950  dbg << "QPageLayout(";
951  if (layout.isValid()) {
952  const QMarginsF margins = layout.margins();
953  dbg << '"' << layout.pageSize().name() << "\", "
954  << (layout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape")
955  << ", l:" << margins.left() << " r:" << margins.right() << " t:"
956  << margins.top() << " b:" << margins.bottom() << ' ';
957  switch (layout.units()) {
959  dbg << "mm";
960  break;
961  case QPageLayout::Point:
962  dbg << "pt";
963  break;
964  case QPageLayout::Inch:
965  dbg << "in";
966  break;
967  case QPageLayout::Pica:
968  dbg << "pc";
969  break;
970  case QPageLayout::Didot:
971  dbg << "DD";
972  break;
973  case QPageLayout::Cicero:
974  dbg << "CC";
975  break;
976  }
977  }
978  dbg << ')';
979  return dbg;
980 }
981 #endif
982 
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
QDebug & noquote()
Definition: qdebug.h:124
QDebug & nospace()
Definition: qdebug.h:113
Convenience class for custom QDebug operators.
Definition: qdebug.h:176
The QMarginsF class defines the four margins of a rectangle.
Definition: qmargins.h:301
constexpr qreal right() const noexcept
Definition: qmargins.h:397
constexpr qreal left() const noexcept
Definition: qmargins.h:391
constexpr qreal top() const noexcept
Definition: qmargins.h:394
constexpr void setLeft(qreal aleft) noexcept
Definition: qmargins.h:404
constexpr bool isNull() const noexcept
Definition: qmargins.h:388
constexpr QMargins toMargins() const noexcept
Definition: qmargins.h:519
constexpr void setRight(qreal aright) noexcept
Definition: qmargins.h:410
constexpr void setBottom(qreal abottom) noexcept
Definition: qmargins.h:413
constexpr void setTop(qreal atop) noexcept
Definition: qmargins.h:407
constexpr qreal bottom() const noexcept
Definition: qmargins.h:400
The QMargins class defines the four margins of a rectangle.
Definition: qmargins.h:52
Describes the size, orientation and margins of a page.
Definition: qpagelayout.h:56
QRect paintRectPoints() const
QMargins marginsPoints() const
bool setLeftMargin(qreal leftMargin)
QMarginsF minimumMargins() const
void setOrientation(Orientation orientation)
QRect fullRectPoints() const
bool setBottomMargin(qreal bottomMargin)
Mode mode() const
QRectF fullRect() const
bool isEquivalentTo(const QPageLayout &other) const
void setMinimumMargins(const QMarginsF &minMargins)
void setUnits(Unit units)
bool setMargins(const QMarginsF &margins)
Unit units() const
bool isValid() const
QMargins marginsPixels(int resolution) const
bool setRightMargin(qreal rightMargin)
QRectF paintRect() const
bool setTopMargin(qreal topMargin)
QMarginsF margins() const
QPageLayout & operator=(const QPageLayout &other)
Orientation orientation() const
QMarginsF maximumMargins() const
QRect paintRectPixels(int resolution) const
void setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins=QMarginsF(0, 0, 0, 0))
QRect fullRectPixels(int resolution) const
void setMode(Mode mode)
QPageSize pageSize() const
bool isEquivalentTo(const QPageLayoutPrivate &other) const
bool operator==(const QPageLayoutPrivate &other) const
void setDefaultMargins(const QMarginsF &minMargins)
QMargins marginsPixels(int resolution) const
QRect fullRectPixels(int resolution) const
QRect fullRectPoints() const
QMarginsF margins(QPageLayout::Unit units) const
QRectF paintRect() const
bool isValid() const
QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation, const QMarginsF &margins, QPageLayout::Unit units, const QMarginsF &minMargins)
void clampMargins(const QMarginsF &margins)
QRectF fullRect() const
QMargins marginsPoints() const
QSizeF paintSize() const
The QPageSize class describes the size and name of a defined page size.
Definition: qpagesize.h:58
bool isValid() const
Definition: qpagesize.cpp:1296
QSizeF size(Unit units) const
Definition: qpagesize.cpp:1412
QSize sizePoints() const
Definition: qpagesize.cpp:1423
QSize sizePixels(int resolution) const
Definition: qpagesize.cpp:1434
bool isEquivalentTo(const QPageSize &other) const
Definition: qpagesize.cpp:1282
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
constexpr qreal x() const noexcept
Definition: qpoint.h:361
constexpr qreal y() const noexcept
Definition: qpoint.h:366
bool isNull() const noexcept
Definition: qpoint.h:356
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
The QSharedData class is a base class for shared data objects. \reentrant.
Definition: qshareddata.h:55
The QSizeF class defines the size of a two-dimensional object using floating point precision.
Definition: qsize.h:235
constexpr qreal width() const noexcept
Definition: qsize.h:349
constexpr QSizeF transposed() const noexcept
Definition: qsize.h:361
constexpr qreal height() const noexcept
Definition: qsize.h:352
constexpr QSize transposed() const noexcept
Definition: qsize.h:169
png_const_structrp png_const_inforp int * unit
Definition: png.h:2159
int qRound(qfloat16 d) noexcept
Definition: qfloat16.h:227
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
GLenum mode
GLfloat units
QPointF qt_convertPoint(const QPointF &xy, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
Definition: qpagelayout.cpp:74
Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
Definition: qpagelayout.cpp:96
qreal qt_pixelMultiplier(int resolution)
Definition: qpagesize.cpp:527
QT_BEGIN_NAMESPACE Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit)
Definition: qpagelayout.cpp:52
QVBoxLayout * layout
QSharedPointer< T > other(t)
[5]