diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2024-03-20 22:15:43 -0700 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2024-03-27 07:47:16 +0100 |
commit | b0e44197db12f400dd3102ee96b5d64891de4340 (patch) | |
tree | 93441c211ab5e9ff859bd14a33151573e65b6d09 | |
parent | a08177e651dc302a3d22df014d3310c81fddc173 (diff) |
Convert "page" <-> "view" coordinates for PdfSelection and LinkModel
Use FPDF_PageToDevice() rather than subtracting from page height,
in all the remaining places where we were doing that.
Also use FPDF_DeviceToPage() to convert coordinates coming from
the view, for hit-testing links and for selecting ranges of text.
Mark the private utility functions that we're modifying const
while we're at it.
Task-number: QTBUG-100630
Fixes: QTBUG-106565
Change-Id: Ide4f73b80888a0e08381c6e4995f69ebeaa2d12f
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit b78c78349d786b294ee0845717ad5db38ae2565a)
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 5642f33e17aa82fd361b972cd8ac88ba83604273)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 61a65ca969aca620da334de4af14616433ee66a9)
-rw-r--r-- | src/pdf/qpdfdocument.cpp | 91 | ||||
-rw-r--r-- | src/pdf/qpdfdocument_p.h | 10 | ||||
-rw-r--r-- | src/pdf/qpdflinkmodel.cpp | 8 | ||||
-rw-r--r-- | tests/auto/pdf/qpdfdocument/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/pdf/qpdfdocument/rotated_text.pdf | 70 | ||||
-rw-r--r-- | tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf | 136 | ||||
-rw-r--r-- | tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp | 84 | ||||
-rw-r--r-- | tests/auto/pdfquick/multipageview/tst_multipageview.cpp | 2 |
8 files changed, 363 insertions, 40 deletions
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp index 11d886dc4..17fdb29b9 100644 --- a/src/pdf/qpdfdocument.cpp +++ b/src/pdf/qpdfdocument.cpp @@ -446,7 +446,7 @@ void QPdfDocumentPrivate::fpdf_AddSegment(_FX_DOWNLOADHINTS *pThis, size_t offse Q_UNUSED(size); } -QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int count) +QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int count) const { QList<ushort> buf(count + 1); // TODO is that enough space in case one unicode character is more than one in utf-16? @@ -455,23 +455,38 @@ QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int return QString::fromUtf16(reinterpret_cast<const char16_t *>(buf.constData()), len - 1); } -QPointF QPdfDocumentPrivate::getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex) +QPointF QPdfDocumentPrivate::getCharPosition(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const { double x, y; - int count = FPDFText_CountChars(textPage); - bool ok = FPDFText_GetCharOrigin(textPage, qMin(count - 1, charIndex), &x, &y); - if (!ok) - return QPointF(); - return QPointF(x, pageHeight - y); + const int count = FPDFText_CountChars(textPage); + if (FPDFText_GetCharOrigin(textPage, qMin(count - 1, charIndex), &x, &y)) + return mapPageToView(pdfPage, x, y); + return {}; } -QRectF QPdfDocumentPrivate::getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex) +QRectF QPdfDocumentPrivate::getCharBox(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const { double l, t, r, b; - bool ok = FPDFText_GetCharBox(textPage, charIndex, &l, &r, &b, &t); - if (!ok) - return QRectF(); - return QRectF(l, pageHeight - t, r - l, t - b); + if (FPDFText_GetCharBox(textPage, charIndex, &l, &r, &b, &t)) + return mapPageToView(pdfPage, l, t, r, b); + return {}; +} + +/*! \internal + Convert the point \a x , \a y to the usual 1x (pixels = points) + 4th-quadrant "view" coordinate system relative to the top-left corner of + the rendered page. Some PDF files have internal transforms that make this + coordinate system different from "page coordinates", so we cannot just + subtract from page height to invert the y coordinates, in general. + */ +QPointF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double x, double y) const +{ + const auto pageHeight = FPDF_GetPageHeight(pdfPage); + const auto pageWidth = FPDF_GetPageWidth(pdfPage); + int rx, ry; + if (FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, x, y, &rx, &ry)) + return QPointF(rx, ry); + return {}; } /*! \internal @@ -482,14 +497,31 @@ QRectF QPdfDocumentPrivate::getCharBox(FPDF_TEXTPAGE textPage, double pageHeight system different from "page coordinates", so we cannot just subtract from page height to invert the y coordinates, in general. */ -QRectF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom) +QRectF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom) const { const auto pageHeight = FPDF_GetPageHeight(pdfPage); const auto pageWidth = FPDF_GetPageWidth(pdfPage); int xfmLeft, xfmTop, xfmRight, xfmBottom; - FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, left, top, &xfmLeft, &xfmTop); - FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, right, bottom, &xfmRight, &xfmBottom); - return QRectF(xfmLeft, xfmTop, xfmRight - xfmLeft, xfmBottom - xfmTop); + if ( FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, left, top, &xfmLeft, &xfmTop) && + FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, right, bottom, &xfmRight, &xfmBottom) ) + return QRectF(xfmLeft, xfmTop, xfmRight - xfmLeft, xfmBottom - xfmTop); + return {}; +} + +/*! \internal + Convert the point \a x , \a y \a from the usual 1x (pixels = points) + 4th-quadrant "view" coordinate system relative to the top-left corner of + the rendered page, to "page coordinates" suited to the given \a pdfPage, + which may have arbitrary internal transforms. + */ +QPointF QPdfDocumentPrivate::mapViewToPage(FPDF_PAGE pdfPage, QPointF position) const +{ + const auto pageHeight = FPDF_GetPageHeight(pdfPage); + const auto pageWidth = FPDF_GetPageWidth(pdfPage); + double rx, ry; + if (FPDF_DeviceToPage(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, position.x(), position.y(), &rx, &ry)) + return QPointF(rx, ry); + return {}; } QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF position) @@ -498,14 +530,14 @@ QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF TextPosition result; FPDF_PAGE pdfPage = FPDF_LoadPage(doc, page); - double pageHeight = FPDF_GetPageHeight(pdfPage); FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage); - int hitIndex = FPDFText_GetCharIndexAtPos(textPage, position.x(), pageHeight - position.y(), + const QPointF pagePos = mapViewToPage(pdfPage, position); + int hitIndex = FPDFText_GetCharIndexAtPos(textPage, pagePos.x(), pagePos.y(), CharacterHitTolerance, CharacterHitTolerance); if (hitIndex >= 0) { - QPointF charPos = getCharPosition(textPage, pageHeight, hitIndex); + QPointF charPos = getCharPosition(pdfPage, textPage, hitIndex); if (!charPos.isNull()) { - QRectF charBox = getCharBox(textPage, pageHeight, hitIndex); + QRectF charBox = getCharBox(pdfPage, textPage, hitIndex); // If the given position is past the end of the line, i.e. if the right edge of the found character's // bounding box is closer to it than the left edge is, we say that we "hit" the next character index after if (qAbs(charBox.right() - position.x()) < qAbs(charPos.x() - position.x())) { @@ -949,11 +981,12 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end) { const QPdfMutexLocker lock; FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page); - double pageHeight = FPDF_GetPageHeight(pdfPage); + const QPointF pageStart = d->mapViewToPage(pdfPage, start); + const QPointF pageEnd = d->mapViewToPage(pdfPage, end); FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage); - int startIndex = FPDFText_GetCharIndexAtPos(textPage, start.x(), pageHeight - start.y(), + int startIndex = FPDFText_GetCharIndexAtPos(textPage, pageStart.x(), pageStart.y(), CharacterHitTolerance, CharacterHitTolerance); - int endIndex = FPDFText_GetCharIndexAtPos(textPage, end.x(), pageHeight - end.y(), + int endIndex = FPDFText_GetCharIndexAtPos(textPage, pageEnd.x(), pageEnd.y(), CharacterHitTolerance, CharacterHitTolerance); QPdfSelection result; @@ -964,7 +997,7 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end) // If the given end position is past the end of the line, i.e. if the right edge of the last character's // bounding box is closer to it than the left edge is, then extend the char range by one - QRectF endCharBox = d->getCharBox(textPage, pageHeight, endIndex); + QRectF endCharBox = d->getCharBox(pdfPage, textPage, endIndex); if (qAbs(endCharBox.right() - end.x()) < qAbs(endCharBox.x() - end.x())) ++endIndex; @@ -976,7 +1009,7 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end) for (int i = 0; i < rectCount; ++i) { double l, r, b, t; FPDFText_GetRect(textPage, i, &l, &t, &r, &b); - QRectF rect(l, pageHeight - t, r - l, t - b); + const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b); if (hull.isNull()) hull = rect; else @@ -1006,7 +1039,6 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma return {}; const QPdfMutexLocker lock; FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page); - double pageHeight = FPDF_GetPageHeight(pdfPage); FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage); int pageCount = FPDFText_CountChars(textPage); if (startIndex >= pageCount) @@ -1021,7 +1053,7 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma for (int i = 0; i < rectCount; ++i) { double l, r, b, t; FPDFText_GetRect(textPage, i, &l, &t, &r, &b); - QRectF rect(l, pageHeight - t, r - l, t - b); + const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b); if (hull.isNull()) hull = rect; else @@ -1030,7 +1062,7 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma } } if (bounds.isEmpty()) - hull = QRectF(d->getCharPosition(textPage, pageHeight, startIndex), QSizeF()); + hull = QRectF(d->getCharPosition(pdfPage, textPage, startIndex), QSizeF()); qCDebug(qLcDoc) << "on page" << page << "at index" << startIndex << "maxLength" << maxLength << "got" << text.size() << "chars," << rectCount << "rects within" << hull; @@ -1047,7 +1079,6 @@ QPdfSelection QPdfDocument::getAllText(int page) { const QPdfMutexLocker lock; FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page); - double pageHeight = FPDF_GetPageHeight(pdfPage); FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage); int count = FPDFText_CountChars(textPage); if (count < 1) @@ -1059,7 +1090,7 @@ QPdfSelection QPdfDocument::getAllText(int page) for (int i = 0; i < rectCount; ++i) { double l, r, b, t; FPDFText_GetRect(textPage, i, &l, &t, &r, &b); - QRectF rect(l, pageHeight - t, r - l, t - b); + const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b); if (hull.isNull()) hull = rect; else diff --git a/src/pdf/qpdfdocument_p.h b/src/pdf/qpdfdocument_p.h index 5ec485012..12092c4ad 100644 --- a/src/pdf/qpdfdocument_p.h +++ b/src/pdf/qpdfdocument_p.h @@ -78,10 +78,12 @@ public: static int fpdf_GetBlock(void* param, unsigned long position, unsigned char* pBuf, unsigned long size); static void fpdf_AddSegment(struct _FX_DOWNLOADHINTS* pThis, size_t offset, size_t size); void updateLastError(); - QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count); - QPointF getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex); - QRectF getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex); - QRectF mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom); + QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count) const; + QPointF getCharPosition(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const; + QRectF getCharBox(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const; + QPointF mapPageToView(FPDF_PAGE pdfPage, double x, double y) const; + QRectF mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom) const; + QPointF mapViewToPage(FPDF_PAGE pdfPage, QPointF position) const; // FPDF takes the rotation parameter as an int. // This enum is mapping the int values defined in fpdfview.h:956. diff --git a/src/pdf/qpdflinkmodel.cpp b/src/pdf/qpdflinkmodel.cpp index 366b77344..645dff21a 100644 --- a/src/pdf/qpdflinkmodel.cpp +++ b/src/pdf/qpdflinkmodel.cpp @@ -179,7 +179,6 @@ void QPdfLinkModelPrivate::update() qCWarning(qLcLink) << "failed to load page" << page; return; } - double pageHeight = FPDF_GetPageHeight(pdfPage); q->beginResetModel(); links.clear(); @@ -204,8 +203,7 @@ void QPdfLinkModelPrivate::update() std::swap(rect.bottom, rect.top); QPdfLink linkData; - linkData.d->rects << QRectF(rect.left, pageHeight - rect.top, - rect.right - rect.left, rect.top - rect.bottom); + linkData.d->rects << document->d->mapPageToView(pdfPage, rect.left, rect.top, rect.right, rect.bottom); FPDF_DEST dest = FPDFLink_GetDest(doc, linkAnnot); FPDF_ACTION action = FPDFLink_GetAction(linkAnnot); switch (FPDFAction_GetType(action)) { @@ -224,7 +222,7 @@ void QPdfLinkModelPrivate::update() break; // at least we got a page number, so the link will jump there } if (hasX && hasY) - linkData.d->location = QPointF(x, pageHeight - y); + linkData.d->location = document->d->mapPageToView(pdfPage, x, y); if (hasZoom) linkData.d->zoom = zoom; break; @@ -287,7 +285,7 @@ void QPdfLinkModelPrivate::update() double left, top, right, bottom; bool success = FPDFLink_GetRect(webLinks, i, r, &left, &top, &right, &bottom); if (success) { - linkData.d->rects << QRectF(left, pageHeight - top, right - left, top - bottom); + linkData.d->rects << document->d->mapPageToView(pdfPage, left, top, right, bottom); links << linkData; } } diff --git a/tests/auto/pdf/qpdfdocument/CMakeLists.txt b/tests/auto/pdf/qpdfdocument/CMakeLists.txt index aadc192b3..b8300ef27 100644 --- a/tests/auto/pdf/qpdfdocument/CMakeLists.txt +++ b/tests/auto/pdf/qpdfdocument/CMakeLists.txt @@ -12,5 +12,7 @@ qt_internal_add_test(tst_qpdfdocument 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/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/tst_qpdfdocument.cpp b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp index 6bb007e7f..d222bff0c 100644 --- a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp +++ b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp @@ -36,6 +36,10 @@ private slots: void passwordClearedOnClose(); void metaData(); void pageLabels(); + void getSelection_data(); + void getSelection(); + void getSelectionAtIndex_data(); + void getSelectionAtIndex(); private: void consistencyCheck(QPdfDocument &doc) const; @@ -394,6 +398,86 @@ void tst_QPdfDocument::pageLabels() 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/pdfquick/multipageview/tst_multipageview.cpp b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp index b64cd47b1..c5e0b30db 100644 --- a/tests/auto/pdfquick/multipageview/tst_multipageview.cpp +++ b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp @@ -62,7 +62,7 @@ void tst_MultiPageView::internalLink_data() QTest::addColumn<qreal>("expectedZoom"); QTest::addColumn<QPoint>("expectedScroll"); - QTest::newRow("first link") << 0 << 1 << qreal(1) << QPoint(134, 1276); + QTest::newRow("first link") << 0 << 1 << qreal(1) << QPoint(134, 1286); // TODO fails because it zooms out, and the view leaves gaps between pages currently // QTest::newRow("second link") << 1 << 2 << qreal(0.5) << QPoint(0, 717); } |