Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
12
13class RenderWorker : public QObject
14{
16
17public:
20
21 void setDocument(QPdfDocument *document);
22
23public Q_SLOTS:
26
30
31private:
32 QPointer<QPdfDocument> m_document;
33 QMutex m_mutex;
34};
35
64
66
67
69 : m_document(nullptr)
70{
71}
72
76
78{
79 const QMutexLocker locker(&m_mutex);
80
81 if (m_document == document)
82 return;
83
84 m_document = document;
85}
86
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
101
109
111{
112 if (m_requests.isEmpty())
113 return;
114
115 const PageRequest request = m_requests.takeFirst();
117
119 Q_ARG(quint64, request.id), Q_ARG(int, request.pageNumber),
121 request.options));
122}
123
125{
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
156 : QObject(parent), d_ptr(new QPdfPageRendererPrivate)
157{
158 qRegisterMetaType<QPdfDocumentRenderOptions>();
159
161 [this](int page, QSize imageSize, const QImage &image,
163 d_ptr->requestFinished(page, imageSize, image, options, requestId);
164 emit pageRendered(page, imageSize, image, options, requestId);
165 d_ptr->handleNextRequest();
166 });
167}
168
175
205
212{
213 if (d_ptr->m_renderMode == mode)
214 return;
215
216 d_ptr->m_renderMode = mode;
218
220 d_ptr->m_renderThread = new QThread;
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
250{
251 return d_ptr->m_document;
252}
253
260{
261 if (d_ptr->m_document == document)
262 return;
263
264 d_ptr->m_document = document;
266
267 d_ptr->m_renderWorker->setDocument(d_ptr->m_document);
268}
269
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
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
308
309#include "qpdfpagerenderer.moc"
310#include "moc_qpdfpagerenderer.cpp"
\inmodule QtGui
Definition qimage.h:37
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:281
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
Definition qobject.cpp:1643
The QPdfDocument class loads a PDF document and renders pages from it.
QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options=QPdfDocumentRenderOptions())
Renders the page into a QImage of size imageSize according to the provided renderOptions.
Status status
This property holds the current status of the document.
QList< PageRequest > m_requests
QPdfPageRenderer::RenderMode m_renderMode
QPointer< QPdfDocument > m_document
void requestFinished(int page, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions options, quint64 requestId)
QList< PageRequest > m_pendingRequests
QScopedPointer< RenderWorker > m_renderWorker
QPdfDocument * document
The document instance this object renders the pages from.
RenderMode renderMode
The mode the renderer uses to render the pages.
void setDocument(QPdfDocument *document)
Sets the document this object renders the pages from.
void setRenderMode(RenderMode mode)
Sets the mode of how the pages are rendered to mode.
quint64 requestPage(int pageNumber, QSize imageSize, QPdfDocumentRenderOptions options=QPdfDocumentRenderOptions())
Requests the renderer to render the page pageNumber into a QImage of size imageSize according to the ...
~QPdfPageRenderer() override
Destroys the page renderer object.
void renderModeChanged(QPdfPageRenderer::RenderMode renderMode)
RenderMode
This enum describes how the pages are rendered.
void documentChanged(QPdfDocument *document)
T * data() const noexcept
Returns the value of the pointer referenced by this object.
\inmodule QtCore
Definition qsize.h:25
void start(Priority=InheritPriority)
Definition qthread.cpp:996
bool wait(QDeadlineTimer deadline=QDeadlineTimer(QDeadlineTimer::Forever))
Definition qthread.cpp:1023
void quit()
Definition qthread.cpp:1008
void pageRendered(int page, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions options, quint64 requestId)
void requestPage(quint64 requestId, int page, QSize imageSize, QPdfDocumentRenderOptions options)
void setDocument(QPdfDocument *document)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
@ QueuedConnection
Definition image.cpp:4
QNearFieldTarget::RequestId requestId
#define Q_ARG(Type, data)
Definition qobjectdefs.h:63
GLenum mode
GLenum GLuint id
[7]
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
#define Q_OBJECT
#define Q_SLOTS
#define Q_SIGNALS
#define emit
#define Q_UNUSED(x)
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:157
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
unsigned long long quint64
Definition qtypes.h:61
QObject::connect nullptr
QByteArray page
[45]
QNetworkRequest request(url)
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...