Coverage Report

Created: 2026-04-01 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/painting/qpagelayout.cpp
Line
Count
Source
1
// Copyright (C) 2014 John Layt <jlayt@kde.org>
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
6
#include "qpagelayout.h"
7
8
#include <QtCore/qpoint.h>
9
#include <QtCore/qrect.h>
10
#include <QtCore/qsize.h>
11
12
#include <qdebug.h>
13
14
QT_BEGIN_NAMESPACE
15
16
QT_IMPL_METATYPE_EXTERN(QPageLayout)
17
QT_IMPL_METATYPE_EXTERN_TAGGED(QPageLayout::Unit, QPageLayout__Unit)
18
QT_IMPL_METATYPE_EXTERN_TAGGED(QPageLayout::Orientation, QPageLayout__Orientation)
19
20
// Multiplier for converting units to points.
21
Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit)
22
0
{
23
0
    switch (unit) {
24
0
    case QPageLayout::Millimeter:
25
0
        return 2.83464566929;
26
0
    case QPageLayout::Point:
27
0
        return 1.0;
28
0
    case QPageLayout::Inch:
29
0
        return 72.0;
30
0
    case QPageLayout::Pica:
31
0
        return 12;
32
0
    case QPageLayout::Didot:
33
0
        return 1.065826771;
34
0
    case QPageLayout::Cicero:
35
0
        return 12.789921252;
36
0
    }
37
0
    return 1.0;
38
0
}
39
40
// Multiplier for converting pixels to points.
41
Q_GUI_EXPORT extern qreal qt_pixelMultiplier(int resolution);
42
43
Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
44
0
{
45
    // If the margins have the same units, or are all 0, then don't need to convert
46
0
    if (fromUnits == toUnits || margins.isNull())
47
0
        return margins;
48
49
    // If converting to points then convert and round up to 2 decimal places
50
0
    if (toUnits == QPageLayout::Point) {
51
0
        const qreal multiplierX100 = qt_pointMultiplier(fromUnits) * 100;
52
0
        return QMarginsF(qCeil(margins.left() * multiplierX100) / 100.0,
53
0
                         qCeil(margins.top() * multiplierX100) / 100.0,
54
0
                         qCeil(margins.right() * multiplierX100) / 100.0,
55
0
                         qCeil(margins.bottom() * multiplierX100) / 100.0);
56
0
    }
57
58
    // If converting to other units, need to convert to unrounded points first
59
0
    QMarginsF pointMargins = fromUnits == QPageLayout::Point ? margins : margins * qt_pointMultiplier(fromUnits);
60
61
    // Then convert from points to required units rounded to 2 decimal places
62
0
    const qreal multiplier = qt_pointMultiplier(toUnits);
63
0
    return QMarginsF(qRound(pointMargins.left() * 100 / multiplier) / 100.0,
64
0
                     qRound(pointMargins.top() * 100 / multiplier) / 100.0,
65
0
                     qRound(pointMargins.right() * 100 / multiplier) / 100.0,
66
0
                     qRound(pointMargins.bottom() * 100 / multiplier) / 100.0);
67
0
}
68
69
class QPageLayoutPrivate : public QSharedData
70
{
71
public:
72
73
    QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation,
74
                       const QMarginsF &margins, QPageLayout::Unit units,
75
                       const QMarginsF &minMargins);
76
77
    bool operator==(const QPageLayoutPrivate &other) const;
78
    bool isEquivalentTo(const QPageLayoutPrivate &other) const;
79
80
    bool isValid() const;
81
82
    QMarginsF clampMargins(const QMarginsF &margins) const;
83
84
    QMarginsF margins(QPageLayout::Unit units) const;
85
    QMarginsF marginsPoints() const;
86
    QMargins marginsPixels(int resolution) const;
87
88
    void setDefaultMargins(const QMarginsF &minMargins);
89
90
    QSizeF paintSize() const;
91
92
    QRectF fullRect() const;
93
    QRectF fullRect(QPageLayout::Unit units) const;
94
    QRect fullRectPoints() const;
95
    QRect fullRectPixels(int resolution) const;
96
97
    QRectF paintRect() const;
98
99
private:
100
    friend class QPageLayout;
101
102
    QSizeF fullSizeUnits(QPageLayout::Unit units) const;
103
104
    QPageSize m_pageSize;
105
    QPageLayout::Orientation m_orientation;
106
    QPageLayout::Mode m_mode;
107
    QPageLayout::Unit m_units;
108
    QSizeF m_fullSize;
109
    QMarginsF m_margins;
110
    QMarginsF m_minMargins;
111
    QMarginsF m_maxMargins;
112
};
113
114
QPageLayoutPrivate::QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation,
115
                                       const QMarginsF &margins, QPageLayout::Unit units,
116
                                       const QMarginsF &minMargins)
117
0
    : m_pageSize(pageSize),
118
0
      m_orientation(orientation),
119
0
      m_mode(QPageLayout::StandardMode),
120
0
      m_units(units),
121
0
      m_margins(margins)
122
0
{
123
0
    m_fullSize = fullSizeUnits(m_units);
124
0
    setDefaultMargins(minMargins);
125
0
}
126
127
bool QPageLayoutPrivate::operator==(const QPageLayoutPrivate &other) const
128
0
{
129
0
    return m_pageSize == other.m_pageSize
130
0
           && m_orientation == other.m_orientation
131
0
           && m_units == other.m_units
132
0
           && m_margins == other.m_margins
133
0
           && m_minMargins == other.m_minMargins
134
0
           && m_maxMargins == other.m_maxMargins;
135
0
}
136
137
bool QPageLayoutPrivate::isEquivalentTo(const QPageLayoutPrivate &other) const
138
0
{
139
0
    return m_pageSize.isEquivalentTo(other.m_pageSize)
140
0
           && m_orientation == other.m_orientation
141
0
           && qt_convertMargins(m_margins, m_units, QPageLayout::Point)
142
0
              == qt_convertMargins(other.m_margins, other.m_units, QPageLayout::Point);
143
0
}
144
145
bool QPageLayoutPrivate::isValid() const
146
0
{
147
0
    return m_pageSize.isValid();
148
0
}
149
150
QMarginsF QPageLayoutPrivate::clampMargins(const QMarginsF &margins) const
151
0
{
152
0
    return QMarginsF(qBound(m_minMargins.left(),   margins.left(),   m_maxMargins.left()),
153
0
                     qBound(m_minMargins.top(),    margins.top(),    m_maxMargins.top()),
154
0
                     qBound(m_minMargins.right(),  margins.right(),  m_maxMargins.right()),
155
0
                     qBound(m_minMargins.bottom(), margins.bottom(), m_maxMargins.bottom()));
156
0
}
157
158
QMarginsF QPageLayoutPrivate::margins(QPageLayout::Unit units) const
159
0
{
160
0
    return qt_convertMargins(m_margins, m_units, units);
161
0
}
162
163
QMarginsF QPageLayoutPrivate::marginsPoints() const
164
0
{
165
0
    return qt_convertMargins(m_margins, m_units, QPageLayout::Point);
166
0
}
167
168
QMargins QPageLayoutPrivate::marginsPixels(int resolution) const
169
0
{
170
0
    return QMarginsF(marginsPoints() / qt_pixelMultiplier(resolution)).toMargins();
171
0
}
172
173
void QPageLayoutPrivate::setDefaultMargins(const QMarginsF &minMargins)
174
0
{
175
0
    m_minMargins = minMargins;
176
0
    m_maxMargins = QMarginsF(qMax(m_fullSize.width() - m_minMargins.right(), qreal(0)),
177
0
                             qMax(m_fullSize.height() - m_minMargins.bottom(), qreal(0)),
178
0
                             qMax(m_fullSize.width() - m_minMargins.left(), qreal(0)),
179
0
                             qMax(m_fullSize.height() - m_minMargins.top(), qreal(0)));
180
0
    if (m_mode == QPageLayout::StandardMode)
181
0
        m_margins = clampMargins(m_margins);
182
0
}
183
184
QSizeF QPageLayoutPrivate::fullSizeUnits(QPageLayout::Unit units) const
185
0
{
186
0
    QSizeF fullPageSize = m_pageSize.size(QPageSize::Unit(units));
187
0
    return m_orientation == QPageLayout::Landscape ? fullPageSize.transposed() : fullPageSize;
188
0
}
189
190
QRectF QPageLayoutPrivate::fullRect() const
191
0
{
192
0
    return QRectF(QPointF(0, 0), m_fullSize);
193
0
}
194
195
QRectF QPageLayoutPrivate::fullRect(QPageLayout::Unit units) const
196
0
{
197
0
    return units == m_units ? fullRect() : QRectF(QPointF(0, 0), fullSizeUnits(units));
198
0
}
199
200
QRect QPageLayoutPrivate::fullRectPoints() const
201
0
{
202
0
    if (m_orientation == QPageLayout::Landscape)
203
0
        return QRect(QPoint(0, 0), m_pageSize.sizePoints().transposed());
204
0
    else
205
0
        return QRect(QPoint(0, 0), m_pageSize.sizePoints());
206
0
}
207
208
QRect QPageLayoutPrivate::fullRectPixels(int resolution) const
209
0
{
210
0
    if (m_orientation == QPageLayout::Landscape)
211
0
        return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution).transposed());
212
0
    else
213
0
        return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution));
214
0
}
215
216
QRectF QPageLayoutPrivate::paintRect() const
217
0
{
218
0
    return m_mode == QPageLayout::FullPageMode ? fullRect() : fullRect() - m_margins;
219
0
}
220
221
222
/*!
223
    \class QPageLayout
224
    \inmodule QtGui
225
    \since 5.3
226
    \brief Describes the size, orientation and margins of a page.
227
228
    The QPageLayout class defines the layout of a page in a paged document, with the
229
    page size, orientation and margins able to be set and the full page and paintable
230
    page rectangles defined by those attributes able to be queried in a variety of units.
231
232
    The page size is defined by the QPageSize class which can be queried for page size
233
    attributes.  Note that the QPageSize itself is always defined in a Portrait
234
    orientation.
235
236
    The minimum margins can be defined for the layout but normally default to 0.
237
    When used in conjunction with Qt's printing support the minimum margins
238
    will reflect the minimum printable area defined by the printer.
239
240
    In the default StandardMode the current margins and minimum margins are
241
    always taken into account.  The paintable rectangle is the full page
242
    rectangle less the current margins, and the current margins can only be set
243
    to values between the minimum margins and the maximum margins allowed by
244
    the full page size.
245
246
    In FullPageMode the current margins and minimum margins are not taken
247
    into account. The paintable rectangle is the full page rectangle, and the
248
    current margins can be set to any values regardless of the minimum margins
249
    and page size.
250
251
    \sa QPageSize
252
*/
253
254
/*!
255
    \enum QPageLayout::Unit
256
257
    This enum type is used to specify the measurement unit for page layout and margins.
258
259
    \value Millimeter
260
    \value Point  1/72th of an inch
261
    \value Inch
262
    \value Pica  1/72th of a foot, 1/6th of an inch, 12 Points
263
    \value Didot  1/72th of a French inch, 0.375 mm
264
    \value Cicero  1/6th of a French inch, 12 Didot, 4.5mm
265
*/
266
267
/*!
268
    \enum QPageLayout::Orientation
269
270
    This enum type defines the page orientation
271
272
    \value Portrait The page size is used in its default orientation
273
    \value Landscape The page size is rotated through 90 degrees
274
275
    Note that some standard page sizes are defined with a width larger than
276
    their height, hence the orientation is defined relative to the standard
277
    page size and not using the relative page dimensions.
278
*/
279
280
/*!
281
    \enum QPageLayout::Mode
282
283
    Defines the page layout mode
284
285
    \value StandardMode Paint Rect includes margins, margins must fall between the minimum and maximum.
286
    \value FullPageMode Paint Rect excludes margins, margins can be any value and must be managed manually.
287
288
    In StandardMode, when setting margins, use \l{QPageLayout::OutOfBoundsPolicy::}{Clamp} to
289
    automatically clamp the margins to fall between the minimum and maximum
290
    allowed values.
291
292
    \sa OutOfBoundsPolicy
293
*/
294
295
/*!
296
    \enum QPageLayout::OutOfBoundsPolicy
297
    \since 6.8
298
299
    Defines the policy for margins that are out of bounds
300
301
    \value Reject The margins must fall within the minimum and maximum values,
302
                  otherwise they will be rejected.
303
    \value Clamp  The margins are clamped between the minimum and maximum
304
                  values to ensure they are valid.
305
306
    \note The policy has no effect in \l{QPageLayout::Mode}{FullPageMode},
307
          where all margins are accepted.
308
*/
309
310
/*!
311
    Creates an invalid QPageLayout.
312
*/
313
314
QPageLayout::QPageLayout()
315
0
    : QPageLayout(QPageSize(), QPageLayout::Landscape, QMarginsF())
316
0
{
317
0
}
318
319
/*!
320
    Creates a QPageLayout with the given \a pageSize, \a orientation and
321
    \a margins in the given \a units.
322
323
    Optionally define the minimum allowed margins \a minMargins, e.g. the minimum
324
    margins able to be printed by a physical print device.
325
326
    The constructed QPageLayout will be in StandardMode.
327
328
    The \a margins given will be clamped to the minimum margins and the maximum
329
    margins allowed by the page size.
330
*/
331
332
QPageLayout::QPageLayout(const QPageSize &pageSize, Orientation orientation,
333
                         const QMarginsF &margins, Unit units,
334
                         const QMarginsF &minMargins)
335
0
    : d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins))
336
0
{
337
0
}
338
339
/*!
340
    Copy constructor, copies \a other to this.
341
*/
342
343
QPageLayout::QPageLayout(const QPageLayout &other)
344
0
    : d(other.d)
345
0
{
346
0
}
347
348
/*!
349
    Destroys the page layout.
350
*/
351
352
QPageLayout::~QPageLayout()
353
0
{
354
0
}
355
356
/*!
357
    Assignment operator, assigns \a other to this.
358
*/
359
360
QPageLayout &QPageLayout::operator=(const QPageLayout &other)
361
0
{
362
0
    d = other.d;
363
0
    return *this;
364
0
}
365
366
/*!
367
    \fn void QPageLayout::swap(QPageLayout &other)
368
    \memberswap{page layout}
369
*/
370
371
/*!
372
    \fn QPageLayout &QPageLayout::operator=(QPageLayout &&other)
373
374
    Move-assigns \a other to this QPageLayout instance, transferring the
375
    ownership of the managed pointer to this instance.
376
*/
377
378
/*!
379
    \fn bool QPageLayout::operator==(const QPageLayout &lhs, const QPageLayout &rhs)
380
381
    Returns \c true if page layout \a lhs is equal to page layout \a rhs,
382
    i.e. if all the attributes are exactly equal.
383
384
    Note that this is a strict equality, especially for page size where the
385
    QPageSize ID, name and size must exactly match, and the margins where the
386
    units must match.
387
388
    \sa QPageLayout::isEquivalentTo()
389
*/
390
391
/*!
392
    \fn bool QPageLayout::operator!=(const QPageLayout &lhs, const QPageLayout &rhs)
393
394
    Returns \c true if page layout \a lhs is not equal to page layout \a rhs,
395
    i.e. if any of the attributes differ.
396
397
    Note that this is a strict equality, especially for page size where the
398
    QPageSize ID, name and size must exactly match, and the margins where the
399
    units must match.
400
401
    \sa QPageLayout::isEquivalentTo()
402
*/
403
404
/*!
405
    \internal
406
*/
407
bool QPageLayout::equals(const QPageLayout &other) const
408
0
{
409
0
    return d == other.d || *d == *other.d;
410
0
}
411
412
413
/*!
414
    Returns \c true if this page layout is equivalent to the \a other page layout,
415
    i.e. if the page has the same size, margins and orientation.
416
*/
417
418
bool QPageLayout::isEquivalentTo(const QPageLayout &other) const
419
0
{
420
0
    return d && other.d && d->isEquivalentTo(*other.d);
421
0
}
422
423
/*!
424
    Returns \c true if this page layout is valid.
425
*/
426
427
bool QPageLayout::isValid() const
428
0
{
429
0
    return d->isValid();
430
0
}
431
432
/*!
433
    Sets a page layout mode to \a mode.
434
*/
435
436
void QPageLayout::setMode(Mode mode)
437
0
{
438
0
    d.detach();
439
0
    d->m_mode = mode;
440
0
}
441
442
/*!
443
    Returns the page layout mode.
444
*/
445
446
QPageLayout::Mode QPageLayout::mode() const
447
0
{
448
0
    return d->m_mode;
449
0
}
450
451
/*!
452
    Sets the page size of the page layout to \a pageSize.
453
454
    Optionally define the minimum allowed margins \a minMargins, e.g. the minimum
455
    margins able to be printed by a physical print device, otherwise the
456
    minimum margins will default to 0.
457
458
    If StandardMode is set then the existing margins will be clamped
459
    to the new minimum margins and the maximum margins allowed by the page size.
460
    If FullPageMode is set then the existing margins will be unchanged.
461
*/
462
463
void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins)
464
0
{
465
0
    if (!pageSize.isValid())
466
0
        return;
467
0
    d.detach();
468
0
    d->m_pageSize = pageSize;
469
0
    d->m_fullSize = d->fullSizeUnits(d->m_units);
470
0
    d->setDefaultMargins(minMargins);
471
0
}
472
473
/*!
474
    Returns the page size of the page layout.
475
476
    Note that the QPageSize is always defined in a Portrait orientation.  To
477
    obtain a size that takes the set orientation into account you must use
478
    fullRect().
479
*/
480
481
QPageSize QPageLayout::pageSize() const
482
0
{
483
0
    return d->m_pageSize;
484
0
}
485
486
/*!
487
    Sets the page orientation of the page layout to \a orientation.
488
489
    Changing the orientation does not affect the current margins or
490
    the minimum margins.
491
*/
492
493
void QPageLayout::setOrientation(Orientation orientation)
494
0
{
495
0
    if (orientation != d->m_orientation) {
496
0
        d.detach();
497
0
        d->m_orientation = orientation;
498
0
        d->m_fullSize = d->fullSizeUnits(d->m_units);
499
        // Adust the max margins to reflect change in max page size
500
0
        const qreal change = d->m_fullSize.width() - d->m_fullSize.height();
501
0
        d->m_maxMargins.setLeft(d->m_maxMargins.left() + change);
502
0
        d->m_maxMargins.setRight(d->m_maxMargins.right() + change);
503
0
        d->m_maxMargins.setTop(d->m_maxMargins.top() - change);
504
0
        d->m_maxMargins.setBottom(d->m_maxMargins.bottom() - change);
505
0
    }
506
0
}
507
508
/*!
509
    Returns the page orientation of the page layout.
510
*/
511
512
QPageLayout::Orientation QPageLayout::orientation() const
513
0
{
514
0
    return d->m_orientation;
515
0
}
516
517
/*!
518
    Sets the \a units used to define the page layout.
519
*/
520
521
void QPageLayout::setUnits(Unit units)
522
0
{
523
0
    if (units != d->m_units) {
524
0
        d.detach();
525
0
        d->m_margins = qt_convertMargins(d->m_margins, d->m_units, units);
526
0
        d->m_minMargins = qt_convertMargins(d->m_minMargins, d->m_units, units);
527
0
        d->m_maxMargins = qt_convertMargins(d->m_maxMargins, d->m_units, units);
528
0
        d->m_units = units;
529
0
        d->m_fullSize = d->fullSizeUnits(d->m_units);
530
0
    }
531
0
}
532
533
/*!
534
    Returns the units the page layout is currently defined in.
535
*/
536
537
QPageLayout::Unit QPageLayout::units() const
538
0
{
539
0
    return d->m_units;
540
0
}
541
542
/*!
543
    Sets the page margins of the page layout to \a margins.
544
    Returns true if the margins were successfully set.
545
546
    The units used are those currently defined for the layout.  To use different
547
    units then call setUnits() first.
548
549
    Since Qt 6.8, the optional \a outOfBoundsPolicy can be used to specify how
550
    margins that are out of bounds are handled.
551
552
    \sa margins(), units()
553
*/
554
555
bool QPageLayout::setMargins(const QMarginsF &margins, OutOfBoundsPolicy outOfBoundsPolicy)
556
0
{
557
0
    if (d->m_mode == FullPageMode) {
558
0
        if (margins != d->m_margins) {
559
0
            d.detach();
560
0
            d->m_margins = margins;
561
0
        }
562
0
        return true;
563
0
    }
564
565
0
    if (outOfBoundsPolicy == OutOfBoundsPolicy::Clamp) {
566
0
        const QMarginsF clampedMargins = d->clampMargins(margins);
567
0
        if (clampedMargins != d->m_margins) {
568
0
            d.detach();
569
0
            d->m_margins = clampedMargins;
570
0
        }
571
0
        return true;
572
0
    }
573
574
0
    if (margins.left() >= d->m_minMargins.left()
575
0
        && margins.right() >= d->m_minMargins.right()
576
0
        && margins.top() >= d->m_minMargins.top()
577
0
        && margins.bottom() >= d->m_minMargins.bottom()
578
0
        && margins.left() <= d->m_maxMargins.left()
579
0
        && margins.right() <= d->m_maxMargins.right()
580
0
        && margins.top() <= d->m_maxMargins.top()
581
0
        && margins.bottom() <= d->m_maxMargins.bottom()) {
582
0
        if (margins != d->m_margins) {
583
0
            d.detach();
584
0
            d->m_margins = margins;
585
0
        }
586
0
        return true;
587
0
    }
588
589
0
    return false;
590
0
}
591
592
/*!
593
    Sets the left page margin of the page layout to \a leftMargin.
594
    Returns true if the margin was successfully set.
595
596
    The units used are those currently defined for the layout.  To use different
597
    units call setUnits() first.
598
599
    Since Qt 6.8, the optional \a outOfBoundsPolicy can be used to specify how
600
    margins that are out of bounds are handled.
601
602
    \sa setMargins(), margins()
603
*/
604
605
bool QPageLayout::setLeftMargin(qreal leftMargin, OutOfBoundsPolicy outOfBoundsPolicy)
606
0
{
607
0
    if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
608
0
        leftMargin = qBound(d->m_minMargins.left(), leftMargin, d->m_maxMargins.left());
609
610
0
    if (QtPrivate::fuzzyCompare(leftMargin, d->m_margins.left()))
611
0
        return true;
612
613
0
    if (d->m_mode == FullPageMode
614
0
        || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) {
615
0
        d.detach();
616
0
        d->m_margins.setLeft(leftMargin);
617
0
        return true;
618
0
    }
619
620
0
    return false;
621
0
}
622
623
/*!
624
    Sets the right page margin of the page layout to \a rightMargin.
625
    Returns true if the margin was successfully set.
626
627
    The units used are those currently defined for the layout.  To use different
628
    units call setUnits() first.
629
630
    Since Qt 6.8, the optional \a outOfBoundsPolicy can be used to specify how
631
    margins that are out of bounds are handled.
632
633
    \sa setMargins(), margins()
634
*/
635
636
bool QPageLayout::setRightMargin(qreal rightMargin, OutOfBoundsPolicy outOfBoundsPolicy)
637
0
{
638
0
    if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
639
0
        rightMargin = qBound(d->m_minMargins.right(), rightMargin, d->m_maxMargins.right());
640
641
0
    if (QtPrivate::fuzzyCompare(rightMargin, d->m_margins.right()))
642
0
        return true;
643
644
0
    if (d->m_mode == FullPageMode
645
0
        || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) {
646
0
        d.detach();
647
0
        d->m_margins.setRight(rightMargin);
648
0
        return true;
649
0
    }
650
651
0
    return false;
652
0
}
653
654
/*!
655
    Sets the top page margin of the page layout to \a topMargin.
656
    Returns true if the margin was successfully set.
657
658
    The units used are those currently defined for the layout.  To use different
659
    units call setUnits() first.
660
661
    Since Qt 6.8, the optional \a outOfBoundsPolicy can be used to specify how
662
    margins that are out of bounds are handled.
663
664
    \sa setMargins(), margins()
665
*/
666
667
bool QPageLayout::setTopMargin(qreal topMargin, OutOfBoundsPolicy outOfBoundsPolicy)
668
0
{
669
0
    if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
670
0
        topMargin = qBound(d->m_minMargins.top(), topMargin, d->m_maxMargins.top());
671
672
0
    if (QtPrivate::fuzzyCompare(topMargin, d->m_margins.top()))
673
0
        return true;
674
675
0
    if (d->m_mode == FullPageMode
676
0
        || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) {
677
0
        d.detach();
678
0
        d->m_margins.setTop(topMargin);
679
0
        return true;
680
0
    }
681
682
0
    return false;
683
0
}
684
685
/*!
686
    Sets the bottom page margin of the page layout to \a bottomMargin.
687
    Returns true if the margin was successfully set.
688
689
    The units used are those currently defined for the layout.  To use different
690
    units call setUnits() first.
691
692
    Since Qt 6.8, the optional \a outOfBoundsPolicy can be used to specify how
693
    margins that are out of bounds are handled.
694
695
    \sa setMargins(), margins()
696
*/
697
698
bool QPageLayout::setBottomMargin(qreal bottomMargin, OutOfBoundsPolicy outOfBoundsPolicy)
699
0
{
700
0
    if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
701
0
        bottomMargin = qBound(d->m_minMargins.bottom(), bottomMargin, d->m_maxMargins.bottom());
702
703
0
    if (QtPrivate::fuzzyCompare(bottomMargin, d->m_margins.bottom()))
704
0
        return true;
705
706
0
    if (d->m_mode == FullPageMode
707
0
        || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) {
708
0
        d.detach();
709
0
        d->m_margins.setBottom(bottomMargin);
710
0
        return true;
711
0
    }
712
713
0
    return false;
714
0
}
715
716
/*!
717
    Returns the margins of the page layout using the currently set units.
718
719
    \sa setMargins(), units()
720
*/
721
722
QMarginsF QPageLayout::margins() const
723
0
{
724
0
    return d->m_margins;
725
0
}
726
727
/*!
728
    Returns the margins of the page layout using the requested \a units.
729
730
    \sa setMargins(), margins()
731
*/
732
733
QMarginsF QPageLayout::margins(Unit units) const
734
0
{
735
0
    return d->margins(units);
736
0
}
737
738
/*!
739
    Returns the margins of the page layout in Postscript Points (1/72 of an inch).
740
741
    \sa setMargins(), margins()
742
*/
743
744
QMargins QPageLayout::marginsPoints() const
745
0
{
746
0
    return d->marginsPoints().toMargins();
747
0
}
748
749
/*!
750
    Returns the margins of the page layout in device pixels for the given \a resolution.
751
752
    \sa setMargins()
753
*/
754
755
QMargins QPageLayout::marginsPixels(int resolution) const
756
0
{
757
0
    return d->marginsPixels(resolution);
758
0
}
759
760
/*!
761
    Sets the minimum page margins of the page layout to \a minMargins.
762
763
    It is not recommended to override the default values set for a page size
764
    as this may be the minimum printable area for a physical print device.
765
766
    If the StandardMode mode is set then the existing margins will be clamped
767
    to the new \a minMargins and the maximum allowed by the page size.  If the
768
    FullPageMode is set then the existing margins will be unchanged.
769
770
    \sa minimumMargins(), setMargins()
771
*/
772
773
void QPageLayout::setMinimumMargins(const QMarginsF &minMargins)
774
0
{
775
0
    d.detach();
776
0
    d->setDefaultMargins(minMargins);
777
0
}
778
779
/*!
780
    Returns the minimum margins of the page layout.
781
782
    \sa setMinimumMargins(), maximumMargins()
783
*/
784
785
QMarginsF QPageLayout::minimumMargins() const
786
0
{
787
0
    return d->m_minMargins;
788
0
}
789
790
/*!
791
    Returns the maximum margins that would be applied if the page layout was
792
    in StandardMode.
793
794
    The maximum margins allowed are calculated as the full size of the page
795
    minus the minimum margins set. For example, if the page width is 100 points
796
    and the minimum right margin is 10 points, then the maximum left margin
797
    will be 90 points.
798
799
    \sa setMinimumMargins(), minimumMargins()
800
*/
801
802
QMarginsF QPageLayout::maximumMargins() const
803
0
{
804
0
    return d->m_maxMargins;
805
0
}
806
807
/*!
808
    Returns the full page rectangle in the current layout units.
809
810
    The page rectangle takes into account the page size and page orientation,
811
    but not the page margins.
812
813
    \sa paintRect(), units()
814
*/
815
816
QRectF QPageLayout::fullRect() const
817
0
{
818
0
    return isValid() ? d->fullRect() : QRect();
819
0
}
820
821
/*!
822
    Returns the full page rectangle in the required \a units.
823
824
    The page rectangle takes into account the page size and page orientation,
825
    but not the page margins.
826
827
    \sa paintRect()
828
*/
829
830
QRectF QPageLayout::fullRect(Unit units) const
831
0
{
832
0
    return isValid() ? d->fullRect(units) : QRect();
833
0
}
834
835
/*!
836
    Returns the full page rectangle in Postscript Points (1/72 of an inch).
837
838
    The page rectangle takes into account the page size and page orientation,
839
    but not the page margins.
840
841
    \sa paintRect()
842
*/
843
844
QRect QPageLayout::fullRectPoints() const
845
0
{
846
0
    return isValid() ? d->fullRectPoints() : QRect();
847
0
}
848
849
/*!
850
    Returns the full page rectangle in device pixels for the given \a resolution.
851
852
    The page rectangle takes into account the page size and page orientation,
853
    but not the page margins.
854
855
    \sa paintRect()
856
*/
857
858
QRect QPageLayout::fullRectPixels(int resolution) const
859
0
{
860
0
    return isValid() ? d->fullRectPixels(resolution) : QRect();
861
0
}
862
863
/*!
864
    Returns the page rectangle in the current layout units.
865
866
    The paintable rectangle takes into account the page size, orientation
867
    and margins.
868
869
    If the FullPageMode mode is set then the fullRect() is returned and
870
    the margins must be manually managed.
871
*/
872
873
QRectF QPageLayout::paintRect() const
874
0
{
875
0
    return isValid() ? d->paintRect() : QRectF();
876
0
}
877
878
/*!
879
    Returns the page rectangle in the required \a units.
880
881
    The paintable rectangle takes into account the page size, orientation
882
    and margins.
883
884
    If the FullPageMode mode is set then the fullRect() is returned and
885
    the margins must be manually managed.
886
*/
887
888
QRectF QPageLayout::paintRect(Unit units) const
889
0
{
890
0
    if (!isValid())
891
0
        return QRectF();
892
0
    if (units == d->m_units)
893
0
        return d->paintRect();
894
0
    return d->m_mode == FullPageMode ? d->fullRect(units)
895
0
                                                  : d->fullRect(units) - d->margins(units);
896
0
}
897
898
/*!
899
    Returns the paintable rectangle in rounded Postscript Points (1/72 of an inch).
900
901
    The paintable rectangle takes into account the page size, orientation
902
    and margins.
903
904
    If the FullPageMode mode is set then the fullRect() is returned and
905
    the margins must be manually managed.
906
*/
907
908
QRect QPageLayout::paintRectPoints() const
909
0
{
910
0
    if (!isValid())
911
0
        return QRect();
912
0
    return d->m_mode == FullPageMode ? d->fullRectPoints()
913
0
                                                  : d->fullRectPoints() - d->marginsPoints().toMargins();
914
0
}
915
916
/*!
917
    Returns the paintable rectangle in rounded device pixels for the given \a resolution.
918
919
    The paintable rectangle takes into account the page size, orientation
920
    and margins.
921
922
    If the FullPageMode mode is set then the fullRect() is returned and
923
    the margins must be manually managed.
924
*/
925
926
QRect QPageLayout::paintRectPixels(int resolution) const
927
0
{
928
0
    if (!isValid())
929
0
        return QRect();
930
0
    return d->m_mode == FullPageMode ? d->fullRectPixels(resolution)
931
0
                                                  : d->fullRectPixels(resolution) - d->marginsPixels(resolution);
932
0
}
933
934
#ifndef QT_NO_DEBUG_STREAM
935
QDebug operator<<(QDebug dbg, const QPageLayout &layout)
936
0
{
937
0
    QDebugStateSaver saver(dbg);
938
0
    dbg.nospace();
939
0
    dbg.noquote();
940
0
    dbg << "QPageLayout(";
941
0
    if (layout.isValid()) {
942
0
        const QMarginsF margins = layout.margins();
943
0
        dbg << '"' << layout.pageSize().name() << "\", "
944
0
            << (layout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape")
945
0
            << ", l:" << margins.left() << " r:" << margins.right() << " t:"
946
0
            << margins.top() << " b:" << margins.bottom() << ' ';
947
0
        switch (layout.units()) {
948
0
        case QPageLayout::Millimeter:
949
0
            dbg << "mm";
950
0
            break;
951
0
        case QPageLayout::Point:
952
0
            dbg << "pt";
953
0
            break;
954
0
        case QPageLayout::Inch:
955
0
            dbg << "in";
956
0
            break;
957
0
        case QPageLayout::Pica:
958
0
            dbg << "pc";
959
0
            break;
960
0
        case QPageLayout::Didot:
961
0
            dbg << "DD";
962
0
            break;
963
0
        case QPageLayout::Cicero:
964
0
            dbg << "CC";
965
0
            break;
966
0
        }
967
0
    }
968
0
    dbg << ')';
969
0
    return dbg;
970
0
}
971
#endif
972
973
QT_END_NAMESPACE