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-24 01:00:53 +0000
commit541b00830fdd12f91a9da5426536abc4787f4859 (patch)
tree1bb4173d8daab240ce2362707186519c5b064bb5
parent2c1e2472e634062b35c93c8325f7692d5237c409 (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. Pick-to: 6.6 6.5 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>
-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) {