From 0dfbc3a2cdcadeb576ad6be54d4a7f84a3f57200 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 22 Feb 2017 12:50:50 +0100 Subject: 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 --- src/pdf/pdf.pro | 4 +- src/pdf/qpdfdocumentrenderoptions.h | 2 + src/pdf/qpdfpagerenderer.cpp | 359 +++++++++++++++++++++ src/pdf/qpdfpagerenderer.h | 91 ++++++ tests/auto/auto.pro | 3 +- .../qpdfpagerenderer/pdf-sample.pagerenderer.pdf | Bin 0 -> 27523 bytes tests/auto/qpdfpagerenderer/qpdfpagerenderer.pro | 5 + .../auto/qpdfpagerenderer/tst_qpdfpagerenderer.cpp | 184 +++++++++++ 8 files changed, 646 insertions(+), 2 deletions(-) create mode 100644 src/pdf/qpdfpagerenderer.cpp create mode 100644 src/pdf/qpdfpagerenderer.h create mode 100644 tests/auto/qpdfpagerenderer/pdf-sample.pagerenderer.pdf create mode 100644 tests/auto/qpdfpagerenderer/qpdfpagerenderer.pro create mode 100644 tests/auto/qpdfpagerenderer/tst_qpdfpagerenderer.cpp 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 +** 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 +#include +#include +#include +#include + +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 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 m_document; + + struct PageRequest + { + quint64 id; + int pageNumber; + QSize imageSize; + QPdfDocumentRenderOptions options; + }; + + QVector m_requests; + QVector m_pendingRequests; + quint64 m_requestIdCounter = 1; + + QThread *m_renderThread = nullptr; + QScopedPointer 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(); + + 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 +** 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 +#include +#include + +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 Binary files /dev/null and b/tests/auto/qpdfpagerenderer/pdf-sample.pagerenderer.pdf 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 +** 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 +#include + +#include + +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().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().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().size(), imageSize); + QCOMPARE(pageRenderedSpy[0][4].toULongLong(), firstRequestId); + + const QImage image = pageRenderedSpy[0][2].value(); + + 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(), image); + QCOMPARE(pageRenderedSpy[0][2].value().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(), image); + QCOMPARE(pageRenderedSpy[0][2].value().size(), imageSize); + QCOMPARE(pageRenderedSpy[0][4].toULongLong(), thirdRequestId); +} + +QTEST_MAIN(tst_QPdfPageRenderer) + +#include "tst_qpdfpagerenderer.moc" -- cgit v1.2.3