Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qprintengine_pdf.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
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
6
7#ifndef QT_NO_PRINTER
8
9#include <qiodevice.h>
10#include <qfile.h>
11#include <qdebug.h>
12#include <qbuffer.h>
13#include "qprinterinfo.h"
14#include <QtGui/qpagelayout.h>
15
16#ifdef Q_OS_UNIX
17#include "private/qcore_unix_p.h" // overrides QT_OPEN
18#endif
19
20#ifdef Q_OS_WIN
21#include <io.h> // _close.
22#endif
23
25
26QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m, QPdfEngine::PdfVersion version)
27 : QPdfEngine(*new QPdfPrintEnginePrivate(m))
28{
29 state = QPrinter::Idle;
30
31 setPdfVersion(version);
32}
33
34QPdfPrintEngine::QPdfPrintEngine(QPdfPrintEnginePrivate &p)
35 : QPdfEngine(p)
36{
37 state = QPrinter::Idle;
38}
39
40QPdfPrintEngine::~QPdfPrintEngine()
41{
42}
43
44bool QPdfPrintEngine::begin(QPaintDevice *pdev)
45{
46 Q_D(QPdfPrintEngine);
47
48 if (!d->openPrintDevice()) {
49 state = QPrinter::Error;
50 return false;
51 }
52 state = QPrinter::Active;
53
54 return QPdfEngine::begin(pdev);
55}
56
57bool QPdfPrintEngine::end()
58{
59 Q_D(QPdfPrintEngine);
60
61 QPdfEngine::end();
62
63 d->closePrintDevice();
64 state = QPrinter::Idle;
65
66 return true;
67}
68
69bool QPdfPrintEngine::newPage()
70{
71 return QPdfEngine::newPage();
72}
73
74int QPdfPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
75{
76 return QPdfEngine::metric(m);
77}
78
79void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
80{
81 Q_D(QPdfPrintEngine);
82
83 switch (int(key)) {
84
85 // The following keys are properties or derived values and so cannot be set
86 case PPK_PageRect:
87 break;
88 case PPK_PaperRect:
89 break;
90 case PPK_PaperSources:
91 break;
92 case PPK_SupportsMultipleCopies:
93 break;
94 case PPK_SupportedResolutions:
95 break;
96
97 // The following keys are settings that are unsupported by the PDF PrintEngine
98 case PPK_CustomBase:
99 break;
100 case PPK_Duplex:
101 break;
102
103 // The following keys are properties and settings that are supported by the PDF PrintEngine
104 case PPK_CollateCopies:
105 d->collate = value.toBool();
106 break;
107 case PPK_ColorMode:
108 switch (QPrinter::ColorMode(value.toInt())) {
109 case QPrinter::GrayScale:
110 d->colorModel = QPdfEngine::ColorModel::Grayscale;
111 break;
112 case QPrinter::Color:
113 d->colorModel = QPdfEngine::ColorModel::Auto;
114 break;
115 }
116 break;
117 case PPK_Creator:
118 d->creator = value.toString();
119 break;
120 case PPK_DocumentName:
121 d->title = value.toString();
122 break;
123 case PPK_FullPage:
124 if (value.toBool())
125 d->m_pageLayout.setMode(QPageLayout::FullPageMode);
126 else
127 d->m_pageLayout.setMode(QPageLayout::StandardMode);
128 break;
129 case PPK_CopyCount:
130 case PPK_NumberOfCopies:
131 d->copies = value.toInt();
132 break;
133 case PPK_Orientation:
134 d->m_pageLayout.setOrientation(QPageLayout::Orientation(value.toInt()));
135 break;
136 case PPK_OutputFileName:
137 d->outputFileName = value.toString();
138 break;
139 case PPK_PageOrder:
140 d->pageOrder = QPrinter::PageOrder(value.toInt());
141 break;
142 case PPK_PageSize: {
143 QPageSize pageSize = QPageSize(QPageSize::PageSizeId(value.toInt()));
144 if (pageSize.isValid())
145 d->m_pageLayout.setPageSize(pageSize);
146 break;
147 }
148 case PPK_PaperName: {
149 QString name = value.toString();
150 for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
151 QPageSize pageSize = QPageSize(QPageSize::PageSizeId(i));
152 if (name == pageSize.name()) {
153 d->m_pageLayout.setPageSize(pageSize);
154 break;
155 }
156 }
157 break;
158 }
159 case PPK_WindowsPageSize:
160 d->m_pageLayout.setPageSize(QPageSize(QPageSize::id(value.toInt())));
161 break;
162 case PPK_PaperSource:
163 d->paperSource = QPrinter::PaperSource(value.toInt());
164 break;
165 case PPK_PrinterName:
166 d->printerName = value.toString();
167 break;
168 case PPK_PrinterProgram:
169 d->printProgram = value.toString();
170 break;
171 case PPK_Resolution:
172 d->resolution = value.toInt();
173 break;
174 case PPK_SelectionOption:
175 d->selectionOption = value.toString();
176 break;
177 case PPK_FontEmbedding:
178 d->embedFonts = value.toBool();
179 break;
180 case PPK_CustomPaperSize:
181 d->m_pageLayout.setPageSize(QPageSize(value.toSizeF(), QPageSize::Point));
182 break;
183 case PPK_PageMargins: {
184 QList<QVariant> margins(value.toList());
185 Q_ASSERT(margins.size() == 4);
186 d->m_pageLayout.setUnits(QPageLayout::Point);
187 d->m_pageLayout.setMargins(QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(),
188 margins.at(2).toReal(), margins.at(3).toReal()),
189 QPageLayout::OutOfBoundsPolicy::Clamp);
190 break;
191 }
192 case PPK_QPageSize: {
193 QPageSize pageSize = qvariant_cast<QPageSize>(value);
194 if (pageSize.isValid())
195 d->m_pageLayout.setPageSize(pageSize);
196 break;
197 }
198 case PPK_QPageMargins: {
199 auto pair = qvariant_cast<std::pair<QMarginsF, QPageLayout::Unit>>(value);
200 d->m_pageLayout.setUnits(pair.second);
201 d->m_pageLayout.setMargins(pair.first, QPageLayout::OutOfBoundsPolicy::Clamp);
202 break;
203 }
204 case PPK_QPageLayout: {
205 QPageLayout pageLayout = qvariant_cast<QPageLayout>(value);
206 if (pageLayout.isValid())
207 d->m_pageLayout = pageLayout;
208 break;
209 }
210 // No default so that compiler will complain if new keys added and not handled in this engine
211 }
212}
213
214QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
215{
216 Q_D(const QPdfPrintEngine);
217
218 QVariant ret;
219 switch (int(key)) {
220
221 // The following keys are settings that are unsupported by the PDF PrintEngine
222 // Return sensible default values to ensure consistent behavior across platforms
223 case PPK_CustomBase:
224 case PPK_Duplex:
225 // Special case, leave null
226 break;
227
228 // The following keys are properties and settings that are supported by the PDF PrintEngine
229 case PPK_CollateCopies:
230 ret = d->collate;
231 break;
232 case PPK_ColorMode:
233 ret = d->printerColorMode();
234 break;
235 case PPK_Creator:
236 ret = d->creator;
237 break;
238 case PPK_DocumentName:
239 ret = d->title;
240 break;
241 case PPK_FullPage:
242 ret = d->m_pageLayout.mode() == QPageLayout::FullPageMode;
243 break;
244 case PPK_CopyCount:
245 ret = d->copies;
246 break;
247 case PPK_SupportsMultipleCopies:
248 ret = false;
249 break;
250 case PPK_NumberOfCopies:
251 ret = d->copies;
252 break;
253 case PPK_Orientation:
254 ret = d->m_pageLayout.orientation();
255 break;
256 case PPK_OutputFileName:
257 ret = d->outputFileName;
258 break;
259 case PPK_PageOrder:
260 ret = d->pageOrder;
261 break;
262 case PPK_PageSize:
263 ret = d->m_pageLayout.pageSize().id();
264 break;
265 case PPK_PaperName:
266 ret = d->m_pageLayout.pageSize().name();
267 break;
268 case PPK_WindowsPageSize:
269 ret = d->m_pageLayout.pageSize().windowsId();
270 break;
271 case PPK_PaperSource:
272 ret = d->paperSource;
273 break;
274 case PPK_PrinterName:
275 ret = d->printerName;
276 break;
277 case PPK_PrinterProgram:
278 ret = d->printProgram;
279 break;
280 case PPK_Resolution:
281 ret = d->resolution;
282 break;
283 case PPK_SupportedResolutions:
284 ret = QList<QVariant>() << 72;
285 break;
286 case PPK_PaperRect:
287 ret = d->m_pageLayout.fullRectPixels(d->resolution);
288 break;
289 case PPK_PageRect:
290 ret = d->m_pageLayout.paintRectPixels(d->resolution);
291 break;
292 case PPK_SelectionOption:
293 ret = d->selectionOption;
294 break;
295 case PPK_FontEmbedding:
296 ret = d->embedFonts;
297 break;
298 case PPK_CustomPaperSize:
299 ret = d->m_pageLayout.fullRectPoints().size();
300 break;
301 case PPK_PageMargins: {
302 QList<QVariant> list;
303 QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Point);
304 list << margins.left() << margins.top() << margins.right() << margins.bottom();
305 ret = list;
306 break;
307 }
308 case PPK_QPageSize:
309 ret.setValue(d->m_pageLayout.pageSize());
310 break;
311 case PPK_QPageMargins: {
312 std::pair<QMarginsF, QPageLayout::Unit> pair(d->m_pageLayout.margins(), d->m_pageLayout.units());
313 ret.setValue(pair);
314 break;
315 }
316 case PPK_QPageLayout:
317 ret.setValue(d->m_pageLayout);
318 break;
319 // No default so that compiler will complain if new keys added and not handled in this engine
320 }
321 return ret;
322}
323
324
325bool QPdfPrintEnginePrivate::openPrintDevice()
326{
327 if (outDevice)
328 return false;
329
330 if (!outputFileName.isEmpty()) {
331 QFile *file = new QFile(outputFileName);
332 if (! file->open(QFile::WriteOnly|QFile::Truncate)) {
333 delete file;
334 return false;
335 }
336 outDevice = file;
337 }
338
339 return true;
340}
341
342void QPdfPrintEnginePrivate::closePrintDevice()
343{
344 if (outDevice) {
345 outDevice->close();
346 if (fd >= 0)
347 #if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
348 ::_close(fd);
349 #else
350 ::close(fd);
351 #endif
352 fd = -1;
353 delete outDevice;
354 outDevice = nullptr;
355 }
356}
357
358
359
360QPdfPrintEnginePrivate::QPdfPrintEnginePrivate(QPrinter::PrinterMode m)
361 : QPdfEnginePrivate(),
362 collate(true),
363 copies(1),
364 pageOrder(QPrinter::FirstPageFirst),
365 paperSource(QPrinter::Auto),
366 fd(-1)
367{
368 resolution = 72;
369 if (m == QPrinter::HighResolution)
370 resolution = 1200;
371 else if (m == QPrinter::ScreenResolution)
372 resolution = qt_defaultDpi();
373}
374
375QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate()
376{
377}
378
379QPrinter::ColorMode QPdfPrintEnginePrivate::printerColorMode() const
380{
381 switch (colorModel) {
382 case QPdfEngine::ColorModel::RGB:
383 case QPdfEngine::ColorModel::CMYK:
384 case QPdfEngine::ColorModel::Auto:
385 return QPrinter::Color;
386 case QPdfEngine::ColorModel::Grayscale:
387 return QPrinter::GrayScale;
388 }
389
390 Q_UNREACHABLE();
391 return QPrinter::Color;
392}
393
394
395QT_END_NAMESPACE
396
397#endif // QT_NO_PRINTER