7#include "third_party/pdfium/public/fpdf_doc.h"
8#include "third_party/pdfium/public/fpdf_text.h"
12#include <QElapsedTimer>
15#include <QLoggingCategory>
21#include <QtCore/private/qtools_p.h>
42 QMetaEnum rolesMetaEnum = doc->metaObject()->enumerator(doc->metaObject()->indexOfEnumerator(
"PageModelRole"));
46 m_roleNames.insert(
r,
name);
63 return document()->pageLabel(
index.row());
65 return document()->pagePointSize(
index.row());
72 return pageThumbnail(
index.row());
74 return document()->pageLabel(
index.row());
91 auto size = doc->pagePointSize(
page);
109 , loadComplete(
false)
123 qCDebug(qLcDoc) <<
"FPDF_InitLibrary took" <<
timer.elapsed() <<
"ms";
132 FX_FILEAVAIL::version = 1;
136 FX_DOWNLOADHINTS::version = 1;
147 qCDebug(qLcDoc) <<
"FPDF_DestroyLibrary";
148 FPDF_DestroyLibrary();
157 FPDF_CloseDocument(
doc);
161 FPDFAvail_Destroy(
avail);
168 emit q->pageModelChanged();
189 const unsigned long error = FPDF_GetLastError();
208 if (transferDeviceOwnership)
220 qWarning() <<
"QPdfDocument: Loading from sequential devices only supported with QNetworkAccessManager.";
231 this->setStatus(QPdfDocument::Status::Error);
257 const int newPageCount = FPDF_GetPageCount(
doc);
262 emit q->pageModelChanged();
288 if (!contentLength.
isValid()) {
304 m_FileLen = totalSize;
308 avail = FPDFAvail_Create(
this,
this);
329 switch (FPDFAvail_IsDocAvail(
avail,
this)) {
331 qCDebug(qLcDoc) <<
"error loading";
333 case PDF_DATA_NOTAVAIL:
334 qCDebug(qLcDoc) <<
"data not yet available";
352 FPDF_CloseDocument(
doc);
356 emit q->passwordRequired();
375 const int newPageCount = FPDF_GetPageCount(
doc);
376 for (
int i = 0;
i < newPageCount; ++
i) {
377 int result = PDF_DATA_NOTAVAIL;
378 while (
result == PDF_DATA_NOTAVAIL) {
382 if (
result == PDF_DATA_ERROR)
392 emit q->pageModelChanged();
408 int result = PDF_DATA_NOTAVAIL;
409 while (
result == PDF_DATA_NOTAVAIL)
413 if (
result == PDF_DATA_ERROR)
416 return (
result != PDF_DATA_ERROR);
421 if (
status == documentStatus)
431 return offset + size <= static_cast<quint64>(
d->device->size());
438 return qMax(
qint64(0),
d->device->read(
reinterpret_cast<char *
>(pBuf),
size));
453 int len = FPDFText_GetText(textPage, startIndex,
count,
buf.data());
461 int count = FPDFText_CountChars(textPage);
462 bool ok = FPDFText_GetCharOrigin(textPage,
qMin(
count - 1, charIndex), &
x, &
y);
471 bool ok = FPDFText_GetCharBox(textPage, charIndex, &l, &
r, &
b, &
t);
474 return QRectF(l, pageHeight -
t,
r - l,
t -
b);
482 FPDF_PAGE pdfPage = FPDF_LoadPage(
doc,
page);
483 double pageHeight = FPDF_GetPageHeight(pdfPage);
484 FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
485 int hitIndex = FPDFText_GetCharIndexAtPos(textPage,
position.x(), pageHeight -
position.y(),
497 qCDebug(qLcDoc) <<
"on page" <<
page <<
"@" <<
position <<
"got char position" << charPos <<
"index" << hitIndex;
502 FPDFText_ClosePage(textPage);
503 FPDF_ClosePage(pdfPage);
549 d->
load(
f.release(),
true);
558QString QPdfDocument::fileName()
const
562 return f->fileName();
659 fieldName =
"ModDate";
667 const unsigned long len = FPDF_GetMetaText(d->
doc, fieldName.
constData(),
nullptr, 0);
817 const unsigned long len = FPDF_GetPageLabel(d->
doc,
page,
nullptr, 0);
862 FPDF_PAGE pdfPage = FPDF_LoadPage(d->
doc,
page);
870 const QPdfDocumentRenderOptions::RenderFlags renderFlags = renderOptions.
renderFlags();
875 flags |= FPDF_LCD_TEXT;
877 flags |= FPDF_GRAYSCALE;
879 flags |= FPDF_RENDER_FORCEHALFTONE;
881 flags |= FPDF_RENDER_NO_SMOOTHTEXT;
883 flags |= FPDF_RENDER_NO_SMOOTHIMAGE;
885 flags |= FPDF_RENDER_NO_SMOOTHPATH;
891 float x0 = clipRect.
left();
892 float y0 = clipRect.
top();
893 float x1 = clipRect.
left();
896 float y2 = clipRect.
top();
920 FPDFBitmap_Destroy(
bitmap);
922 FPDF_ClosePage(pdfPage);
933 FPDF_PAGE pdfPage = FPDF_LoadPage(d->
doc,
page);
934 double pageHeight = FPDF_GetPageHeight(pdfPage);
935 FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
936 int startIndex = FPDFText_GetCharIndexAtPos(textPage,
start.x(), pageHeight -
start.y(),
938 int endIndex = FPDFText_GetCharIndexAtPos(textPage,
end.x(), pageHeight -
end.y(),
943 if (startIndex >= 0 && endIndex != startIndex) {
944 if (startIndex > endIndex)
945 qSwap(startIndex, endIndex);
953 int count = endIndex - startIndex;
957 int rectCount = FPDFText_CountRects(textPage, startIndex, endIndex - startIndex);
958 for (
int i = 0;
i < rectCount; ++
i) {
960 FPDFText_GetRect(textPage,
i, &l, &
t, &
r, &
b);
974 FPDFText_ClosePage(textPage);
975 FPDF_ClosePage(pdfPage);
990 FPDF_PAGE pdfPage = FPDF_LoadPage(d->
doc,
page);
991 double pageHeight = FPDF_GetPageHeight(pdfPage);
992 FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
993 int pageCount = FPDFText_CountChars(textPage);
1002 rectCount = FPDFText_CountRects(textPage, startIndex,
text.
size());
1003 for (
int i = 0;
i < rectCount; ++
i) {
1005 FPDFText_GetRect(textPage,
i, &l, &
t, &
r, &
b);
1017 <<
"got" <<
text.
size() <<
"chars," << rectCount <<
"rects within" << hull;
1019 FPDFText_ClosePage(textPage);
1020 FPDF_ClosePage(pdfPage);
1031 FPDF_PAGE pdfPage = FPDF_LoadPage(d->
doc,
page);
1032 double pageHeight = FPDF_GetPageHeight(pdfPage);
1033 FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
1034 int count = FPDFText_CountChars(textPage);
1040 int rectCount = FPDFText_CountRects(textPage, 0,
count);
1041 for (
int i = 0;
i < rectCount; ++
i) {
1043 FPDFText_GetRect(textPage,
i, &l, &
t, &
r, &
b);
1051 qCDebug(qLcDoc) <<
"on page" <<
page <<
"got" <<
count <<
"chars," << rectCount <<
"rects within" << hull;
1053 FPDFText_ClosePage(textPage);
1054 FPDF_ClosePage(pdfPage);
1061#include "qpdfdocument.moc"
1062#include "moc_qpdfdocument.cpp"
IOBluetoothDevice * device
void endResetModel()
Completes a model reset operation.
virtual QHash< int, QByteArray > roleNames() const
void beginResetModel()
Begins a model reset operation.
QObject * parent() const
Returns a pointer to the parent object.
bool open(OpenMode openMode) override
\reimp
void setData(const QByteArray &data)
Sets the contents of the internal buffer to be data.
void close() override
\reimp
qint64 size() const override
\reimp
bool seek(qint64 off) override
\reimp
QByteArrayView trimmed() const noexcept
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
void clear()
Clears the contents of the byte array and makes it null.
\inmodule QtCore \reentrant
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
bool isEmpty() const noexcept
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
NetworkError error() const
Returns the error that was found during the processing of this request.
QVariant header(QNetworkRequest::KnownHeaders header) const
Returns the value of the known header header, if that header was sent by the remote server.
void finished()
This signal is emitted when the reply has finished processing.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
TextPosition hitTest(int page, QPointF position)
void _q_copyFromSequentialSourceDevice()
void _q_tryLoadingWithSizeFromContentHeader()
QPointer< QIODevice > device
void load(QIODevice *device, bool ownDevice)
static void fpdf_AddSegment(struct _FX_DOWNLOADHINTS *pThis, size_t offset, size_t size)
static FPDF_BOOL fpdf_IsDataAvail(struct _FX_FILEAVAIL *pThis, size_t offset, size_t size)
QPdfDocument::Status status
bool checkPageComplete(int page)
void initiateAsyncLoadWithTotalSizeKnown(quint64 totalSize)
QScopedPointer< QIODevice > ownDevice
static constexpr QFPDFRotation toFPDFRotation(QPdfDocumentRenderOptions::Rotation rotation)
QPointer< QIODevice > sequentialSourceDevice
QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count)
QRectF getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex)
static int fpdf_GetBlock(void *param, unsigned long position, unsigned char *pBuf, unsigned long size)
QPdfPageModel * pageModel
QPdfDocument::Error lastError
QPointF getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex)
void setStatus(QPdfDocument::Status status)
constexpr RenderFlags renderFlags() const noexcept
constexpr Rotation rotation() const noexcept
constexpr QSize scaledSize() const noexcept
constexpr QRect scaledClipRect() const noexcept
The QPdfDocument class loads a PDF document and renders pages from it.
Error error() const
Returns the type of error if \l status is Error, or NoError if there is no error.
QString password
This property holds the document password.
QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options=QPdfDocumentRenderOptions())
Renders the page into a QImage of size imageSize according to the provided renderOptions.
Status status
This property holds the current status of the document.
void close()
Closes the document.
MetaDataField
This enum describes the available fields of meta data.
QAbstractListModel * pageModel
This property holds an instance of QAbstractListModel to provide page-specific metadata,...
Q_INVOKABLE QPdfSelection getAllText(int page)
Returns all the text and its bounds on the given page.
Status
This enum describes the current status of the document.
~QPdfDocument() override
Destroys the document.
Q_INVOKABLE QPdfSelection getSelectionAtIndex(int page, int startIndex, int maxLength)
Returns information about the text on the given page that can be found beginning at the given startIn...
PageModelRole
Roles in pageModel().
int pageCount
This property holds the number of pages in the loaded document or 0 if no document is loaded.
Error
This enum describes the error while attempting the last operation on the document.
@ UnsupportedSecurityScheme
Q_INVOKABLE QPdfSelection getSelection(int page, QPointF start, QPointF end)
Returns information about the text on the given page that can be found between the given start and en...
QVariant metaData(MetaDataField field) const
Returns the meta data of the document for the given field.
Q_INVOKABLE int pageIndexForLabel(QAnyStringView label)
Returns the index of the page that has the label, or -1 if not found.
Q_INVOKABLE QString pageLabel(int page)
Returns the page number to be used for display purposes.
void setPassword(const QString &password)
Error load(const QString &fileName)
Loads the document contents from fileName.
void statusChanged(QPdfDocument::Status status)
friend class QPdfPageModel
Q_INVOKABLE QSizeF pagePointSize(int page) const
Returns the size of page page in points (1/72 of an inch).
int rowCount(const QModelIndex &=QModelIndex()) const override
Returns the number of rows under the given parent.
QPdfPageModel(QPdfDocument *doc)
QHash< int, QByteArray > roleNames() const override
QVariant data(const QModelIndex &index, int role) const override
Returns the data stored under the given role for the item referred to by the index.
The QPdfSelection class defines a range of text that has been selected on one page in a PDF document,...
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr void setX(qreal x) noexcept
Sets the x coordinate of this point to the given finite x coordinate.
bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0.0 (ignoring the sign); otherwise returns fa...
The QPolygonF class provides a list of points using floating point precision.
\inmodule QtCore\reentrant
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr bool isNull() const noexcept
Returns true if the rectangle is a null rectangle, otherwise returns false.
QRectF united(const QRectF &other) const noexcept
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
\inmodule QtCore\reentrant
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
const_iterator constEnd() const noexcept
const_iterator constFind(const T &value) const
constexpr qreal width() const noexcept
Returns the width.
constexpr qreal height() const noexcept
Returns the height.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isNull() const noexcept
Returns true if both the width and height is 0; otherwise returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
QString & replace(qsizetype i, qsizetype len, QChar after)
void chop(qsizetype n)
Removes n characters from the end of the string.
static QString fromUtf16(const char16_t *, qsizetype size=-1)
qsizetype size() const
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
QString & insert(qsizetype i, QChar c)
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray toUtf8() const &
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
qulonglong toULongLong(bool *ok=nullptr) const
Returns the variant as an unsigned long long int if the variant has type() \l QMetaType::ULongLong,...
The QVector2D class represents a vector or vertex in 2D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
QSet< QString >::iterator it
Combined button and popup list for selecting options.
constexpr char toAsciiLower(char ch) noexcept
emscripten::val document()
DBusConnection const char DBusError * error
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLfloat GLfloat GLfloat x1
GLenum GLenum GLsizei count
GLuint GLsizei const GLchar * label
[43]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum const GLint * param
GLenum GLuint GLintptr offset
GLuint GLfloat GLfloat y0
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
GLfixed GLfixed GLfixed y2
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
GLdouble GLdouble GLdouble GLdouble q
static QT_BEGIN_NAMESPACE int libraryRefCount
static const double CharacterHitTolerance
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
unsigned long long quint64
obj metaObject() -> className()
\inmodule QtCore \reentrant
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent