summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2024-03-20 21:16:11 -0700
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-03-26 03:33:27 +0000
commita08177e651dc302a3d22df014d3310c81fddc173 (patch)
tree798c6b20899fd97eee3bb07465c78ede131e83c5
parent1aebeea6527248d7fb7f7a951ecb8570a710cf63 (diff)
Convert search result bounds to account for PDF transforms
As a drive-by, remove unneeded includes. QPdfDocumentPrivate::convertPageRect() will be useful for fixing related bugs. If PDF files can contain arbitrary transforms, and "page coordinates" returned from pdfium functions are not already converted, then it's never ok to just subtract from page height to invert the y's. Fixes: QTBUG-120764 Change-Id: Iffce528c0c5e66c499e7147078b7b8718f7610ce Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> (cherry picked from commit fccbc33d95c17b0911fd4cbd97998acfc8e6320f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 541b00830fdd12f91a9da5426536abc4787f4859) (cherry picked from commit 496b935279e3dfd94b3c4bf5e01bb70ef91a3138)
-rw-r--r--src/pdf/qpdfdocument.cpp18
-rw-r--r--src/pdf/qpdfdocument_p.h1
-rw-r--r--src/pdf/qpdfsearchmodel.cpp12
3 files changed, 26 insertions, 5 deletions
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index 6de2fbc6c..11d886dc4 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -474,6 +474,24 @@ QRectF QPdfDocumentPrivate::getCharBox(FPDF_TEXTPAGE textPage, double pageHeight
return QRectF(l, pageHeight - t, r - l, t - b);
}
+/*! \internal
+ Convert the bounding box defined by \a left \a top \a right and \a bottom
+ to the usual 1x (pixels = points) 4th-quadrant "view" coordinate system
+ that we use for rendering things on top of the page image.
+ 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.
+ */
+QRectF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom)
+{
+ 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);
+}
+
QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF position)
{
const QPdfMutexLocker lock;
diff --git a/src/pdf/qpdfdocument_p.h b/src/pdf/qpdfdocument_p.h
index 4adbf695e..5ec485012 100644
--- a/src/pdf/qpdfdocument_p.h
+++ b/src/pdf/qpdfdocument_p.h
@@ -81,6 +81,7 @@ public:
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);
// 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/qpdfsearchmodel.cpp b/src/pdf/qpdfsearchmodel.cpp
index 78dfe06fa..abe0122bf 100644
--- a/src/pdf/qpdfsearchmodel.cpp
+++ b/src/pdf/qpdfsearchmodel.cpp
@@ -3,12 +3,11 @@
#include "qpdfdocument_p.h"
#include "qpdflink.h"
-#include "qpdflink_p.h"
#include "qpdfsearchmodel.h"
#include "qpdfsearchmodel_p.h"
-#include "third_party/pdfium/public/fpdf_doc.h"
#include "third_party/pdfium/public/fpdf_text.h"
+#include "third_party/pdfium/public/fpdfview.h"
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qloggingcategory.h>
@@ -251,7 +250,6 @@ bool QPdfSearchModelPrivate::doSearch(int page)
qWarning() << "failed to load page" << page;
return false;
}
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
if (!textPage) {
qWarning() << "failed to load text of page" << page;
@@ -269,9 +267,12 @@ bool QPdfSearchModelPrivate::doSearch(int page)
int startIndex = -1;
int endIndex = -1;
for (int r = 0; r < rectCount; ++r) {
+ // get bounding box of search result in page coordinates
double left, top, right, bottom;
FPDFText_GetRect(textPage, r, &left, &top, &right, &bottom);
- rects << QRectF(left, pageHeight - top, right - left, top - bottom);
+ // deal with any internal PDF transforms and
+ // convert to the 1x (pixels = points) 4th-quadrant coordinate system
+ rects << document->d->mapPageToView(pdfPage, left, top, right, bottom);
if (r == 0) {
startIndex = FPDFText_GetCharIndexAtPos(textPage, left, top,
CharacterHitTolerance, CharacterHitTolerance);
@@ -280,7 +281,8 @@ bool QPdfSearchModelPrivate::doSearch(int page)
endIndex = FPDFText_GetCharIndexAtPos(textPage, right, top,
CharacterHitTolerance, CharacterHitTolerance);
}
- qCDebug(qLcS) << rects.last() << "char idx" << startIndex << "->" << endIndex;
+ qCDebug(qLcS) << rects.last() << "char idx" << startIndex << "->" << endIndex
+ << "from page rect" << left << top << right << bottom;
}
QString contextBefore, contextAfter;
if (startIndex >= 0 || endIndex >= 0) {