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 
49 QT_BEGIN_NAMESPACE
50 
51 // Multiplier for converting units to points.
qt_pointMultiplier(QPageLayout::Unit unit)52 Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit)
53 {
54     switch (unit) {
55     case QPageLayout::Millimeter:
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;
65     case QPageLayout::Cicero:
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 
qt_convertPoint(const QPointF & xy,QPageLayout::Unit fromUnits,QPageLayout::Unit toUnits)74 QPointF qt_convertPoint(const QPointF &xy, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
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 
qt_convertMargins(const QMarginsF & margins,QPageLayout::Unit fromUnits,QPageLayout::Unit toUnits)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 
122 class QPageLayoutPrivate : public QSharedData
123 {
124 public:
125 
126     QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation,
127                        const QMarginsF &margins, QPageLayout::Unit units,
128                        const QMarginsF &minMargins);
129     ~QPageLayoutPrivate();
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 
138     QMarginsF margins(QPageLayout::Unit units) const;
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;
147     QRectF fullRect(QPageLayout::Unit units) 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 
QPageLayoutPrivate(const QPageSize & pageSize,QPageLayout::Orientation orientation,const QMarginsF & margins,QPageLayout::Unit units,const QMarginsF & minMargins)168 QPageLayoutPrivate::QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation,
169                                        const QMarginsF &margins, QPageLayout::Unit units,
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 
~QPageLayoutPrivate()181 QPageLayoutPrivate::~QPageLayoutPrivate()
182 {
183 }
184 
operator ==(const QPageLayoutPrivate & other) const185 bool QPageLayoutPrivate::operator==(const QPageLayoutPrivate &other) const
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 
isEquivalentTo(const QPageLayoutPrivate & other) const195 bool QPageLayoutPrivate::isEquivalentTo(const QPageLayoutPrivate &other) const
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 
isValid() const203 bool QPageLayoutPrivate::isValid() const
204 {
205     return m_pageSize.isValid();
206 }
207 
clampMargins(const QMarginsF & margins)208 void QPageLayoutPrivate::clampMargins(const QMarginsF &margins)
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 
margins(QPageLayout::Unit units) const216 QMarginsF QPageLayoutPrivate::margins(QPageLayout::Unit units) const
217 {
218     return qt_convertMargins(m_margins, m_units, units);
219 }
220 
marginsPoints() const221 QMargins QPageLayoutPrivate::marginsPoints() const
222 {
223     return qt_convertMargins(m_margins, m_units, QPageLayout::Point).toMargins();
224 }
225 
marginsPixels(int resolution) const226 QMargins QPageLayoutPrivate::marginsPixels(int resolution) const
227 {
228     return marginsPoints() / qt_pixelMultiplier(resolution);
229 }
230 
setDefaultMargins(const QMarginsF & minMargins)231 void QPageLayoutPrivate::setDefaultMargins(const QMarginsF &minMargins)
232 {
233     m_minMargins = minMargins;
234     m_maxMargins = QMarginsF(m_fullSize.width() - m_minMargins.right(),
235                              m_fullSize.height() - m_minMargins.bottom(),
236                              m_fullSize.width() - m_minMargins.left(),
237                              m_fullSize.height() - m_minMargins.top());
238     if (m_mode == QPageLayout::StandardMode)
239         clampMargins(m_margins);
240 }
241 
fullSizeUnits(QPageLayout::Unit units) const242 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 
fullRect() const248 QRectF QPageLayoutPrivate::fullRect() const
249 {
250     return QRectF(QPointF(0, 0), m_fullSize);
251 }
252 
fullRect(QPageLayout::Unit units) const253 QRectF QPageLayoutPrivate::fullRect(QPageLayout::Unit units) const
254 {
255     return units == m_units ? fullRect() : QRectF(QPointF(0, 0), fullSizeUnits(units));
256 }
257 
fullRectPoints() const258 QRect QPageLayoutPrivate::fullRectPoints() const
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 
fullRectPixels(int resolution) const266 QRect QPageLayoutPrivate::fullRectPixels(int resolution) const
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 
paintRect() const274 QRectF QPageLayoutPrivate::paintRect() const
275 {
276     return m_mode == QPageLayout::FullPageMode ? fullRect() : fullRect() - m_margins;
277 }
278 
279 
280 /*!
281     \class QPageLayout
282     \inmodule QtGui
283     \since 5.3
284     \brief Describes the size, orientation and margins of a page.
285 
286     The QPageLayout class defines the layout of a page in a paged document, with the
287     page size, orientation and margins able to be set and the full page and paintable
288     page rectangles defined by those attributes able to be queried in a variety of units.
289 
290     The page size is defined by the QPageSize class which can be queried for page size
291     attributes.  Note that the QPageSize itself is always defined in a Portrait
292     orientation.
293 
294     The minimum margins can be defined for the layout but normally default to 0.
295     When used in conjunction with Qt's printing support the minimum margins
296     will reflect the minimum printable area defined by the printer.
297 
298     In the default StandardMode the current margins and minimum margins are
299     always taken into account.  The paintable rectangle is the full page
300     rectangle less the current margins, and the current margins can only be set
301     to values between the minimum margins and the maximum margins allowed by
302     the full page size.
303 
304     In FullPageMode the current margins and minimum margins are not taken
305     into account. The paintable rectangle is the full page rectangle, and the
306     current margins can be set to any values regardless of the minimum margins
307     and page size.
308 
309     \sa QPageSize
310 */
311 
312 /*!
313     \enum QPageLayout::Unit
314 
315     This enum type is used to specify the measurement unit for page layout and margins.
316 
317     \value Millimeter
318     \value Point  1/72th of an inch
319     \value Inch
320     \value Pica  1/72th of a foot, 1/6th of an inch, 12 Points
321     \value Didot  1/72th of a French inch, 0.375 mm
322     \value Cicero  1/6th of a French inch, 12 Didot, 4.5mm
323 */
324 
325 /*!
326     \enum QPageLayout::Orientation
327 
328     This enum type defines the page orientation
329 
330     \value Portrait The page size is used in its default orientation
331     \value Landscape The page size is rotated through 90 degrees
332 
333     Note that some standard page sizes are defined with a width larger than
334     their height, hence the orientation is defined relative to the standard
335     page size and not using the relative page dimensions.
336 */
337 
338 /*!
339     \enum QPageLayout::Mode
340 
341     Defines the page layout mode
342 
343     \value StandardMode Paint Rect includes margins, margins must fall between the minimum and maximum.
344     \value FullPageMode Paint Rect excludes margins, margins can be any value and must be managed manually.
345 */
346 
347 /*!
348     Creates an invalid QPageLayout.
349 */
350 
QPageLayout()351 QPageLayout::QPageLayout()
352     : QPageLayout(QPageSize(), QPageLayout::Landscape, QMarginsF())
353 {
354 }
355 
356 /*!
357     Creates a QPageLayout with the given \a pageSize, \a orientation and
358     \a margins in the given \a units.
359 
360     Optionally define the minimum allowed margins \a minMargins, e.g. the minimum
361     margins able to be printed by a physical print device.
362 
363     The constructed QPageLayout will be in StandardMode.
364 
365     The \a margins given will be clamped to the minimum margins and the maximum
366     margins allowed by the page size.
367 */
368 
QPageLayout(const QPageSize & pageSize,Orientation orientation,const QMarginsF & margins,Unit units,const QMarginsF & minMargins)369 QPageLayout::QPageLayout(const QPageSize &pageSize, Orientation orientation,
370                          const QMarginsF &margins, Unit units,
371                          const QMarginsF &minMargins)
372     : d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins))
373 {
374 }
375 
376 /*!
377     Copy constructor, copies \a other to this.
378 */
379 
QPageLayout(const QPageLayout & other)380 QPageLayout::QPageLayout(const QPageLayout &other)
381     : d(other.d)
382 {
383 }
384 
385 /*!
386     Destroys the page layout.
387 */
388 
~QPageLayout()389 QPageLayout::~QPageLayout()
390 {
391 }
392 
393 /*!
394     Assignment operator, assigns \a other to this.
395 */
396 
operator =(const QPageLayout & other)397 QPageLayout &QPageLayout::operator=(const QPageLayout &other)
398 {
399     d = other.d;
400     return *this;
401 }
402 
403 /*!
404     \fn void QPageLayout::swap(QPageLayout &other)
405 
406     Swaps this page layout with \a other. This function is very fast and
407     never fails.
408 */
409 
410 /*!
411     \fn QPageLayout &QPageLayout::operator=(QPageLayout &&other)
412 
413     Move-assigns \a other to this QPageLayout instance, transferring the
414     ownership of the managed pointer to this instance.
415 */
416 
417 /*!
418     \relates QPageLayout
419 
420     Returns \c true if page layout \a lhs is equal to page layout \a rhs,
421     i.e. if all the attributes are exactly equal.
422 
423     Note that this is a strict equality, especially for page size where the
424     QPageSize ID, name and size must exactly match, and the margins where the
425     units must match.
426 
427     \sa QPageLayout::isEquivalentTo()
428 */
429 
operator ==(const QPageLayout & lhs,const QPageLayout & rhs)430 bool operator==(const QPageLayout &lhs, const QPageLayout &rhs)
431 {
432     return lhs.d == rhs.d || *lhs.d == *rhs.d;
433 }
434 
435 /*!
436     \fn bool operator!=(const QPageLayout &lhs, const QPageLayout &rhs)
437     \relates QPageLayout
438 
439     Returns \c true if page layout \a lhs is not equal to page layout \a rhs,
440     i.e. if any of the attributes differ.
441 
442     Note that this is a strict equality, especially for page size where the
443     QPageSize ID, name and size must exactly match, and the margins where the
444     units must match.
445 
446     \sa QPageLayout::isEquivalentTo()
447 */
448 
449 /*!
450     Returns \c true if this page layout is equivalent to the \a other page layout,
451     i.e. if the page has the same size, margins and orientation.
452 */
453 
isEquivalentTo(const QPageLayout & other) const454 bool QPageLayout::isEquivalentTo(const QPageLayout &other) const
455 {
456     return d && other.d && d->isEquivalentTo(*other.d);
457 }
458 
459 /*!
460     Returns \c true if this page layout is valid.
461 */
462 
isValid() const463 bool QPageLayout::isValid() const
464 {
465     return d->isValid();
466 }
467 
468 /*!
469     Sets a page layout mode to \a mode.
470 */
471 
setMode(Mode mode)472 void QPageLayout::setMode(Mode mode)
473 {
474     d.detach();
475     d->m_mode = mode;
476 }
477 
478 /*!
479     Returns the page layout mode.
480 */
481 
mode() const482 QPageLayout::Mode QPageLayout::mode() const
483 {
484     return d->m_mode;
485 }
486 
487 /*!
488     Sets the page size of the page layout to \a pageSize.
489 
490     Optionally define the minimum allowed margins \a minMargins, e.g. the minimum
491     margins able to be printed by a physical print device, otherwise the
492     minimum margins will default to 0.
493 
494     If StandardMode is set then the existing margins will be clamped
495     to the new minimum margins and the maximum margins allowed by the page size.
496     If FullPageMode is set then the existing margins will be unchanged.
497 */
498 
setPageSize(const QPageSize & pageSize,const QMarginsF & minMargins)499 void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins)
500 {
501     if (!pageSize.isValid())
502         return;
503     d.detach();
504     d->m_pageSize = pageSize;
505     d->m_fullSize = d->fullSizeUnits(d->m_units);
506     d->setDefaultMargins(minMargins);
507 }
508 
509 /*!
510     Returns the page size of the page layout.
511 
512     Note that the QPageSize is always defined in a Portrait orientation.  To
513     obtain a size that takes the set orientation into account you must use
514     fullRect().
515 */
516 
pageSize() const517 QPageSize QPageLayout::pageSize() const
518 {
519     return d->m_pageSize;
520 }
521 
522 /*!
523     Sets the page orientation of the page layout to \a orientation.
524 
525     Changing the orientation does not affect the current margins or
526     the minimum margins.
527 */
528 
setOrientation(Orientation orientation)529 void QPageLayout::setOrientation(Orientation orientation)
530 {
531     if (orientation != d->m_orientation) {
532         d.detach();
533         d->m_orientation = orientation;
534         d->m_fullSize = d->fullSizeUnits(d->m_units);
535         // Adust the max margins to reflect change in max page size
536         const qreal change = d->m_fullSize.width() - d->m_fullSize.height();
537         d->m_maxMargins.setLeft(d->m_maxMargins.left() + change);
538         d->m_maxMargins.setRight(d->m_maxMargins.right() + change);
539         d->m_maxMargins.setTop(d->m_maxMargins.top() - change);
540         d->m_maxMargins.setBottom(d->m_maxMargins.bottom() - change);
541     }
542 }
543 
544 /*!
545     Returns the page orientation of the page layout.
546 */
547 
orientation() const548 QPageLayout::Orientation QPageLayout::orientation() const
549 {
550     return d->m_orientation;
551 }
552 
553 /*!
554     Sets the \a units used to define the page layout.
555 */
556 
setUnits(Unit units)557 void QPageLayout::setUnits(Unit units)
558 {
559     if (units != d->m_units) {
560         d.detach();
561         d->m_margins = qt_convertMargins(d->m_margins, d->m_units, units);
562         d->m_minMargins = qt_convertMargins(d->m_minMargins, d->m_units, units);
563         d->m_maxMargins = qt_convertMargins(d->m_maxMargins, d->m_units, units);
564         d->m_units = units;
565         d->m_fullSize = d->fullSizeUnits(d->m_units);
566     }
567 }
568 
569 /*!
570     Returns the units the page layout is currently defined in.
571 */
572 
units() const573 QPageLayout::Unit QPageLayout::units() const
574 {
575     return d->m_units;
576 }
577 
578 /*!
579     Sets the page margins of the page layout to \a margins
580     Returns true if the margins were successfully set.
581 
582     The units used are those currently defined for the layout.  To use different
583     units then call setUnits() first.
584 
585     If in the default StandardMode then all the new margins must fall between the
586     minimum margins set and the maximum margins allowed by the page size,
587     otherwise the margins will not be set.
588 
589     If in FullPageMode then any margin values will be accepted.
590 
591     \sa margins(), units()
592 */
593 
setMargins(const QMarginsF & margins)594 bool QPageLayout::setMargins(const QMarginsF &margins)
595 {
596     if (d->m_mode == FullPageMode) {
597         d.detach();
598         d->m_margins = margins;
599         return true;
600     } else if (margins.left() >= d->m_minMargins.left()
601                && margins.right() >= d->m_minMargins.right()
602                && margins.top() >= d->m_minMargins.top()
603                && margins.bottom() >= d->m_minMargins.bottom()
604                && margins.left() <= d->m_maxMargins.left()
605                && margins.right() <= d->m_maxMargins.right()
606                && margins.top() <= d->m_maxMargins.top()
607                && margins.bottom() <= d->m_maxMargins.bottom()) {
608         d.detach();
609         d->m_margins = margins;
610         return true;
611     }
612     return false;
613 }
614 
615 /*!
616     Sets the left page margin of the page layout to \a leftMargin.
617     Returns true if the margin was successfully set.
618 
619     The units used are those currently defined for the layout.  To use different
620     units call setUnits() first.
621 
622     If in the default StandardMode then the new margin must fall between the
623     minimum margin set and the maximum margin allowed by the page size,
624     otherwise the margin will not be set.
625 
626     If in FullPageMode then any margin values will be accepted.
627 
628     \sa setMargins(), margins()
629 */
630 
setLeftMargin(qreal leftMargin)631 bool QPageLayout::setLeftMargin(qreal leftMargin)
632 {
633     if (d->m_mode == FullPageMode
634         || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) {
635         d.detach();
636         d->m_margins.setLeft(leftMargin);
637         return true;
638     }
639     return false;
640 }
641 
642 /*!
643     Sets the right page margin of the page layout to \a rightMargin.
644     Returns true if the margin was successfully set.
645 
646     The units used are those currently defined for the layout.  To use different
647     units call setUnits() first.
648 
649     If in the default StandardMode then the new margin must fall between the
650     minimum margin set and the maximum margin allowed by the page size,
651     otherwise the margin will not be set.
652 
653     If in FullPageMode then any margin values will be accepted.
654 
655     \sa setMargins(), margins()
656 */
657 
setRightMargin(qreal rightMargin)658 bool QPageLayout::setRightMargin(qreal rightMargin)
659 {
660     if (d->m_mode == FullPageMode
661         || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) {
662         d.detach();
663         d->m_margins.setRight(rightMargin);
664         return true;
665     }
666     return false;
667 }
668 
669 /*!
670     Sets the top page margin of the page layout to \a topMargin.
671     Returns true if the margin was successfully set.
672 
673     The units used are those currently defined for the layout.  To use different
674     units call setUnits() first.
675 
676     If in the default StandardMode then the new margin must fall between the
677     minimum margin set and the maximum margin allowed by the page size,
678     otherwise the margin will not be set.
679 
680     If in FullPageMode then any margin values will be accepted.
681 
682     \sa setMargins(), margins()
683 */
684 
setTopMargin(qreal topMargin)685 bool QPageLayout::setTopMargin(qreal topMargin)
686 {
687     if (d->m_mode == FullPageMode
688         || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) {
689         d.detach();
690         d->m_margins.setTop(topMargin);
691         return true;
692     }
693     return false;
694 }
695 
696 /*!
697     Sets the bottom page margin of the page layout to \a bottomMargin.
698     Returns true if the margin was successfully set.
699 
700     The units used are those currently defined for the layout.  To use different
701     units call setUnits() first.
702 
703     If in the default StandardMode then the new margin must fall between the
704     minimum margin set and the maximum margin allowed by the page size,
705     otherwise the margin will not be set.
706 
707     If in FullPageMode then any margin values will be accepted.
708 
709     \sa setMargins(), margins()
710 */
711 
setBottomMargin(qreal bottomMargin)712 bool QPageLayout::setBottomMargin(qreal bottomMargin)
713 {
714     if (d->m_mode == FullPageMode
715         || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) {
716         d.detach();
717         d->m_margins.setBottom(bottomMargin);
718         return true;
719     }
720     return false;
721 }
722 
723 /*!
724     Returns the margins of the page layout using the currently set units.
725 
726     \sa setMargins(), units()
727 */
728 
margins() const729 QMarginsF QPageLayout::margins() const
730 {
731     return d->m_margins;
732 }
733 
734 /*!
735     Returns the margins of the page layout using the requested \a units.
736 
737     \sa setMargins(), margins()
738 */
739 
margins(Unit units) const740 QMarginsF QPageLayout::margins(Unit units) const
741 {
742     return d->margins(units);
743 }
744 
745 /*!
746     Returns the margins of the page layout in Postscript Points (1/72 of an inch).
747 
748     \sa setMargins(), margins()
749 */
750 
marginsPoints() const751 QMargins QPageLayout::marginsPoints() const
752 {
753     return d->marginsPoints();
754 }
755 
756 /*!
757     Returns the margins of the page layout in device pixels for the given \a resolution.
758 
759     \sa setMargins()
760 */
761 
marginsPixels(int resolution) const762 QMargins QPageLayout::marginsPixels(int resolution) const
763 {
764     return d->marginsPixels(resolution);
765 }
766 
767 /*!
768     Sets the minimum page margins of the page layout to \a minMargins.
769 
770     It is not recommended to override the default values set for a page size
771     as this may be the minimum printable area for a physical print device.
772 
773     If the StandardMode mode is set then the existing margins will be clamped
774     to the new \a minMargins and the maximum allowed by the page size.  If the
775     FullPageMode is set then the existing margins will be unchanged.
776 
777     \sa minimumMargins(), setMargins()
778 */
779 
setMinimumMargins(const QMarginsF & minMargins)780 void QPageLayout::setMinimumMargins(const QMarginsF &minMargins)
781 {
782     d.detach();
783     d->setDefaultMargins(minMargins);
784 }
785 
786 /*!
787     Returns the minimum margins of the page layout.
788 
789     \sa setMinimumMargins(), maximumMargins()
790 */
791 
minimumMargins() const792 QMarginsF QPageLayout::minimumMargins() const
793 {
794     return d->m_minMargins;
795 }
796 
797 /*!
798     Returns the maximum margins that would be applied if the page layout was
799     in StandardMode.
800 
801     The maximum margins allowed are calculated as the full size of the page
802     minus the minimum margins set. For example, if the page width is 100 points
803     and the minimum right margin is 10 points, then the maximum left margin
804     will be 90 points.
805 
806     \sa setMinimumMargins(), minimumMargins()
807 */
808 
maximumMargins() const809 QMarginsF QPageLayout::maximumMargins() const
810 {
811     return d->m_maxMargins;
812 }
813 
814 /*!
815     Returns the full page rectangle in the current layout units.
816 
817     The page rectangle takes into account the page size and page orientation,
818     but not the page margins.
819 
820     \sa paintRect(), units()
821 */
822 
fullRect() const823 QRectF QPageLayout::fullRect() const
824 {
825     return isValid() ? d->fullRect() : QRect();
826 }
827 
828 /*!
829     Returns the full page rectangle in the required \a units.
830 
831     The page rectangle takes into account the page size and page orientation,
832     but not the page margins.
833 
834     \sa paintRect()
835 */
836 
fullRect(Unit units) const837 QRectF QPageLayout::fullRect(Unit units) const
838 {
839     return isValid() ? d->fullRect(units) : QRect();
840 }
841 
842 /*!
843     Returns the full page rectangle in Postscript Points (1/72 of an inch).
844 
845     The page rectangle takes into account the page size and page orientation,
846     but not the page margins.
847 
848     \sa paintRect()
849 */
850 
fullRectPoints() const851 QRect QPageLayout::fullRectPoints() const
852 {
853     return isValid() ? d->fullRectPoints() : QRect();
854 }
855 
856 /*!
857     Returns the full page rectangle in device pixels for the given \a resolution.
858 
859     The page rectangle takes into account the page size and page orientation,
860     but not the page margins.
861 
862     \sa paintRect()
863 */
864 
fullRectPixels(int resolution) const865 QRect QPageLayout::fullRectPixels(int resolution) const
866 {
867     return isValid() ? d->fullRectPixels(resolution) : QRect();
868 }
869 
870 /*!
871     Returns the page rectangle in the current layout units.
872 
873     The paintable rectangle takes into account the page size, orientation
874     and margins.
875 
876     If the FullPageMode mode is set then the fullRect() is returned and
877     the margins must be manually managed.
878 */
879 
paintRect() const880 QRectF QPageLayout::paintRect() const
881 {
882     return isValid() ? d->paintRect() : QRectF();
883 }
884 
885 /*!
886     Returns the page rectangle in the required \a units.
887 
888     The paintable rectangle takes into account the page size, orientation
889     and margins.
890 
891     If the FullPageMode mode is set then the fullRect() is returned and
892     the margins must be manually managed.
893 */
894 
paintRect(Unit units) const895 QRectF QPageLayout::paintRect(Unit units) const
896 {
897     if (!isValid())
898         return QRectF();
899     if (units == d->m_units)
900         return d->paintRect();
901     return d->m_mode == FullPageMode ? d->fullRect(units)
902                                                   : d->fullRect(units) - d->margins(units);
903 }
904 
905 /*!
906     Returns the paintable rectangle in rounded Postscript Points (1/72 of an inch).
907 
908     The paintable rectangle takes into account the page size, orientation
909     and margins.
910 
911     If the FullPageMode mode is set then the fullRect() is returned and
912     the margins must be manually managed.
913 */
914 
paintRectPoints() const915 QRect QPageLayout::paintRectPoints() const
916 {
917     if (!isValid())
918         return QRect();
919     return d->m_mode == FullPageMode ? d->fullRectPoints()
920                                                   : d->fullRectPoints() - d->marginsPoints();
921 }
922 
923 /*!
924     Returns the paintable rectangle in rounded device pixels for the given \a resolution.
925 
926     The paintable rectangle takes into account the page size, orientation
927     and margins.
928 
929     If the FullPageMode mode is set then the fullRect() is returned and
930     the margins must be manually managed.
931 */
932 
paintRectPixels(int resolution) const933 QRect QPageLayout::paintRectPixels(int resolution) const
934 {
935     if (!isValid())
936         return QRect();
937     return d->m_mode == FullPageMode ? d->fullRectPixels(resolution)
938                                                   : d->fullRectPixels(resolution) - d->marginsPixels(resolution);
939 }
940 
941 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QPageLayout & layout)942 QDebug operator<<(QDebug dbg, const QPageLayout &layout)
943 {
944     QDebugStateSaver saver(dbg);
945     dbg.nospace();
946     dbg.noquote();
947     dbg << "QPageLayout(";
948     if (layout.isValid()) {
949         const QMarginsF margins = layout.margins();
950         dbg << '"' << layout.pageSize().name() << "\", "
951             << (layout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape")
952             << ", l:" << margins.left() << " r:" << margins.right() << " t:"
953             << margins.top() << " b:" << margins.bottom() << ' ';
954         switch (layout.units()) {
955         case QPageLayout::Millimeter:
956             dbg << "mm";
957             break;
958         case QPageLayout::Point:
959             dbg << "pt";
960             break;
961         case QPageLayout::Inch:
962             dbg << "in";
963             break;
964         case QPageLayout::Pica:
965             dbg << "pc";
966             break;
967         case QPageLayout::Didot:
968             dbg << "DD";
969             break;
970         case QPageLayout::Cicero:
971             dbg << "CC";
972             break;
973         }
974     }
975     dbg << ')';
976     return dbg;
977 }
978 #endif
979 
980 QT_END_NAMESPACE
981