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
qohospdfprintengine.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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
7#include <QByteArray>
8#include <QtCore/private/qohoslogger_p.h>
9#include <QtCore/qjsondocument.h>
10#include <QtCore/qjsonobject.h>
11#include <cstdint>
12#include <qpagesize.h>
13
14QT_BEGIN_NAMESPACE
15
16QTemporaryDir QOhosPdfPrintEngine::s_tempDir;
17
18QOhosPdfPrintEngine::QOhosPdfPrintEngine(QPrinter::PrinterMode mode, const QString &deviceId)
19 : QPdfPrintEngine(*new QOhosPdfPrintEnginePrivate(mode))
20 , m_deviceId(deviceId)
21{
22 setProperty(QPrintEngine::PPK_PrinterName, QVariant(deviceId));
23 updateUnsupportedPrinterParameters();
24}
25
27
28bool QOhosPdfPrintEngine::begin(QPaintDevice *pdev)
29{
30 auto __dbg = make_QCScopedDebug("QOhosPdfPrintEngine::begin");
31
32 if (isActive())
33 qOhosCritical(QtForOhos) << "QOhosPdfPrintEngine: Cannot print multiple documents at once.";
34
35 Q_D(QPdfPrintEngine);
36
37 d->outputFileName = s_tempDir.filePath(QStringLiteral("doc.pdf"));
38
39 qOhosDebug(QtForOhos) << "QOhosPdfPrintEngine: Printing to pdf file:" << d->outputFileName;
40
41 if (!d->openPrintDevice()) {
42 state = QPrinter::Error;
43 return false;
44 }
45 state = QPrinter::Active;
46
47 return QPdfEngine::begin(pdev);
48}
49
51{
52 auto __dbg = make_QCScopedDebug("QOhosPdfPrintEngine::end");
53
54 Q_D(QPdfPrintEngine);
55
56 QPdfEngine::end();
57 d->closePrintDevice();
58
59 if (!QFile::exists(d->outputFileName)) {
60 qOhosCritical(QtForOhos) << "QOhosPdfPrintEngine: output pdf doc" << d->outputFileName << "does not exist. Aborting";
61 return false;
62 }
63
64 QOhosNativePrint::PrinterInfo printerInfo{};
65 if (!QOhosNativePrint::queryPrinterInfo(m_deviceId, printerInfo)) {
66 qOhosCritical(QtForOhos) << "QOhosPdfPrintEngine: failed to retrieve printer info";
67 return false;
68 }
69
70 if (printerInfo.state == ::PRINTER_UNAVAILABLE) {
71 qOhosCritical(QtForOhos) << "QOhosPdfPrintEngine: printer is unavailable";
72 return false;
73 }
74
75 QFile f(d->outputFileName);
76 if (!f.open(QIODevice::ReadOnly)) {
77 qOhosCritical(QtForOhos) << "QOhosPdfPrintEngine: failed to open generated document";
78 return false;
79 }
80 int fd = f.handle();
81 if (fd == -1) {
82 qOhosCritical(QtForOhos) << "QOhosPdfPrintEngine: failed to obtain fd of pdf file";
83 return false;
84 }
85 qOhosDebug(QtForOhos) << "QOhosPdfPrintEngine: printing file" << d->outputFileName << "with fd:" << fd;
86
87 std::vector<std::uint32_t> fdList;
88 fdList.push_back(static_cast<std::uint32_t>(fd));
89
90 auto printerId = m_deviceId.toUtf8();
91 auto supportedPageSize
92 = QOhosPrintDevice(m_deviceId).supportedPageSize(d->m_pageLayout.pageSize());
93 QByteArray pageSizeId = supportedPageSize.key().toUtf8();
94 auto jobName = QPdfPrintEngine::property(PPK_DocumentName).toString().toUtf8();
95
96 Print_PrintJob printJob{};
97 printJob.jobName = jobName.data();
98 printJob.fdListCount = fdList.size();
99 printJob.fdList = fdList.data();
100 printJob.printerId = printerId.data();
101 printJob.resolution.horizontalDpi = static_cast<std::uint32_t>(d->resolution);
102 printJob.resolution.verticalDpi = static_cast<std::uint32_t>(d->resolution);
103 printJob.copyNumber = m_copies;
104 // FIXME: Use the actual settings, not the default ones.
105 printJob.pageSizeId = pageSizeId.data();
106 printJob.colorMode = nativeColorMode();
107 printJob.duplexMode = nativeDuplexMode();
108 printJob.orientationMode = nativeOrientationMode();
109
110 QJsonObject advancedOptions = {
111 {"isCollate", QPdfPrintEngine::property(PPK_CollateCopies).toBool()},
112 {"isReverse", QPdfPrintEngine::property(PPK_PageOrder).toInt() == QPrinter::LastPageFirst},
113 };
114 auto advancedOptionsJson = QJsonDocument(advancedOptions).toJson(QJsonDocument::Compact);
115 printJob.advancedOptions = advancedOptionsJson.data();
116
117 if (!QOhosNativePrint::startPrintJob(printJob)) {
118 qOhosCritical(QtForOhos) << "QOhosPdfPrintEngine: failed to start print job";
119 return false;
120 }
121
122 state = QPrinter::Idle;
123
124 return true;
125}
126
127void QOhosPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
128{
129 const QOhosPrintDevice printDevice(m_deviceId);
130 Q_D(QOhosPdfPrintEngine);
131
132 switch (key) {
133 case PPK_Duplex: {
134 auto requestedDuplexMode = QPrinter::DuplexMode(value.toInt());
135 if (printDevice.supportedDuplexModes().contains(static_cast<QPrint::DuplexMode>(requestedDuplexMode)))
136 m_duplexMode = requestedDuplexMode;
137 break;
138 }
139 case PPK_CustomPaperSize:
140 d->m_pageLayout.setPageSize(printDevice.supportedPageSize(value.toString()));
141 break;
142 case PPK_CopyCount:
143 case PPK_NumberOfCopies:
144 if (printDevice.supportsMultipleCopies())
145 m_copies = value.toInt();
146 break;
147 case PPK_ColorMode: {
148 auto requestedColorMode = QPrinter::ColorMode(value.toInt());
149 if (printDevice.supportedColorModes().contains(static_cast<QPrint::ColorMode>(requestedColorMode)))
150 QPdfPrintEngine::setProperty(key, value);
151 break;
152 }
153 default:
154 QPdfPrintEngine::setProperty(key, value);
155 break;
156 }
157}
158
159QVariant QOhosPdfPrintEngine::property(PrintEnginePropertyKey key) const
160{
161 switch (key) {
162 case PPK_Duplex:
163 return m_duplexMode;
164 case PPK_SupportsMultipleCopies:
165 return true;
166 case PPK_CopyCount:
167 case PPK_NumberOfCopies:
168 return m_copies;
169 default:
170 break;
171 }
172 return QPdfPrintEngine::property(key);
173}
174
175Print_DuplexMode QOhosPdfPrintEngine::nativeDuplexMode() const
176{
177 Q_D(const QOhosPdfPrintEngine);
178
179 switch (m_duplexMode) {
180 case QPrinter::DuplexNone:
181 return DUPLEX_MODE_ONE_SIDED;
182 case QPrinter::DuplexAuto:
183 return d->m_pageLayout.orientation() == QPageLayout::Landscape
184 ? DUPLEX_MODE_TWO_SIDED_SHORT_EDGE
185 : DUPLEX_MODE_TWO_SIDED_LONG_EDGE;
186 case QPrinter::DuplexLongSide:
187 return DUPLEX_MODE_TWO_SIDED_LONG_EDGE;
188 case QPrinter::DuplexShortSide:
189 return DUPLEX_MODE_TWO_SIDED_SHORT_EDGE;
190 }
191}
192
193Print_ColorMode QOhosPdfPrintEngine::nativeColorMode() const
194{
195 Q_D(const QOhosPdfPrintEngine);
196
197 if (d->colorModel == QPdfEngine::ColorModel::Grayscale)
198 return COLOR_MODE_MONOCHROME;
199 else
200 return COLOR_MODE_COLOR;
201}
202
203Print_OrientationMode QOhosPdfPrintEngine::nativeOrientationMode() const
204{
205 Q_D(const QOhosPdfPrintEngine);
206
207 switch (d->m_pageLayout.orientation()) {
208 case QPageLayout::Portrait:
209 return ORIENTATION_MODE_PORTRAIT;
210 case QPageLayout::Landscape:
211 return ORIENTATION_MODE_LANDSCAPE;
212 }
213}
214
215void QOhosPdfPrintEngine::updateUnsupportedPrinterParameters()
216{
217 Q_D(QOhosPdfPrintEngine);
218 const QOhosPrintDevice currentPrintDevice(m_deviceId);
219 auto currentColorMode = static_cast<QPrint::ColorMode>(property(PPK_ColorMode).toInt());
220 auto currentDuplexMode = static_cast<QPrint::DuplexMode>(m_duplexMode);
221 auto currentPageSize = d->m_pageLayout.pageSize();
222
223 if (!currentPrintDevice.supportedColorModes().contains(currentColorMode))
224 setProperty(PPK_ColorMode, QVariant(static_cast<int>(currentPrintDevice.defaultColorMode())));
225
226 if (!currentPrintDevice.supportedDuplexModes().contains(currentDuplexMode))
227 m_duplexMode = static_cast<QPrinter::DuplexMode>(currentPrintDevice.defaultDuplexMode());
228
229 d->m_pageLayout.setPageSize(currentPrintDevice.supportedPageSize(currentPageSize));
230
231 if (!currentPrintDevice.supportsMultipleCopies())
232 m_copies = 1;
233}
234
235QOhosPdfPrintEnginePrivate::QOhosPdfPrintEnginePrivate(QPrinter::PrinterMode m)
236 : QPdfPrintEnginePrivate(m)
237{
238}
239
241
242QT_END_NAMESPACE
bool begin(QPaintDevice *pdev) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
bool end() override
Reimplement this function to finish painting on the current paint device.
QVariant property(PrintEnginePropertyKey key) const override
Returns the print engine's property specified by key.
void setProperty(PrintEnginePropertyKey key, const QVariant &value) override
Sets the print engine's property specified by key to the given value.
~QOhosPdfPrintEngine() override