diff options
Diffstat (limited to 'tests/auto/pdf')
23 files changed, 1491 insertions, 0 deletions
diff --git a/tests/auto/pdf/CMakeLists.txt b/tests/auto/pdf/CMakeLists.txt new file mode 100644 index 000000000..205bd24d0 --- /dev/null +++ b/tests/auto/pdf/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(qpdfbookmarkmodel) +if (TARGET Qt::PdfWidgets) + add_subdirectory(qpdfpagenavigator) +endif() +add_subdirectory(qpdfpagerenderer) +add_subdirectory(qpdfsearchmodel) +if(TARGET Qt::PrintSupport) + add_subdirectory(qpdfdocument) +endif() diff --git a/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt b/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt new file mode 100644 index 000000000..729bc9138 --- /dev/null +++ b/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_qpdfbookmarkmodel + SOURCES + tst_qpdfbookmarkmodel.cpp + LIBRARIES + Qt::Gui + Qt::Network + Qt::Pdf + TESTDATA + pdf-sample.bookmarks.pdf + pdf-sample.bookmarks_pages.pdf +) + diff --git a/tests/auto/pdf/qpdfbookmarkmodel/pdf-sample.bookmarks.pdf b/tests/auto/pdf/qpdfbookmarkmodel/pdf-sample.bookmarks.pdf Binary files differnew file mode 100644 index 000000000..bd27c18b6 --- /dev/null +++ b/tests/auto/pdf/qpdfbookmarkmodel/pdf-sample.bookmarks.pdf diff --git a/tests/auto/pdf/qpdfbookmarkmodel/pdf-sample.bookmarks_pages.pdf b/tests/auto/pdf/qpdfbookmarkmodel/pdf-sample.bookmarks_pages.pdf Binary files differnew file mode 100644 index 000000000..c4e1aa36e --- /dev/null +++ b/tests/auto/pdf/qpdfbookmarkmodel/pdf-sample.bookmarks_pages.pdf diff --git a/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp b/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp new file mode 100644 index 000000000..a1804e179 --- /dev/null +++ b/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp @@ -0,0 +1,217 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#include <QtTest/QtTest> + +#include <QPdfDocument> +#include <QPdfBookmarkModel> + +class tst_QPdfBookmarkModel: public QObject +{ + Q_OBJECT + +public: + tst_QPdfBookmarkModel() + { + qRegisterMetaType<QPdfDocument::Status>(); + } + +private slots: + void emptyModel(); + void setEmptyDocument(); + void setEmptyDocumentAndLoad(); + void setLoadedDocument(); + void unloadDocument(); + void testTreeStructure(); + void testPageNumberRole(); + void testLocationAndZoomRoles(); +}; + +void tst_QPdfBookmarkModel::emptyModel() +{ + QPdfBookmarkModel model; + + QVERIFY(!model.document()); + QCOMPARE(model.rowCount(), 0); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.index(0, 0).isValid(), false); +} + +void tst_QPdfBookmarkModel::setEmptyDocument() +{ + QPdfDocument document; + QPdfBookmarkModel model; + + model.setDocument(&document); + + QCOMPARE(model.document(), &document); + QCOMPARE(model.rowCount(), 0); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.index(0, 0).isValid(), false); +} + +void tst_QPdfBookmarkModel::setEmptyDocumentAndLoad() +{ + QPdfDocument document; + QPdfBookmarkModel model; + + model.setDocument(&document); + + QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset())); + QSignalSpy modelResetSpy(&model, SIGNAL(modelReset())); + + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None); + + QCOMPARE(modelAboutToBeResetSpy.size(), 1); + QCOMPARE(modelResetSpy.size(), 1); + + QCOMPARE(model.rowCount(), 3); +} + +void tst_QPdfBookmarkModel::setLoadedDocument() +{ + QPdfDocument document; + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None); + + QPdfBookmarkModel model; + + QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset())); + QSignalSpy modelResetSpy(&model, SIGNAL(modelReset())); + + model.setDocument(&document); + + QCOMPARE(modelAboutToBeResetSpy.size(), 1); + QCOMPARE(modelResetSpy.size(), 1); + + QCOMPARE(model.rowCount(), 3); +} + +void tst_QPdfBookmarkModel::unloadDocument() +{ + QPdfDocument document; + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None); + + QPdfBookmarkModel model; + model.setDocument(&document); + + QCOMPARE(model.rowCount(), 3); + + QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset())); + QSignalSpy modelResetSpy(&model, SIGNAL(modelReset())); + + document.close(); + + QCOMPARE(modelAboutToBeResetSpy.size(), 1); + QCOMPARE(modelResetSpy.size(), 1); + + QCOMPARE(model.rowCount(), 0); +} + +void tst_QPdfBookmarkModel::testTreeStructure() +{ + QPdfDocument document; + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None); + + QPdfBookmarkModel model; + model.setDocument(&document); + + QCOMPARE(model.rowCount(), 3); + + const QModelIndex index1 = model.index(0, 0); + QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 1")); + QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 0); + QCOMPARE(model.rowCount(index1), 2); + + const QModelIndex index1_1 = model.index(0, 0, index1); + QCOMPARE(index1_1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 1.1")); + QCOMPARE(index1_1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1); + QCOMPARE(model.rowCount(index1_1), 0); + + const QModelIndex index1_2 = model.index(1, 0, index1); + QCOMPARE(index1_2.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 1.2")); + QCOMPARE(index1_2.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1); + QCOMPARE(model.rowCount(index1_2), 0); + + const QModelIndex index2 = model.index(1, 0); + QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2")); + QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 0); + QCOMPARE(model.rowCount(index2), 2); + + const QModelIndex index2_1 = model.index(0, 0, index2); + QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2.1")); + QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1); + QCOMPARE(model.rowCount(index2_1), 1); + + const QModelIndex index2_1_1 = model.index(0, 0, index2_1); + QCOMPARE(index2_1_1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2.1.1")); + QCOMPARE(index2_1_1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 2); + QCOMPARE(model.rowCount(index2_1_1), 0); + + const QModelIndex index2_2 = model.index(1, 0, index2); + QCOMPARE(index2_2.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2.2")); + QCOMPARE(index2_2.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1); + QCOMPARE(model.rowCount(index2_2), 0); + + const QModelIndex index3 = model.index(2, 0); + QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 3")); + QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 0); + QCOMPARE(model.rowCount(index3), 0); + + const QModelIndex index4 = model.index(3, 0); + QCOMPARE(index4, QModelIndex()); +} + +void tst_QPdfBookmarkModel::testPageNumberRole() +{ + QPdfDocument document; + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::Error::None); + + QPdfBookmarkModel model; + model.setDocument(&document); + + QCOMPARE(model.rowCount(), 3); + + const QModelIndex index1 = model.index(0, 0); + QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 0); + + const QModelIndex index2 = model.index(1, 0); + QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 1); + + const QModelIndex index2_1 = model.index(0, 0, index2); + QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 1); + + const QModelIndex index3 = model.index(2, 0); + QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 2); +} + +void tst_QPdfBookmarkModel::testLocationAndZoomRoles() +{ + QPdfDocument document; + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::Error::None); + + QPdfBookmarkModel model; + model.setDocument(&document); + + QCOMPARE(model.rowCount(), 3); + + const QModelIndex index1 = model.index(0, 0); + QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 69)); + QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0); + + const QModelIndex index2 = model.index(1, 0); + QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 57)); + QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0); + + const QModelIndex index2_1 = model.index(0, 0, index2); + QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 526)); + QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0); + + const QModelIndex index3 = model.index(2, 0); + QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 402)); + QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0); +} + +QTEST_MAIN(tst_QPdfBookmarkModel) + +#include "tst_qpdfbookmarkmodel.moc" diff --git a/tests/auto/pdf/qpdfdocument/CMakeLists.txt b/tests/auto/pdf/qpdfdocument/CMakeLists.txt new file mode 100644 index 000000000..b8300ef27 --- /dev/null +++ b/tests/auto/pdf/qpdfdocument/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_qpdfdocument + SOURCES + tst_qpdfdocument.cpp + LIBRARIES + Qt::Gui + Qt::Network + Qt::PrintSupport + Qt::Pdf + TESTDATA + pdf-sample.protected.pdf + pdf-sample.metadata.pdf + rotated_text.pdf + tagged_mcr_multipage.pdf + test.pdf +) diff --git a/tests/auto/pdf/qpdfdocument/pdf-sample.metadata.pdf b/tests/auto/pdf/qpdfdocument/pdf-sample.metadata.pdf Binary files differnew file mode 100644 index 000000000..c3350ba5f --- /dev/null +++ b/tests/auto/pdf/qpdfdocument/pdf-sample.metadata.pdf diff --git a/tests/auto/pdf/qpdfdocument/pdf-sample.protected.pdf b/tests/auto/pdf/qpdfdocument/pdf-sample.protected.pdf Binary files differnew file mode 100644 index 000000000..d76fdd1a6 --- /dev/null +++ b/tests/auto/pdf/qpdfdocument/pdf-sample.protected.pdf diff --git a/tests/auto/pdf/qpdfdocument/rotated_text.pdf b/tests/auto/pdf/qpdfdocument/rotated_text.pdf new file mode 100644 index 000000000..d6d8db84e --- /dev/null +++ b/tests/auto/pdf/qpdfdocument/rotated_text.pdf @@ -0,0 +1,70 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [ 0 0 200 200 ] + /Count 1 + /Kids [ 3 0 R ] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Resources << + /Font << + /F1 4 0 R + >> + >> + /Contents 5 0 R +>> +endobj +4 0 obj << + /Type /Font + /Subtype /Type1 + /BaseFont /Times-Roman +>> +endobj +5 0 obj << + /Length 406 +>> +stream +BT +0 0 Td +/F1 12 Tf +0.70710678118 -0.70710678118 0.70710678118 0.70710678118 100 100 Tm +(Hello,) Tj +0 0 Td +/F1 12 Tf +-0.70710678118 -0.70710678118 0.70710678118 -0.70710678118 100 100 Tm +( world!\r\n) Tj +0 0 Td +/F1 12 Tf +-0.70710678118 0.70710678118 -0.70710678118 -0.70710678118 100 100 Tm +(Goodbye,) Tj +0 0 Td +/F1 12 Tf +0.70710678118 0.70710678118 -0.70710678118 0.70710678118 100 100 Tm +( world!) Tj +ET +endstream +endobj +xref +0 6 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000161 00000 n +0000000287 00000 n +0000000365 00000 n +trailer << + /Root 1 0 R + /Size 6 +>> +startxref +823 +%%EOF diff --git a/tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf b/tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf new file mode 100644 index 000000000..fcc5fafda --- /dev/null +++ b/tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf @@ -0,0 +1,136 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /MarkInfo << + /Type /MarkInfo + /Marked true + >> + /Pages 2 0 R + /StructTreeRoot 8 0 R +>> +endobj +2 0 obj << + /Type /Pages + /CropBox [ 10.8197 8.459 605.705 801.639 ] + /MediaBox [ 0.0 0.0 616.721 809.902 ] + /Count 2 + /Kids [ + 4 0 R + 6 0 R + ] +>> +endobj +3 0 obj << + /Type /Font + /Subtype /Type1 + /BaseFont /Times-Roman +>> +endobj +4 0 obj << + /Type /Page + /Tabs /S + /Parent 2 0 R + /StructParents 0 + /Contents 5 0 R + /Resources << + /ProcSet [/PDF /Text] + /Font << + /F1 3 0 R + >> + >> +>> +endobj +5 0 obj << + /Length 83 +>> +stream +BT +/Document <</MCID 0 >>BDC +0 i +/F1 1 Tf +12 0 0 12 43.073 771.625 Tm +(1)Tj +EMC +ET +endstream +endobj +6 0 obj << + /Type /Page + /Tabs /S + /Parent 2 0 R + /StructParents 1 + /Contents 7 0 R + /Resources << + /ProcSet [/PDF /Text] + /Font << + /F1 3 0 R + >> + >> +>> +endobj +7 0 obj << + /Length 83 +>> +stream +BT +/Document <</MCID 0 >>BDC +0 i +/F1 1 Tf +12 0 0 12 43.073 771.625 Tm +(2)Tj +EMC +ET +endstream +endobj +8 0 obj << + /Type /StructTreeRoot + /K 10 0 R + /ParentTree 9 0 R + /ParentTreeNextKey 2 +>> +endobj +9 0 obj << + /Nums [ + 0 + [10 0 R] + 1 + [10 0 R] + ] +>> +endobj +10 0 obj << + /T () + /S /Document + /P 8 0 R + /Pg 4 0 R + /K [ + 0 + << + /MCID 0 + /Pg 6 0 R + /Type /MCR + >> + ] +>> +%endobj +xref +0 11 +0000000000 65535 f +0000000015 00000 n +0000000149 00000 n +0000000315 00000 n +0000000393 00000 n +0000000575 00000 n +0000000709 00000 n +0000000891 00000 n +0000001025 00000 n +0000001125 00000 n +0000001198 00000 n +trailer << + /Root 1 0 R + /Size 11 +>> +startxref +1345 +%%EOF diff --git a/tests/auto/pdf/qpdfdocument/test.pdf b/tests/auto/pdf/qpdfdocument/test.pdf Binary files differnew file mode 100644 index 000000000..0832dfbed --- /dev/null +++ b/tests/auto/pdf/qpdfdocument/test.pdf diff --git a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp new file mode 100644 index 000000000..d222bff0c --- /dev/null +++ b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp @@ -0,0 +1,484 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#include <QtTest/QtTest> + +#include <QPainter> +#include <QPdfDocument> +#include <QPrinter> +#include <QDateTime> +#include <QTemporaryFile> +#include <QTimeZone> +#include <QNetworkAccessManager> +#include <QNetworkRequest> +#include <QNetworkReply> + +class tst_QPdfDocument: public QObject +{ + Q_OBJECT + +public: + tst_QPdfDocument() + { + qRegisterMetaType<QPdfDocument::Status>(); + } + +private slots: + void pageCount(); + void loadFromIODevice(); + void loadAsync(); + void password(); + void close(); + void loadAfterClose(); + void closeOnDestroy(); + void status(); + void passwordClearedOnClose(); + void metaData(); + void pageLabels(); + void getSelection_data(); + void getSelection(); + void getSelectionAtIndex_data(); + void getSelectionAtIndex(); + +private: + void consistencyCheck(QPdfDocument &doc) const; +}; + +struct TemporaryPdf: public QTemporaryFile +{ + TemporaryPdf(); + QPageLayout pageLayout; + + static QString pageText(int page) { + switch (page) { + case 0: return QStringLiteral("Hello Page 1"); + case 1: return QStringLiteral("Hello Page 2"); + default: return {}; + } + } +}; + + +TemporaryPdf::TemporaryPdf():QTemporaryFile(QStringLiteral("qpdfdocument")) +{ + open(); + pageLayout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF()); + + { + QPrinter printer; + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setOutputFileName(fileName()); + printer.setPageLayout(pageLayout); + + { + QPainter painter(&printer); + painter.drawText(100, 100, pageText(0)); + printer.newPage(); + painter.drawText(100, 100, pageText(1)); + } + } + + seek(0); +} + +void tst_QPdfDocument::pageCount() +{ + TemporaryPdf tempPdf; + + QPdfDocument doc; + QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int))); + + QCOMPARE(doc.pageCount(), 0); + QCOMPARE(doc.load(tempPdf.fileName()), QPdfDocument::Error::None); + QCOMPARE(doc.pageCount(), 2); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); + + QCOMPARE(doc.pagePointSize(0).toSize(), tempPdf.pageLayout.fullRectPoints().size()); +} + +void tst_QPdfDocument::loadFromIODevice() +{ + TemporaryPdf tempPdf; + QPdfDocument doc; + QSignalSpy statusChangedSpy(&doc, SIGNAL(statusChanged(QPdfDocument::Status))); + QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int))); + doc.load(&tempPdf); + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready); + QCOMPARE(doc.error(), QPdfDocument::Error::None); + QCOMPARE(doc.pageCount(), 2); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); + + consistencyCheck(doc); +} + +void tst_QPdfDocument::consistencyCheck(QPdfDocument &doc) const +{ + for (int i = 0; i < doc.pageCount(); ++i) { + const QString expected = TemporaryPdf::pageText(i); + QPdfSelection page = doc.getAllText(i); + QCOMPARE(page.text(), expected); + auto pageMoved = std::move(page); + QCOMPARE(pageMoved.text(), expected); + } +} + +void tst_QPdfDocument::loadAsync() +{ + TemporaryPdf tempPdf; + + QNetworkAccessManager nam; + + QUrl url = QUrl::fromLocalFile(tempPdf.fileName()); + QScopedPointer<QNetworkReply> reply(nam.get(QNetworkRequest(url))); + + QPdfDocument doc; + QSignalSpy statusChangedSpy(&doc, SIGNAL(statusChanged(QPdfDocument::Status))); + QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int))); + + doc.load(reply.data()); + + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready); + QCOMPARE(doc.pageCount(), 2); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); + + consistencyCheck(doc); +} + +void tst_QPdfDocument::password() +{ + QPdfDocument doc; + QSignalSpy passwordChangedSpy(&doc, SIGNAL(passwordChanged())); + + QCOMPARE(doc.pageCount(), 0); + QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::IncorrectPassword); + QCOMPARE(passwordChangedSpy.size(), 0); + doc.setPassword(QStringLiteral("WrongPassword")); + QCOMPARE(passwordChangedSpy.size(), 1); + QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::IncorrectPassword); + QCOMPARE(doc.status(), QPdfDocument::Status::Error); + doc.setPassword(QStringLiteral("Qt")); + QCOMPARE(passwordChangedSpy.size(), 2); + QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::None); + QCOMPARE(doc.pageCount(), 1); +} + +void tst_QPdfDocument::close() +{ + TemporaryPdf tempPdf; + QPdfDocument doc; + + QSignalSpy statusChangedSpy(&doc, SIGNAL(statusChanged(QPdfDocument::Status))); + QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int))); + + doc.load(&tempPdf); + + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); + + statusChangedSpy.clear(); + pageCountChangedSpy.clear(); + + consistencyCheck(doc); + if (QTest::currentTestFailed()) + return; + + doc.close(); + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null); + QCOMPARE(doc.pageCount(), 0); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); +} + +void tst_QPdfDocument::loadAfterClose() +{ + TemporaryPdf tempPdf; + QPdfDocument doc; + + QSignalSpy statusChangedSpy(&doc, SIGNAL(statusChanged(QPdfDocument::Status))); + QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int))); + + doc.load(&tempPdf); + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); + statusChangedSpy.clear(); + pageCountChangedSpy.clear(); + + doc.close(); + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); + statusChangedSpy.clear(); + pageCountChangedSpy.clear(); + + doc.load(&tempPdf); + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready); + QCOMPARE(doc.error(), QPdfDocument::Error::None); + QCOMPARE(doc.pageCount(), 2); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount()); + + consistencyCheck(doc); +} + +void tst_QPdfDocument::closeOnDestroy() +{ + TemporaryPdf tempPdf; + + // deleting an open document should automatically close it + { + QPdfDocument *doc = new QPdfDocument; + + doc->load(&tempPdf); + + QSignalSpy statusChangedSpy(doc, SIGNAL(statusChanged(QPdfDocument::Status))); + QSignalSpy pageCountChangedSpy(doc, SIGNAL(pageCountChanged(int))); + + delete doc; + + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null); + QCOMPARE(pageCountChangedSpy.size(), 1); + QCOMPARE(pageCountChangedSpy[0][0].toInt(), 0); + } + + // deleting a closed document should not emit any signal + { + QPdfDocument *doc = new QPdfDocument; + doc->load(&tempPdf); + doc->close(); + + QSignalSpy statusChangedSpy(doc, SIGNAL(statusChanged(QPdfDocument::Status))); + QSignalSpy pageCountChangedSpy(doc, SIGNAL(pageCountChanged(int))); + + delete doc; + + QCOMPARE(statusChangedSpy.size(), 0); + QCOMPARE(pageCountChangedSpy.size(), 0); + } +} + +void tst_QPdfDocument::status() +{ + TemporaryPdf tempPdf; + + QPdfDocument doc; + QCOMPARE(doc.status(), QPdfDocument::Status::Null); + + QSignalSpy statusChangedSpy(&doc, SIGNAL(statusChanged(QPdfDocument::Status))); + + // open existing document + doc.load(&tempPdf); + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready); + statusChangedSpy.clear(); + + QCOMPARE(doc.status(), QPdfDocument::Status::Ready); + + // close document + doc.close(); + + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null); + statusChangedSpy.clear(); + + QCOMPARE(doc.status(), QPdfDocument::Status::Null); + + // try to open non-existing document + doc.load(QFINDTESTDATA("does-not-exist.pdf")); + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Error); + QCOMPARE(doc.status(), QPdfDocument::Status::Error); + statusChangedSpy.clear(); + + // try to open non-existing document asynchronously + QNetworkAccessManager accessManager; + + const QUrl url("http://doesnotexist.qt.io"); + QScopedPointer<QNetworkReply> reply(accessManager.get(QNetworkRequest(url))); + + doc.load(reply.data()); + + QElapsedTimer stopWatch; + stopWatch.start(); + forever { + QCoreApplication::instance()->processEvents(); + if (statusChangedSpy.size() == 2) + break; + if (stopWatch.elapsed() >= 30000) + break; + } + + QCOMPARE(statusChangedSpy.size(), 2); + QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading); + QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Error); + statusChangedSpy.clear(); +} + +void tst_QPdfDocument::passwordClearedOnClose() +{ + TemporaryPdf tempPdf; + QPdfDocument doc; + + QSignalSpy passwordChangedSpy(&doc, SIGNAL(passwordChanged())); + + doc.setPassword(QStringLiteral("Qt")); + QCOMPARE(passwordChangedSpy.size(), 1); + QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::None); + passwordChangedSpy.clear(); + + doc.close(); // password is cleared on close + QCOMPARE(passwordChangedSpy.size(), 1); + passwordChangedSpy.clear(); + + doc.load(&tempPdf); + doc.close(); // signal is not emitted if password didn't change + QCOMPARE(passwordChangedSpy.size(), 0); +} + +void tst_QPdfDocument::metaData() +{ + QPdfDocument doc; + + // a closed document does not return any meta data + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Title).toString(), QString()); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Subject).toString(), QString()); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Author).toString(), QString()); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Keywords).toString(), QString()); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Producer).toString(), QString()); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Creator).toString(), QString()); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::CreationDate).toDateTime(), QDateTime()); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::ModificationDate).toDateTime(), QDateTime()); + + QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.metadata.pdf")), QPdfDocument::Error::None); + + // check for proper meta data from sample document + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Title).toString(), QString::fromLatin1("Qt PDF Unit Test Document")); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Subject).toString(), QString::fromLatin1("A test for meta data access")); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Author).toString(), QString::fromLatin1("John Doe")); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Keywords).toString(), QString::fromLatin1("meta data keywords")); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Producer).toString(), QString::fromLatin1("LibreOffice 5.1")); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Creator).toString(), QString::fromLatin1("Writer")); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::CreationDate).toDateTime(), + QDateTime(QDate(2016, 8, 7), QTime(7, 3, 6), QTimeZone::UTC)); + QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::ModificationDate).toDateTime(), + QDateTime(QDate(2016, 8, 8), QTime(8, 3, 6), QTimeZone::UTC)); +} + +void tst_QPdfDocument::pageLabels() +{ + QPdfDocument doc; + QCOMPARE(doc.load(QFINDTESTDATA("test.pdf")), QPdfDocument::Error::None); + QCOMPARE(doc.pageCount(), 3); + QCOMPARE(doc.pageLabel(0), "Qt"); + QCOMPARE(doc.pageLabel(1), "1"); + QCOMPARE(doc.pageLabel(2), "i"); // i of the tiger! +} + +void tst_QPdfDocument::getSelection_data() +{ + QTest::addColumn<QString>("pdfPath"); + QTest::addColumn<int>("page"); + QTest::addColumn<QPointF>("start"); + QTest::addColumn<QPointF>("end"); + QTest::addColumn<QString>("expectedText"); + QTest::addColumn<int>("expectedStartIndex"); + QTest::addColumn<int>("expectedEndIndex"); + QTest::addColumn<QRect>("expectedBounds"); + QTest::addColumn<int>("expectedPolygonCount"); + + QTest::newRow("raid") << QFINDTESTDATA("test.pdf") + << 1 << QPointF(316.4, 206) << QPointF(339, 201) + << "raid" << 80 << 84 << QRect(316, 201, 21, 12) << 1; + QTest::newRow("rotated text") << QFINDTESTDATA("rotated_text.pdf") + << 0 << QPointF(102, 94) << QPointF(125, 73) + << "world!" << 25 << 31 << QRect(98, 70, 26, 28) << 1; +} + +void tst_QPdfDocument::getSelection() +{ + QFETCH(QString, pdfPath); + QFETCH(int, page); + QFETCH(QPointF, start); + QFETCH(QPointF, end); + QFETCH(QString, expectedText); + QFETCH(int, expectedStartIndex); + QFETCH(int, expectedEndIndex); + QFETCH(QRect, expectedBounds); + QFETCH(int, expectedPolygonCount); + + QPdfDocument doc; + QCOMPARE(doc.load(pdfPath), QPdfDocument::Error::None); + + QPdfSelection sel = doc.getSelection(page, start, end); + QCOMPARE(sel.text(), expectedText); + QCOMPARE(sel.startIndex(), expectedStartIndex); + QCOMPARE(sel.endIndex(), expectedEndIndex); + QCOMPARE(sel.boundingRectangle().toRect(), expectedBounds); + QCOMPARE(sel.bounds().size(), expectedPolygonCount); +} + +void tst_QPdfDocument::getSelectionAtIndex_data() +{ + QTest::addColumn<QString>("pdfPath"); + QTest::addColumn<int>("page"); + QTest::addColumn<int>("start"); + QTest::addColumn<int>("maxLen"); + QTest::addColumn<QString>("expectedText"); + QTest::addColumn<QRect>("expectedBounds"); + QTest::addColumn<int>("expectedPolygonCount"); + + QTest::newRow("raid") << QFINDTESTDATA("test.pdf") + << 1 << 80 << 4 << "raid" << QRect(316, 201, 21, 12) << 1; + QTest::newRow("rotated text") << QFINDTESTDATA("rotated_text.pdf") + << 0 << 7 << 6 << "world!" << QRect(76, 102, 26, 28) << 1; + QTest::newRow("displaced text") << QFINDTESTDATA("tagged_mcr_multipage.pdf") + << 0 << 0 << 10 << "1" << QRect(34, 22, 3, 8) << 1; +} + +void tst_QPdfDocument::getSelectionAtIndex() +{ + QFETCH(QString, pdfPath); + QFETCH(int, page); + QFETCH(int, start); + QFETCH(int, maxLen); + QFETCH(QString, expectedText); + QFETCH(QRect, expectedBounds); + QFETCH(int, expectedPolygonCount); + + QPdfDocument doc; + QCOMPARE(doc.load(pdfPath), QPdfDocument::Error::None); + + QPdfSelection sel = doc.getSelectionAtIndex(page, start, maxLen); + QCOMPARE(sel.text(), expectedText); + QCOMPARE(sel.boundingRectangle().toRect(), expectedBounds); + QCOMPARE(sel.bounds().size(), expectedPolygonCount); +} + +QTEST_MAIN(tst_QPdfDocument) + +#include "tst_qpdfdocument.moc" + diff --git a/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt b/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt new file mode 100644 index 000000000..3e8b8f416 --- /dev/null +++ b/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_qpdfpagenavigator.cpp + SOURCES + tst_qpdfpagenavigator.cpp + LIBRARIES + Qt::Gui + Qt::Network + Qt::Pdf + Qt::PdfWidgets + TESTDATA + pdf-sample.bookmarks_pages.pdf +) diff --git a/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf b/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf Binary files differnew file mode 100644 index 000000000..c4e1aa36e --- /dev/null +++ b/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf diff --git a/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp new file mode 100644 index 000000000..327a9f36a --- /dev/null +++ b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#include <QtTest/QtTest> + +#include <QPdfDocument> +#include <QPdfView> +#include <QPdfPageNavigator> + +class tst_QPdfPageNavigator: public QObject +{ + Q_OBJECT + +private slots: + void offScreenSignals(); +}; + +void tst_QPdfPageNavigator::offScreenSignals() +{ + QPdfDocument document; + QPdfView pdfView; + QPdfPageNavigator *navigator = pdfView.pageNavigator(); + + QSignalSpy currentPageChanged(navigator, &QPdfPageNavigator::currentPageChanged); + QSignalSpy currentLocationChanged(navigator, &QPdfPageNavigator::currentLocationChanged); + QSignalSpy backAvailableChanged(navigator, &QPdfPageNavigator::backAvailableChanged); + QSignalSpy forwardAvailableChanged(navigator, &QPdfPageNavigator::forwardAvailableChanged); + QSignalSpy jumped(navigator, &QPdfPageNavigator::jumped); + + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::Error::None); + QVERIFY2(document.pageCount() == 3, "Test document has changed! 3 pages expected."); + pdfView.setDocument(&document); + + // Start with a clean history + QCOMPARE(forwardAvailableChanged.count(), 0); + QCOMPARE(backAvailableChanged.count(), 0); + + navigator->jump(3, QPoint()); + QCOMPARE(forwardAvailableChanged.count(), 0); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 1); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 1); + + navigator->jump(1, QPoint()); + QCOMPARE(forwardAvailableChanged.count(), 0); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 2); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 2); + + navigator->back(); + QCOMPARE(forwardAvailableChanged.count(), 1); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 3); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 3); + + navigator->forward(); + QCOMPARE(forwardAvailableChanged.count(), 2); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 4); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 4); +} + +QTEST_MAIN(tst_QPdfPageNavigator) + +#include "tst_qpdfpagenavigator.moc" diff --git a/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt b/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt new file mode 100644 index 000000000..53a68fe59 --- /dev/null +++ b/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_qpdfpagerenderer + SOURCES + tst_qpdfpagerenderer.cpp + LIBRARIES + Qt::Gui + Qt::Network + Qt::Pdf + TESTDATA + pdf-sample.pagerenderer.pdf +) + diff --git a/tests/auto/pdf/qpdfpagerenderer/pdf-sample.pagerenderer.pdf b/tests/auto/pdf/qpdfpagerenderer/pdf-sample.pagerenderer.pdf Binary files differnew file mode 100644 index 000000000..c4e1aa36e --- /dev/null +++ b/tests/auto/pdf/qpdfpagerenderer/pdf-sample.pagerenderer.pdf diff --git a/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp b/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp new file mode 100644 index 000000000..39d32df0b --- /dev/null +++ b/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp @@ -0,0 +1,151 @@ +// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#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::RenderMode::SingleThreaded); +} + +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::Error::None); + + QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered); + + const QSize imageSize(100, 100); + const quint64 requestId = pageRenderer.requestPage(0, imageSize); + + QCOMPARE(requestId, quint64(1)); + QTRY_COMPARE(pageRenderedSpy.size(), 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::RenderMode::MultiThreaded); + + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::Error::None); + + QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered); + + const QSize imageSize(100, 100); + const quint64 requestId = pageRenderer.requestPage(0, imageSize); + + QCOMPARE(requestId, quint64(1)); + QTRY_COMPARE(pageRenderedSpy.size(), 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::Error::None); + + QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered); + + // render single threaded + const QSize imageSize(100, 100); + const quint64 firstRequestId = pageRenderer.requestPage(0, imageSize); + + QTRY_COMPARE(pageRenderedSpy.size(), 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::RenderMode::MultiThreaded); + + const quint64 secondRequestId = pageRenderer.requestPage(0, imageSize); + + QVERIFY(firstRequestId != secondRequestId); + QTRY_COMPARE(pageRenderedSpy.size(), 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::RenderMode::SingleThreaded); + + const quint64 thirdRequestId = pageRenderer.requestPage(0, imageSize); + + QTRY_COMPARE(pageRenderedSpy.size(), 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" diff --git a/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt b/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt new file mode 100644 index 000000000..668d1ea36 --- /dev/null +++ b/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_qpdfsearchmodel + SOURCES + tst_qpdfsearchmodel.cpp + LIBRARIES + Qt::Gui + Qt::Network + Qt::Pdf + TESTDATA + rotated_text.pdf + tagged_mcr_multipage.pdf + test.pdf +) diff --git a/tests/auto/pdf/qpdfsearchmodel/rotated_text.pdf b/tests/auto/pdf/qpdfsearchmodel/rotated_text.pdf new file mode 100644 index 000000000..d6d8db84e --- /dev/null +++ b/tests/auto/pdf/qpdfsearchmodel/rotated_text.pdf @@ -0,0 +1,70 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [ 0 0 200 200 ] + /Count 1 + /Kids [ 3 0 R ] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Resources << + /Font << + /F1 4 0 R + >> + >> + /Contents 5 0 R +>> +endobj +4 0 obj << + /Type /Font + /Subtype /Type1 + /BaseFont /Times-Roman +>> +endobj +5 0 obj << + /Length 406 +>> +stream +BT +0 0 Td +/F1 12 Tf +0.70710678118 -0.70710678118 0.70710678118 0.70710678118 100 100 Tm +(Hello,) Tj +0 0 Td +/F1 12 Tf +-0.70710678118 -0.70710678118 0.70710678118 -0.70710678118 100 100 Tm +( world!\r\n) Tj +0 0 Td +/F1 12 Tf +-0.70710678118 0.70710678118 -0.70710678118 -0.70710678118 100 100 Tm +(Goodbye,) Tj +0 0 Td +/F1 12 Tf +0.70710678118 0.70710678118 -0.70710678118 0.70710678118 100 100 Tm +( world!) Tj +ET +endstream +endobj +xref +0 6 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000161 00000 n +0000000287 00000 n +0000000365 00000 n +trailer << + /Root 1 0 R + /Size 6 +>> +startxref +823 +%%EOF diff --git a/tests/auto/pdf/qpdfsearchmodel/tagged_mcr_multipage.pdf b/tests/auto/pdf/qpdfsearchmodel/tagged_mcr_multipage.pdf new file mode 100644 index 000000000..fcc5fafda --- /dev/null +++ b/tests/auto/pdf/qpdfsearchmodel/tagged_mcr_multipage.pdf @@ -0,0 +1,136 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /MarkInfo << + /Type /MarkInfo + /Marked true + >> + /Pages 2 0 R + /StructTreeRoot 8 0 R +>> +endobj +2 0 obj << + /Type /Pages + /CropBox [ 10.8197 8.459 605.705 801.639 ] + /MediaBox [ 0.0 0.0 616.721 809.902 ] + /Count 2 + /Kids [ + 4 0 R + 6 0 R + ] +>> +endobj +3 0 obj << + /Type /Font + /Subtype /Type1 + /BaseFont /Times-Roman +>> +endobj +4 0 obj << + /Type /Page + /Tabs /S + /Parent 2 0 R + /StructParents 0 + /Contents 5 0 R + /Resources << + /ProcSet [/PDF /Text] + /Font << + /F1 3 0 R + >> + >> +>> +endobj +5 0 obj << + /Length 83 +>> +stream +BT +/Document <</MCID 0 >>BDC +0 i +/F1 1 Tf +12 0 0 12 43.073 771.625 Tm +(1)Tj +EMC +ET +endstream +endobj +6 0 obj << + /Type /Page + /Tabs /S + /Parent 2 0 R + /StructParents 1 + /Contents 7 0 R + /Resources << + /ProcSet [/PDF /Text] + /Font << + /F1 3 0 R + >> + >> +>> +endobj +7 0 obj << + /Length 83 +>> +stream +BT +/Document <</MCID 0 >>BDC +0 i +/F1 1 Tf +12 0 0 12 43.073 771.625 Tm +(2)Tj +EMC +ET +endstream +endobj +8 0 obj << + /Type /StructTreeRoot + /K 10 0 R + /ParentTree 9 0 R + /ParentTreeNextKey 2 +>> +endobj +9 0 obj << + /Nums [ + 0 + [10 0 R] + 1 + [10 0 R] + ] +>> +endobj +10 0 obj << + /T () + /S /Document + /P 8 0 R + /Pg 4 0 R + /K [ + 0 + << + /MCID 0 + /Pg 6 0 R + /Type /MCR + >> + ] +>> +%endobj +xref +0 11 +0000000000 65535 f +0000000015 00000 n +0000000149 00000 n +0000000315 00000 n +0000000393 00000 n +0000000575 00000 n +0000000709 00000 n +0000000891 00000 n +0000001025 00000 n +0000001125 00000 n +0000001198 00000 n +trailer << + /Root 1 0 R + /Size 11 +>> +startxref +1345 +%%EOF diff --git a/tests/auto/pdf/qpdfsearchmodel/test.pdf b/tests/auto/pdf/qpdfsearchmodel/test.pdf Binary files differnew file mode 100644 index 000000000..0832dfbed --- /dev/null +++ b/tests/auto/pdf/qpdfsearchmodel/test.pdf diff --git a/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp b/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp new file mode 100644 index 000000000..cf71b148e --- /dev/null +++ b/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#include <QtTest/QtTest> + +#include <QPdfDocument> +#include <QPdfSearchModel> + +Q_LOGGING_CATEGORY(lcTests, "qt.pdf.tests") + +class tst_QPdfSearchModel: public QObject +{ + Q_OBJECT + +public: + tst_QPdfSearchModel() {} + +private slots: + void findText_data(); + void findText(); +}; + +void tst_QPdfSearchModel::findText_data() +{ + QTest::addColumn<QString>("pdfPath"); + QTest::addColumn<QString>("searchString"); + QTest::addColumn<int>("expectedMatchCount"); + QTest::addColumn<int>("matchIndexToCheck"); + QTest::addColumn<int>("expectedRectangleCount"); + QTest::addColumn<int>("rectIndexToCheck"); + QTest::addColumn<QRect>("expectedMatchBounds"); + + QTest::newRow("the search for ai") << QFINDTESTDATA("test.pdf") + << "ai" << 3 << 0 << 1 << 0 << QRect(321, 202, 9, 11); + QTest::newRow("rotated text") << QFINDTESTDATA("rotated_text.pdf") + << "world!" << 2 << 0 << 1 << 0 << QRect(76, 102, 26, 28); + QTest::newRow("displaced text") << QFINDTESTDATA("tagged_mcr_multipage.pdf") + << "1" << 1 << 0 << 1 << 0 << QRect(34, 22, 3, 8); +} + +void tst_QPdfSearchModel::findText() +{ + QFETCH(QString, pdfPath); + QFETCH(QString, searchString); + QFETCH(int, expectedMatchCount); + QFETCH(int, matchIndexToCheck); + QFETCH(int, expectedRectangleCount); + QFETCH(int, rectIndexToCheck); + QFETCH(QRect, expectedMatchBounds); + + QPdfDocument document; + QCOMPARE(document.load(pdfPath), QPdfDocument::Error::None); + + QPdfSearchModel model; + model.setDocument(&document); + model.setSearchString(searchString); + + QTRY_COMPARE(model.count(), expectedMatchCount); // wait for the timer + QPdfLink match = model.resultAtIndex(matchIndexToCheck); + qCDebug(lcTests) << match; + QList<QRectF> rects = match.rectangles(); + QCOMPARE(rects.size(), expectedRectangleCount); + QCOMPARE(rects.at(rectIndexToCheck).toRect(), expectedMatchBounds); +} + +QTEST_MAIN(tst_QPdfSearchModel) + +#include "tst_qpdfsearchmodel.moc" |