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 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#include <qpdfwriter.h>
41
42#ifndef QT_NO_PDF
43
44#include "qpagedpaintdevice_p.h"
45#include <QtCore/private/qobject_p.h>
46#include "private/qpdf_p.h"
47#include <QtCore/qfile.h>
48
49QT_BEGIN_NAMESPACE
50
51class QPdfWriterPrivate : public QObjectPrivate
52{
53public:
54 QPdfWriterPrivate()
55 : QObjectPrivate()
56 {
57 engine = new QPdfEngine();
58 output = 0;
59 pdfVersion = QPdfWriter::PdfVersion_1_4;
60 }
61 ~QPdfWriterPrivate()
62 {
63 delete engine;
64 delete output;
65 }
66
67 QPdfEngine *engine;
68 QFile *output;
69 QPdfWriter::PdfVersion pdfVersion;
70};
71
72class QPdfPagedPaintDevicePrivate : public QPagedPaintDevicePrivate
73{
74public:
75 QPdfPagedPaintDevicePrivate(QPdfWriterPrivate *d)
76 : QPagedPaintDevicePrivate(), pd(d)
77 {}
78
79 ~QPdfPagedPaintDevicePrivate()
80 {}
81
82 bool setPageLayout(const QPageLayout &newPageLayout) override
83 {
84 // Try to set the paint engine page layout
85 pd->engine->setPageLayout(newPageLayout);
86 return pageLayout().isEquivalentTo(newPageLayout);
87 }
88
89 bool setPageSize(const QPageSize &pageSize) override
90 {
91 // Try to set the paint engine page size
92 pd->engine->setPageSize(pageSize);
93 return pageLayout().pageSize().isEquivalentTo(pageSize);
94 }
95
96 bool setPageOrientation(QPageLayout::Orientation orientation) override
97 {
98 // Set the print engine value
99 pd->engine->setPageOrientation(orientation);
100 return pageLayout().orientation() == orientation;
101 }
102
103 bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override
104 {
105 // Try to set engine margins
106 pd->engine->setPageMargins(margins, units);
107 return pageLayout().margins() == margins && pageLayout().units() == units;
108 }
109
110 QPageLayout pageLayout() const override
111 {
112 return pd->engine->pageLayout();
113 }
114
115 QPdfWriterPrivate *pd;
116};
117
118/*! \class QPdfWriter
119 \inmodule QtGui
120
121 \brief The QPdfWriter class is a class to generate PDFs
122 that can be used as a paint device.
123
124 \ingroup painting
125
126 QPdfWriter generates PDF out of a series of drawing commands using QPainter.
127 The newPage() method can be used to create several pages.
128 */
129
130/*!
131 Constructs a PDF writer that will write the pdf to \a filename.
132 */
133QPdfWriter::QPdfWriter(const QString &filename)
134 : QObject(*new QPdfWriterPrivate),
135 QPagedPaintDevice(new QPdfPagedPaintDevicePrivate(d_func()))
136{
137 Q_D(QPdfWriter);
138
139 d->engine->setOutputFilename(filename);
140}
141
142/*!
143 Constructs a PDF writer that will write the pdf to \a device.
144 */
145QPdfWriter::QPdfWriter(QIODevice *device)
146 : QObject(*new QPdfWriterPrivate),
147 QPagedPaintDevice(new QPdfPagedPaintDevicePrivate(d_func()))
148{
149 Q_D(QPdfWriter);
150
151 d->engine->d_func()->outDevice = device;
152}
153
154/*!
155 Destroys the pdf writer.
156 */
157QPdfWriter::~QPdfWriter()
158{
159
160}
161
162/*!
163 \since 5.10
164
165 Sets the PDF version for this writer to \a version.
166
167 If \a version is the same value as currently set then no change will be made.
168*/
169void QPdfWriter::setPdfVersion(PdfVersion version)
170{
171 Q_D(QPdfWriter);
172
173 if (d->pdfVersion == version)
174 return;
175
176 d->pdfVersion = version;
177 d->engine->setPdfVersion(static_cast<QPdfEngine::PdfVersion>(static_cast<int>(version)));
178}
179
180/*!
181 \since 5.10
182
183 Returns the PDF version for this writer. The default is \c PdfVersion_1_4.
184*/
185QPdfWriter::PdfVersion QPdfWriter::pdfVersion() const
186{
187 Q_D(const QPdfWriter);
188 return d->pdfVersion;
189}
190
191/*!
192 Returns the title of the document.
193 */
194QString QPdfWriter::title() const
195{
196 Q_D(const QPdfWriter);
197 return d->engine->d_func()->title;
198}
199
200/*!
201 Sets the title of the document being created to \a title.
202 */
203void QPdfWriter::setTitle(const QString &title)
204{
205 Q_D(QPdfWriter);
206 d->engine->d_func()->title = title;
207}
208
209/*!
210 Returns the creator of the document.
211 */
212QString QPdfWriter::creator() const
213{
214 Q_D(const QPdfWriter);
215 return d->engine->d_func()->creator;
216}
217
218/*!
219 Sets the creator of the document to \a creator.
220 */
221void QPdfWriter::setCreator(const QString &creator)
222{
223 Q_D(QPdfWriter);
224 d->engine->d_func()->creator = creator;
225}
226
227/*!
228 \reimp
229 */
230QPaintEngine *QPdfWriter::paintEngine() const
231{
232 Q_D(const QPdfWriter);
233
234 return d->engine;
235}
236
237/*!
238 \since 5.3
239
240 Sets the PDF \a resolution in DPI.
241
242 This setting affects the coordinate system as returned by, for
243 example QPainter::viewport().
244
245 \sa resolution()
246*/
247
248void QPdfWriter::setResolution(int resolution)
249{
250 Q_D(const QPdfWriter);
251 if (resolution > 0)
252 d->engine->setResolution(resolution);
253}
254
255/*!
256 \since 5.3
257
258 Returns the resolution of the PDF in DPI.
259
260 \sa setResolution()
261*/
262
263int QPdfWriter::resolution() const
264{
265 Q_D(const QPdfWriter);
266 return d->engine->resolution();
267}
268
269// Defined in QPagedPaintDevice but non-virtual, add QPdfWriter specific doc here
270#ifdef Q_QDOC
271/*!
272 \fn bool QPdfWriter::setPageLayout(const QPageLayout &newPageLayout)
273 \since 5.3
274
275 Sets the PDF page layout to \a newPageLayout.
276
277 You should call this before calling QPainter::begin(), or immediately
278 before calling newPage() to apply the new page layout to a new page.
279 You should not call any painting methods between a call to setPageLayout()
280 and newPage() as the wrong paint metrics may be used.
281
282 Returns true if the page layout was successfully set to \a newPageLayout.
283
284 \sa pageLayout()
285*/
286
287/*!
288 \fn bool QPdfWriter::setPageSize(const QPageSize &pageSize)
289 \since 5.3
290
291 Sets the PDF page size to \a pageSize.
292
293 To get the current QPageSize use pageLayout().pageSize().
294
295 You should call this before calling QPainter::begin(), or immediately
296 before calling newPage() to apply the new page size to a new page.
297 You should not call any painting methods between a call to setPageSize()
298 and newPage() as the wrong paint metrics may be used.
299
300 Returns true if the page size was successfully set to \a pageSize.
301
302 \sa pageLayout()
303*/
304
305/*!
306 \fn bool QPdfWriter::setPageOrientation(QPageLayout::Orientation orientation)
307 \since 5.3
308
309 Sets the PDF page \a orientation.
310
311 The page orientation is used to define the orientation of the
312 page size when obtaining the page rect.
313
314 You should call this before calling QPainter::begin(), or immediately
315 before calling newPage() to apply the new orientation to a new page.
316 You should not call any painting methods between a call to setPageOrientation()
317 and newPage() as the wrong paint metrics may be used.
318
319 To get the current QPageLayout::Orientation use pageLayout().pageOrientation().
320
321 Returns true if the page orientation was successfully set to \a orientation.
322
323 \sa pageLayout()
324*/
325
326/*!
327 \fn bool QPdfWriter::setPageMargins(const QMarginsF &margins)
328 \since 5.3
329
330 Set the PDF page \a margins in the current page layout units.
331
332 You should call this before calling QPainter::begin(), or immediately
333 before calling newPage() to apply the new margins to a new page.
334 You should not call any painting methods between a call to setPageMargins()
335 and newPage() as the wrong paint metrics may be used.
336
337 To get the current page margins use pageLayout().pageMargins().
338
339 Returns true if the page margins were successfully set to \a margins.
340
341 \sa pageLayout()
342*/
343
344/*!
345 \fn bool QPdfWriter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
346 \since 5.3
347
348 Set the PDF page \a margins defined in the given \a units.
349
350 You should call this before calling QPainter::begin(), or immediately
351 before calling newPage() to apply the new margins to a new page.
352 You should not call any painting methods between a call to setPageMargins()
353 and newPage() as the wrong paint metrics may be used.
354
355 To get the current page margins use pageLayout().pageMargins().
356
357 Returns true if the page margins were successfully set to \a margins.
358
359 \sa pageLayout()
360*/
361
362/*!
363 \fn QPageLayout QPdfWriter::pageLayout() const
364 \since 5.3
365
366 Returns the current page layout. Use this method to access the current
367 QPageSize, QPageLayout::Orientation, QMarginsF, fullRect() and paintRect().
368
369 Note that you cannot use the setters on the returned object, you must either
370 call the individual QPdfWriter methods or use setPageLayout().
371
372 \sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins()
373*/
374#endif
375
376#if QT_DEPRECATED_SINCE(5, 14)
377QT_WARNING_PUSH
378QT_WARNING_DISABLE_DEPRECATED
379/*!
380 \reimp
381
382 \obsolete Use setPageSize(QPageSize(id)) instead
383
384 \sa setPageSize()
385*/
386
387void QPdfWriter::setPageSize(PageSize size)
388{
389 setPageSize(QPageSize(QPageSize::PageSizeId(size)));
390}
391
392/*!
393 \reimp
394
395 \obsolete Use setPageSize(QPageSize(size, QPageSize::Millimeter)) instead
396
397 \sa setPageSize()
398*/
399
400void QPdfWriter::setPageSizeMM(const QSizeF &size)
401{
402 setPageSize(QPageSize(size, QPageSize::Millimeter));
403}
404QT_WARNING_POP
405#endif
406
407/*!
408 \internal
409
410 Returns the metric for the given \a id.
411*/
412int QPdfWriter::metric(PaintDeviceMetric id) const
413{
414 Q_D(const QPdfWriter);
415 return d->engine->metric(id);
416}
417
418/*!
419 \reimp
420*/
421bool QPdfWriter::newPage()
422{
423 Q_D(QPdfWriter);
424
425 return d->engine->newPage();
426}
427
428
429#if QT_DEPRECATED_SINCE(5, 14)
430QT_WARNING_PUSH
431QT_WARNING_DISABLE_DEPRECATED
432/*!
433 \reimp
434
435 \obsolete Use setPageMargins(QMarginsF(l, t, r, b), QPageLayout::Millimeter) instead
436
437 \sa setPageMargins()
438 */
439void QPdfWriter::setMargins(const Margins &m)
440{
441 setPageMargins(QMarginsF(m.left, m.top, m.right, m.bottom), QPageLayout::Millimeter);
442}
443QT_WARNING_POP
444#endif
445
446QT_END_NAMESPACE
447
448#endif // QT_NO_PDF
449