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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/printsupport/kernel/qprintengine_pdf.cpp