summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Koenig <tobias.koenig@kdab.com>2017-02-22 12:50:50 +0100
committerTobias Koenig <tobias.koenig@kdab.com>2018-02-06 09:37:43 +0000
commit0dfbc3a2cdcadeb576ad6be54d4a7f84a3f57200 (patch)
treea16fb25c3aba48b22d8bae13164f60f5eacda7f7
parent0a591bd8e26566ab6177b7357529d374fad5fa2e (diff)
Add QPdfPageRenderer class
The QPdfPageRenderer renders a page of a QPdfDocument for a given zoom factor. Depending on its render mode, it does the rendering in the UI thread or a worker thread. Subsequent requests are queued and processed in order. Change-Id: I95820cd318cb443b2572f6d3db5a0bee53939bd1 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-rw-r--r--src/pdf/pdf.pro4
-rw-r--r--src/pdf/qpdfdocumentrenderoptions.h2
-rw-r--r--src/pdf/qpdfpagerenderer.cpp359
-rw-r--r--src/pdf/qpdfpagerenderer.h91
-rw-r--r--tests/auto/auto.pro3
-rw-r--r--tests/auto/qpdfpagerenderer/pdf-sample.pagerenderer.pdfbin0 -> 27523 bytes
-rw-r--r--tests/auto/qpdfpagerenderer/qpdfpagerenderer.pro5
-rw-r--r--tests/auto/qpdfpagerenderer/tst_qpdfpagerenderer.cpp184
8 files changed, 646 insertions, 2 deletions
diff --git a/src/pdf/pdf.pro b/src/pdf/pdf.pro
index 319e244..dd2df76 100644
--- a/src/pdf/pdf.pro
+++ b/src/pdf/pdf.pro
@@ -24,7 +24,8 @@ SOURCES += \
jsbridge.cpp \
qpdfbookmarkmodel.cpp \
qpdfdocument.cpp \
- qpdfpagenavigation.cpp
+ qpdfpagenavigation.cpp \
+ qpdfpagerenderer.cpp
HEADERS += \
qpdfbookmarkmodel.h \
@@ -33,4 +34,5 @@ HEADERS += \
qpdfdocumentrenderoptions.h \
qpdfnamespace.h \
qpdfpagenavigation.h \
+ qpdfpagerenderer.h \
qtpdfglobal.h
diff --git a/src/pdf/qpdfdocumentrenderoptions.h b/src/pdf/qpdfdocumentrenderoptions.h
index b602bb0..1d316b9 100644
--- a/src/pdf/qpdfdocumentrenderoptions.h
+++ b/src/pdf/qpdfdocumentrenderoptions.h
@@ -85,4 +85,6 @@ Q_DECL_CONSTEXPR inline bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocum
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QPdfDocumentRenderOptions)
+
#endif // QPDFDOCUMENTRENDEROPTIONS_H
diff --git a/src/pdf/qpdfpagerenderer.cpp b/src/pdf/qpdfpagerenderer.cpp
new file mode 100644
index 0000000..02d6ef4
--- /dev/null
+++ b/src/pdf/qpdfpagerenderer.cpp
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpdfpagerenderer.h"
+
+#include <private/qobject_p.h>
+#include <QMutex>
+#include <QPdfDocument>
+#include <QPointer>
+#include <QThread>
+
+QT_BEGIN_NAMESPACE
+
+class RenderWorker : public QObject
+{
+ Q_OBJECT
+
+public:
+ RenderWorker();
+ ~RenderWorker();
+
+ void setDocument(QPdfDocument *document);
+
+public Q_SLOTS:
+ void requestPage(quint64 requestId, int page, QSize imageSize,
+ QPdfDocumentRenderOptions options);
+
+Q_SIGNALS:
+ void pageRendered(int page, QSize imageSize, const QImage &image,
+ QPdfDocumentRenderOptions options, quint64 requestId);
+
+private:
+ QPointer<QPdfDocument> m_document;
+ QMutex m_mutex;
+};
+
+class QPdfPageRendererPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QPdfPageRenderer)
+
+public:
+ QPdfPageRendererPrivate();
+ ~QPdfPageRendererPrivate();
+
+ void handleNextRequest();
+ void requestFinished(int page, QSize imageSize, const QImage &image,
+ QPdfDocumentRenderOptions options, quint64 requestId);
+
+ QPdfPageRenderer::RenderMode m_renderMode = QPdfPageRenderer::SingleThreadedRenderMode;
+ QPointer<QPdfDocument> m_document;
+
+ struct PageRequest
+ {
+ quint64 id;
+ int pageNumber;
+ QSize imageSize;
+ QPdfDocumentRenderOptions options;
+ };
+
+ QVector<PageRequest> m_requests;
+ QVector<PageRequest> m_pendingRequests;
+ quint64 m_requestIdCounter = 1;
+
+ QThread *m_renderThread = nullptr;
+ QScopedPointer<RenderWorker> m_renderWorker;
+};
+
+Q_DECLARE_TYPEINFO(QPdfPageRendererPrivate::PageRequest, Q_PRIMITIVE_TYPE);
+
+
+RenderWorker::RenderWorker()
+ : m_document(nullptr)
+{
+}
+
+RenderWorker::~RenderWorker()
+{
+}
+
+void RenderWorker::setDocument(QPdfDocument *document)
+{
+ const QMutexLocker locker(&m_mutex);
+
+ if (m_document == document)
+ return;
+
+ m_document = document;
+}
+
+void RenderWorker::requestPage(quint64 requestId, int pageNumber, QSize imageSize,
+ QPdfDocumentRenderOptions options)
+{
+ const QMutexLocker locker(&m_mutex);
+
+ if (!m_document || m_document->status() != QPdfDocument::Ready)
+ return;
+
+ const QImage image = m_document->render(pageNumber, imageSize, options);
+
+ emit pageRendered(pageNumber, imageSize, image, options, requestId);
+}
+
+
+QPdfPageRendererPrivate::QPdfPageRendererPrivate()
+ : QObjectPrivate()
+ , m_renderWorker(new RenderWorker)
+{
+}
+
+QPdfPageRendererPrivate::~QPdfPageRendererPrivate()
+{
+ if (m_renderThread) {
+ m_renderThread->quit();
+ m_renderThread->wait();
+ }
+}
+
+void QPdfPageRendererPrivate::handleNextRequest()
+{
+ if (m_requests.isEmpty())
+ return;
+
+ const PageRequest request = m_requests.takeFirst();
+ m_pendingRequests.append(request);
+
+ QMetaObject::invokeMethod(m_renderWorker.data(), "requestPage", Qt::QueuedConnection,
+ Q_ARG(quint64, request.id), Q_ARG(int, request.pageNumber),
+ Q_ARG(QSize, request.imageSize), Q_ARG(QPdfDocumentRenderOptions,
+ request.options));
+}
+
+void QPdfPageRendererPrivate::requestFinished(int page, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions options, quint64 requestId)
+{
+ const auto it = std::find_if(m_pendingRequests.begin(), m_pendingRequests.end(),
+ [page, imageSize, options](const PageRequest &request){ return request.pageNumber == page && request.imageSize == imageSize && request.options == options; });
+
+ if (it != m_pendingRequests.end())
+ m_pendingRequests.erase(it);
+}
+
+/*!
+ \class QPdfPageRenderer
+ \since 5.11
+ \inmodule QtPdf
+
+ \brief The QPdfPageRenderer class encapsulates the rendering of pages of a PDF document.
+
+ The QPdfPageRenderer contains a queue that collects all render requests that are invoked through
+ requestPage(). Depending on the configured RenderMode the QPdfPageRenderer processes this queue
+ in the main UI thread on next event loop invocation (SingleThreadedRenderMode) or in a separate worker thread
+ (MultiThreadedRenderMode) and emits the result through the pageRendered() signal for each request once
+ the rendering is done.
+
+ \sa QPdfDocument
+*/
+
+
+/*!
+ Constructs a page renderer object with parent object \a parent.
+*/
+QPdfPageRenderer::QPdfPageRenderer(QObject *parent)
+ : QObject(*new QPdfPageRendererPrivate(), parent)
+{
+ Q_D(QPdfPageRenderer);
+
+ qRegisterMetaType<QPdfDocumentRenderOptions>();
+
+ connect(d->m_renderWorker.data(), &RenderWorker::pageRendered, this,
+ [this,d](int page, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions options, quint64 requestId) {
+ d->requestFinished(page, imageSize, image, options, requestId);
+ emit pageRendered(page, imageSize, image, options, requestId);
+ d->handleNextRequest();
+ });
+}
+
+/*!
+ Destroys the page renderer object.
+*/
+QPdfPageRenderer::~QPdfPageRenderer()
+{
+}
+
+/*!
+ \enum QPdfPageRenderer::RenderMode
+
+ This enum describes how the pages are rendered.
+
+ \value MultiThreadedRenderMode All pages are rendered in a separate worker thread.
+ \value SingleThreadedRenderMode All pages are rendered in the main UI thread (default).
+
+ \sa renderMode(), setRenderMode()
+*/
+
+/*!
+ \property QPdfPageRenderer::renderMode
+ \brief the mode the renderer renders the pages
+
+ By default, this property is \c QPdfPageRenderer::SingleThreaded.
+
+ \sa setRenderMode(), RenderMode
+*/
+
+/*!
+ Returns the mode of how the pages are rendered.
+
+ \sa RenderMode
+*/
+QPdfPageRenderer::RenderMode QPdfPageRenderer::renderMode() const
+{
+ Q_D(const QPdfPageRenderer);
+
+ return d->m_renderMode;
+}
+
+/*!
+ Sets the mode of how the pages are rendered.
+
+ \sa RenderMode
+*/
+void QPdfPageRenderer::setRenderMode(RenderMode mode)
+{
+ Q_D(QPdfPageRenderer);
+
+ if (d->m_renderMode == mode)
+ return;
+
+ d->m_renderMode = mode;
+ emit renderModeChanged(d->m_renderMode);
+
+ if (d->m_renderMode == MultiThreadedRenderMode) {
+ d->m_renderThread = new QThread;
+ d->m_renderWorker->moveToThread(d->m_renderThread);
+ d->m_renderThread->start();
+ } else {
+ d->m_renderThread->quit();
+ d->m_renderThread->wait();
+ delete d->m_renderThread;
+ d->m_renderThread = nullptr;
+
+ // pulling the object from another thread should be fine, once that thread is deleted
+ d->m_renderWorker->moveToThread(this->thread());
+ }
+}
+
+/*!
+ \property QPdfPageRenderer::document
+ \brief the document instance this object renders the pages from
+
+ By default, this property is \c nullptr.
+
+ \sa document(), setDocument(), QPdfDocument
+*/
+
+/*!
+ Returns the document this objects renders the pages from, or a \c nullptr
+ if none has been set before.
+
+ \sa QPdfDocument
+*/
+QPdfDocument* QPdfPageRenderer::document() const
+{
+ Q_D(const QPdfPageRenderer);
+
+ return d->m_document;
+}
+
+/*!
+ Sets the \a document this object renders the pages from.
+
+ \sa QPdfDocument
+*/
+void QPdfPageRenderer::setDocument(QPdfDocument *document)
+{
+ Q_D(QPdfPageRenderer);
+
+ if (d->m_document == document)
+ return;
+
+ d->m_document = document;
+ emit documentChanged(d->m_document);
+
+ d->m_renderWorker->setDocument(d->m_document);
+}
+
+/*!
+ Requests the renderer to render the page \a pageNumber into a QImage of size \a imageSize
+ according to the provided \a options.
+
+ Once the rendering is done the pageRendered() signal is emitted with the result as parameters.
+
+ The return value is an ID that uniquely identifies the render request. If a request with the
+ same parameters is still in the queue, the ID of that queued request is returned.
+*/
+quint64 QPdfPageRenderer::requestPage(int pageNumber, QSize imageSize,
+ QPdfDocumentRenderOptions options)
+{
+ Q_D(QPdfPageRenderer);
+
+ if (!d->m_document || d->m_document->status() != QPdfDocument::Ready)
+ return 0;
+
+ for (const auto request : qAsConst(d->m_pendingRequests)) {
+ if (request.pageNumber == pageNumber
+ && request.imageSize == imageSize
+ && request.options == options)
+ return request.id;
+ }
+
+ const auto id = d->m_requestIdCounter++;
+
+ QPdfPageRendererPrivate::PageRequest request;
+ request.id = id;
+ request.pageNumber = pageNumber;
+ request.imageSize = imageSize;
+ request.options = options;
+
+ d->m_requests.append(request);
+
+ d->handleNextRequest();
+
+ return id;
+}
+
+QT_END_NAMESPACE
+
+#include "qpdfpagerenderer.moc"
diff --git a/src/pdf/qpdfpagerenderer.h b/src/pdf/qpdfpagerenderer.h
new file mode 100644
index 0000000..8056579
--- /dev/null
+++ b/src/pdf/qpdfpagerenderer.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPDFPAGERENDERER_H
+#define QPDFPAGERENDERER_H
+
+#include "qtpdfglobal.h"
+
+#include <QObject>
+#include <QPdfDocumentRenderOptions>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfDocument;
+class QPdfPageRendererPrivate;
+
+class Q_PDF_EXPORT QPdfPageRenderer : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(RenderMode renderMode READ renderMode WRITE setRenderMode NOTIFY renderModeChanged)
+
+public:
+ enum RenderMode
+ {
+ MultiThreadedRenderMode,
+ SingleThreadedRenderMode
+ };
+ Q_ENUM(RenderMode)
+
+ explicit QPdfPageRenderer(QObject *parent = nullptr);
+ ~QPdfPageRenderer();
+
+ RenderMode renderMode() const;
+ void setRenderMode(RenderMode mode);
+
+ QPdfDocument* document() const;
+ void setDocument(QPdfDocument *document);
+
+ quint64 requestPage(int pageNumber, QSize imageSize,
+ QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions());
+
+Q_SIGNALS:
+ void documentChanged(QPdfDocument *document);
+ void renderModeChanged(RenderMode renderMode);
+
+ void pageRendered(int pageNumber, QSize imageSize, const QImage &image,
+ QPdfDocumentRenderOptions options, quint64 requestId);
+
+private:
+ Q_DECLARE_PRIVATE(QPdfPageRenderer)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 388b885..a2b3fcf 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -2,6 +2,7 @@ TEMPLATE = subdirs
SUBDIRS = \
qpdfbookmarkmodel \
- qpdfpagenavigation
+ qpdfpagenavigation \
+ qpdfpagerenderer
qtHaveModule(printsupport): SUBDIRS += qpdfdocument
diff --git a/tests/auto/qpdfpagerenderer/pdf-sample.pagerenderer.pdf b/tests/auto/qpdfpagerenderer/pdf-sample.pagerenderer.pdf
new file mode 100644
index 0000000..c4e1aa3
--- /dev/null
+++ b/tests/auto/qpdfpagerenderer/pdf-sample.pagerenderer.pdf
Binary files differ
diff --git a/tests/auto/qpdfpagerenderer/qpdfpagerenderer.pro b/tests/auto/qpdfpagerenderer/qpdfpagerenderer.pro
new file mode 100644
index 0000000..9ccb4e8
--- /dev/null
+++ b/tests/auto/qpdfpagerenderer/qpdfpagerenderer.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+TARGET = tst_qpdfpagerenderer
+QT += pdf testlib network
+macos:CONFIG -= app_bundle
+SOURCES += tst_qpdfpagerenderer.cpp
diff --git a/tests/auto/qpdfpagerenderer/tst_qpdfpagerenderer.cpp b/tests/auto/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
new file mode 100644
index 0000000..8eaef7c
--- /dev/null
+++ b/tests/auto/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QPdfDocument>
+#include <QPdfPageRenderer>
+
+#include <QtTest/QtTest>
+
+class tst_QPdfPageRenderer: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void defaultValues();
+ void withNoDocument();
+ void withEmptyDocument();
+ void withLoadedDocumentSingleThreaded();
+ void withLoadedDocumentMultiThreaded();
+ void switchingRenderMode();
+};
+
+void tst_QPdfPageRenderer::defaultValues()
+{
+ QPdfPageRenderer pageRenderer;
+
+ QCOMPARE(pageRenderer.document(), nullptr);
+ QCOMPARE(pageRenderer.renderMode(), QPdfPageRenderer::SingleThreadedRenderMode);
+}
+
+void tst_QPdfPageRenderer::withNoDocument()
+{
+ QPdfPageRenderer pageRenderer;
+
+ const QSize imageSize(100, 100);
+ const quint64 requestId = pageRenderer.requestPage(0, imageSize);
+
+ QCOMPARE(requestId, quint64(0));
+}
+
+void tst_QPdfPageRenderer::withEmptyDocument()
+{
+ QPdfDocument document;
+ QPdfPageRenderer pageRenderer;
+
+ pageRenderer.setDocument(&document);
+
+ const QSize imageSize(100, 100);
+ const quint64 requestId = pageRenderer.requestPage(0, imageSize);
+
+ QCOMPARE(requestId, quint64(0));
+}
+
+void tst_QPdfPageRenderer::withLoadedDocumentSingleThreaded()
+{
+ QPdfDocument document;
+ QPdfPageRenderer pageRenderer;
+ pageRenderer.setDocument(&document);
+
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::NoError);
+
+ QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered);
+
+ const QSize imageSize(100, 100);
+ const quint64 requestId = pageRenderer.requestPage(0, imageSize);
+
+ QCOMPARE(requestId, quint64(1));
+ QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
+ QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][4].toULongLong(), requestId);
+}
+
+void tst_QPdfPageRenderer::withLoadedDocumentMultiThreaded()
+{
+ QPdfDocument document;
+
+ QPdfPageRenderer pageRenderer;
+ pageRenderer.setDocument(&document);
+ pageRenderer.setRenderMode(QPdfPageRenderer::MultiThreadedRenderMode);
+
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::NoError);
+
+ QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered);
+
+ const QSize imageSize(100, 100);
+ const quint64 requestId = pageRenderer.requestPage(0, imageSize);
+
+ QCOMPARE(requestId, quint64(1));
+ QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
+ QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][4].toULongLong(), requestId);
+}
+
+void tst_QPdfPageRenderer::switchingRenderMode()
+{
+ QPdfDocument document;
+ QPdfPageRenderer pageRenderer;
+ pageRenderer.setDocument(&document);
+
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::NoError);
+
+ QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered);
+
+ // render single threaded
+ const QSize imageSize(100, 100);
+ const quint64 firstRequestId = pageRenderer.requestPage(0, imageSize);
+
+ QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
+ QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][4].toULongLong(), firstRequestId);
+
+ const QImage image = pageRenderedSpy[0][2].value<QImage>();
+
+ pageRenderedSpy.clear();
+
+ // switch to multi threaded
+ pageRenderer.setRenderMode(QPdfPageRenderer::MultiThreadedRenderMode);
+
+ const quint64 secondRequestId = pageRenderer.requestPage(0, imageSize);
+
+ QVERIFY(firstRequestId != secondRequestId);
+ QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
+ QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][2].value<QImage>(), image);
+ QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][4].toULongLong(), secondRequestId);
+
+ pageRenderedSpy.clear();
+
+ // switch back to single threaded
+ pageRenderer.setRenderMode(QPdfPageRenderer::SingleThreadedRenderMode);
+
+ const quint64 thirdRequestId = pageRenderer.requestPage(0, imageSize);
+
+ QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
+ QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][2].value<QImage>(), image);
+ QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
+ QCOMPARE(pageRenderedSpy[0][4].toULongLong(), thirdRequestId);
+}
+
+QTEST_MAIN(tst_QPdfPageRenderer)
+
+#include "tst_qpdfpagerenderer.moc"