Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qpdfpagerenderer.cpp
Go to the documentation of this file.
1
// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
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
"qpdfpagerenderer.h"
5
6
#
include
<
private
/
qobject_p
.
h
>
7
#
include
<
QMutex
>
8
#
include
<
QPointer
>
9
#
include
<
QThread
>
10
11
QT_BEGIN_NAMESPACE
12
13
class
RenderWorker
:
public
QObject
14
{
15
Q_OBJECT
16
17
public
:
18
RenderWorker
();
19
~
RenderWorker
();
20
21
void
setDocument
(QPdfDocument *document);
22
23
public
Q_SLOTS
:
24
void
requestPage
(
quint64
requestId
,
int
page
,
QSize
imageSize
,
25
QPdfDocumentRenderOptions
options
);
26
27
Q_SIGNALS
:
28
void
pageRendered
(
int
page
,
QSize
imageSize
,
const
QImage
&
image
,
29
QPdfDocumentRenderOptions
options
,
quint64
requestId
);
30
31
private
:
32
QPointer<QPdfDocument> m_document;
33
QMutex m_mutex;
34
};
35
36
class
QPdfPageRendererPrivate
37
{
38
public
:
39
QPdfPageRendererPrivate
();
40
~
QPdfPageRendererPrivate
();
41
42
void
handleNextRequest
();
43
void
requestFinished
(
int
page, QSize imageSize,
const
QImage &image,
44
QPdfDocumentRenderOptions options, quint64 requestId);
45
46
QPdfPageRenderer
::
RenderMode
m_renderMode
=
QPdfPageRenderer
::
RenderMode
::
SingleThreaded
;
47
QPointer
<
QPdfDocument
>
m_document
;
48
49
struct
PageRequest
50
{
51
quint64
id
;
52
int
pageNumber
;
53
QSize
imageSize
;
54
QPdfDocumentRenderOptions
options
;
55
};
56
57
QList
<
PageRequest
>
m_requests
;
58
QList
<
PageRequest
>
m_pendingRequests
;
59
quint64
m_requestIdCounter
= 1;
60
61
QThread
*
m_renderThread
=
nullptr
;
62
QScopedPointer
<
RenderWorker
>
m_renderWorker
;
63
};
64
65
Q_DECLARE_TYPEINFO
(
QPdfPageRendererPrivate
::
PageRequest
,
Q_PRIMITIVE_TYPE
);
66
67
68
RenderWorker
::RenderWorker()
69
: m_document(
nullptr
)
70
{
71
}
72
73
RenderWorker
::~
RenderWorker
()
74
{
75
}
76
77
void
RenderWorker
::
setDocument
(QPdfDocument *document)
78
{
79
const
QMutexLocker locker(&m_mutex);
80
81
if
(m_document == document)
82
return
;
83
84
m_document = document;
85
}
86
87
void
RenderWorker
::requestPage(quint64 requestId,
int
pageNumber, QSize imageSize,
88
QPdfDocumentRenderOptions options)
89
{
90
const
QMutexLocker locker(&m_mutex);
91
92
if
(!m_document || m_document->status() != QPdfDocument::Status::Ready)
93
return
;
94
95
const
QImage image = m_document->render(pageNumber, imageSize, options);
96
97
emit pageRendered(pageNumber, imageSize, image, options, requestId);
98
}
99
100
QPdfPageRendererPrivate
::
QPdfPageRendererPrivate
() :
m_renderWorker
(
new
RenderWorker
) { }
101
102
QPdfPageRendererPrivate
::~
QPdfPageRendererPrivate
()
103
{
104
if
(m_renderThread) {
105
m_renderThread->quit();
106
m_renderThread->wait();
107
}
108
}
109
110
void
QPdfPageRendererPrivate
::
handleNextRequest
()
111
{
112
if
(m_requests.isEmpty())
113
return
;
114
115
const
PageRequest
request = m_requests.takeFirst();
116
m_pendingRequests.append(request);
117
118
QMetaObject::invokeMethod(m_renderWorker.data(),
"requestPage"
, Qt::QueuedConnection,
119
Q_ARG(quint64, request.id), Q_ARG(
int
, request.pageNumber),
120
Q_ARG(QSize, request.imageSize), Q_ARG(QPdfDocumentRenderOptions,
121
request.options));
122
}
123
124
void
QPdfPageRendererPrivate
::
requestFinished
(
int
page, QSize imageSize,
const
QImage &image, QPdfDocumentRenderOptions options, quint64 requestId)
125
{
126
Q_UNUSED(image);
127
Q_UNUSED(requestId);
128
const
auto
it = std::find_if(m_pendingRequests.begin(), m_pendingRequests.end(),
129
[page, imageSize, options](
const
PageRequest &request){
return
request.pageNumber == page && request.imageSize == imageSize && request.options == options; });
130
131
if
(it != m_pendingRequests.end())
132
m_pendingRequests.erase(it);
133
}
134
135
/*!
136
\class QPdfPageRenderer
137
\since 5.11
138
\inmodule QtPdf
139
140
\brief The QPdfPageRenderer class encapsulates the rendering of pages of a PDF document.
141
142
The QPdfPageRenderer contains a queue that collects all render requests that are invoked through
143
requestPage(). Depending on the configured RenderMode the QPdfPageRenderer processes this queue
144
in the main UI thread on next event loop invocation (\c RenderMode::SingleThreaded) or in a separate worker thread
145
(\c RenderMode::MultiThreaded) and emits the result through the pageRendered() signal for each request once
146
the rendering is done.
147
148
\sa QPdfDocument
149
*/
150
151
152
/*!
153
Constructs a page renderer object with parent object \a parent.
154
*/
155
QPdfPageRenderer::QPdfPageRenderer(QObject *parent)
156
: QObject(parent), d_ptr(
new
QPdfPageRendererPrivate)
157
{
158
qRegisterMetaType<QPdfDocumentRenderOptions>();
159
160
connect(d_ptr->m_renderWorker.data(), &RenderWorker::pageRendered,
this
,
161
[
this
](
int
page, QSize imageSize,
const
QImage &image,
162
QPdfDocumentRenderOptions options, quint64 requestId) {
163
d_ptr->requestFinished(page, imageSize, image, options, requestId);
164
emit pageRendered(page, imageSize, image, options, requestId);
165
d_ptr->handleNextRequest();
166
});
167
}
168
169
/*!
170
Destroys the page renderer object.
171
*/
172
QPdfPageRenderer::~QPdfPageRenderer()
173
{
174
}
175
176
/*!
177
\enum QPdfPageRenderer::RenderMode
178
179
This enum describes how the pages are rendered.
180
181
\value MultiThreaded All pages are rendered in a separate worker thread.
182
\value SingleThreaded All pages are rendered in the main UI thread (default).
183
184
\sa renderMode(), setRenderMode()
185
*/
186
187
/*!
188
\property QPdfPageRenderer::renderMode
189
\brief The mode the renderer uses to render the pages.
190
191
By default, this property is \c RenderMode::SingleThreaded.
192
193
\sa setRenderMode(), RenderMode
194
*/
195
196
/*!
197
Returns the mode of how the pages are rendered.
198
199
\sa RenderMode
200
*/
201
QPdfPageRenderer::RenderMode QPdfPageRenderer::renderMode()
const
202
{
203
return
d_ptr->m_renderMode;
204
}
205
206
/*!
207
Sets the mode of how the pages are rendered to \a mode.
208
209
\sa RenderMode
210
*/
211
void
QPdfPageRenderer::setRenderMode(RenderMode mode)
212
{
213
if
(d_ptr->m_renderMode == mode)
214
return
;
215
216
d_ptr->m_renderMode = mode;
217
emit renderModeChanged(d_ptr->m_renderMode);
218
219
if
(d_ptr->m_renderMode == RenderMode::MultiThreaded) {
220
d_ptr->m_renderThread =
new
QThread;
221
d_ptr->m_renderWorker->moveToThread(d_ptr->m_renderThread);
222
d_ptr->m_renderThread->start();
223
}
else
{
224
d_ptr->m_renderThread->quit();
225
d_ptr->m_renderThread->wait();
226
delete
d_ptr->m_renderThread;
227
d_ptr->m_renderThread =
nullptr
;
228
229
// pulling the object from another thread should be fine, once that thread is deleted
230
d_ptr->m_renderWorker->moveToThread(
this
->thread());
231
}
232
}
233
234
/*!
235
\property QPdfPageRenderer::document
236
\brief The document instance this object renders the pages from.
237
238
By default, this property is \c nullptr.
239
240
\sa document(), setDocument(), QPdfDocument
241
*/
242
243
/*!
244
Returns the document this objects renders the pages from, or a \c nullptr
245
if none has been set before.
246
247
\sa QPdfDocument
248
*/
249
QPdfDocument* QPdfPageRenderer::document()
const
250
{
251
return
d_ptr->m_document;
252
}
253
254
/*!
255
Sets the \a document this object renders the pages from.
256
257
\sa QPdfDocument
258
*/
259
void
QPdfPageRenderer::setDocument(QPdfDocument *document)
260
{
261
if
(d_ptr->m_document == document)
262
return
;
263
264
d_ptr->m_document = document;
265
emit documentChanged(d_ptr->m_document);
266
267
d_ptr->m_renderWorker->setDocument(d_ptr->m_document);
268
}
269
270
/*!
271
Requests the renderer to render the page \a pageNumber into a QImage of size \a imageSize
272
according to the provided \a options.
273
274
Once the rendering is done the pageRendered() signal is emitted with the result as parameters.
275
276
The return value is an ID that uniquely identifies the render request. If a request with the
277
same parameters is still in the queue, the ID of that queued request is returned.
278
*/
279
quint64 QPdfPageRenderer::requestPage(
int
pageNumber, QSize imageSize,
280
QPdfDocumentRenderOptions options)
281
{
282
if
(!d_ptr->m_document || d_ptr->m_document->status() != QPdfDocument::Status::Ready)
283
return
0;
284
285
for
(
const
auto
&request : std::as_const(d_ptr->m_pendingRequests)) {
286
if
(request.pageNumber == pageNumber
287
&& request.imageSize == imageSize
288
&& request.options == options)
289
return
request.id;
290
}
291
292
const
auto
id = d_ptr->m_requestIdCounter++;
293
294
QPdfPageRendererPrivate::PageRequest request;
295
request.id = id;
296
request.pageNumber = pageNumber;
297
request.imageSize = imageSize;
298
request.options = options;
299
300
d_ptr->m_requests.append(request);
301
302
d_ptr->handleNextRequest();
303
304
return
id;
305
}
306
307
QT_END_NAMESPACE
308
309
#
include
"qpdfpagerenderer.moc"
310
#
include
"moc_qpdfpagerenderer.cpp"
QPdfPageRendererPrivate
Definition
qpdfpagerenderer.cpp:37
QPdfPageRendererPrivate::m_renderThread
QThread * m_renderThread
Definition
qpdfpagerenderer.cpp:61
QPdfPageRendererPrivate::~QPdfPageRendererPrivate
~QPdfPageRendererPrivate()
Definition
qpdfpagerenderer.cpp:102
QPdfPageRendererPrivate::m_pendingRequests
QList< PageRequest > m_pendingRequests
Definition
qpdfpagerenderer.cpp:58
QPdfPageRendererPrivate::m_requests
QList< PageRequest > m_requests
Definition
qpdfpagerenderer.cpp:57
QPdfPageRendererPrivate::m_requestIdCounter
quint64 m_requestIdCounter
Definition
qpdfpagerenderer.cpp:59
QPdfPageRendererPrivate::requestFinished
void requestFinished(int page, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions options, quint64 requestId)
Definition
qpdfpagerenderer.cpp:124
QPdfPageRendererPrivate::handleNextRequest
void handleNextRequest()
Definition
qpdfpagerenderer.cpp:110
QPdfPageRendererPrivate::m_renderWorker
QScopedPointer< RenderWorker > m_renderWorker
Definition
qpdfpagerenderer.cpp:62
QPdfPageRendererPrivate::m_document
QPointer< QPdfDocument > m_document
Definition
qpdfpagerenderer.cpp:47
QPdfPageRendererPrivate::QPdfPageRendererPrivate
QPdfPageRendererPrivate()
Definition
qpdfpagerenderer.cpp:100
RenderWorker
Definition
qpdfpagerenderer.cpp:14
RenderWorker::setDocument
void setDocument(QPdfDocument *document)
Definition
qpdfpagerenderer.cpp:77
RenderWorker::~RenderWorker
~RenderWorker()
Definition
qpdfpagerenderer.cpp:73
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
Q_DECLARE_TYPEINFO
Q_DECLARE_TYPEINFO(QPdfPageRendererPrivate::PageRequest, Q_PRIMITIVE_TYPE)
QPdfPageRendererPrivate::PageRequest
Definition
qpdfpagerenderer.cpp:50
QPdfPageRendererPrivate::PageRequest::pageNumber
int pageNumber
Definition
qpdfpagerenderer.cpp:52
QPdfPageRendererPrivate::PageRequest::id
quint64 id
Definition
qpdfpagerenderer.cpp:51
QPdfPageRendererPrivate::PageRequest::imageSize
QSize imageSize
Definition
qpdfpagerenderer.cpp:53
QPdfPageRendererPrivate::PageRequest::options
QPdfDocumentRenderOptions options
Definition
qpdfpagerenderer.cpp:54
qtwebengine
src
pdf
qpdfpagerenderer.cpp
Generated on
for Qt by
1.18.0