1#include <QtCore/QDebug>
2#include <QtCore/QFile>
3#include <QtWidgets/QApplication>
4#include <QtGui/QImage>
5#include <QtWidgets/QLabel>
6#include <QtGui/QMouseEvent>
7#include <QtGui/QPainter>
8#include <QtGui/QPaintEvent>
9#include <QtWidgets/QToolTip>
10#include <QtWidgets/QWidget>
11
12#include <poppler-qt6.h>
13
14class PDFDisplay : public QWidget // picture display widget
15{
16 Q_OBJECT
17public:
18 PDFDisplay(std::unique_ptr<Poppler::Document> &&d, bool qpainter, QWidget *parent = nullptr);
19 ~PDFDisplay() override;
20 void setShowTextRects(bool show);
21 void display();
22
23protected:
24 void paintEvent(QPaintEvent *) override;
25 void keyPressEvent(QKeyEvent *) override;
26 void mousePressEvent(QMouseEvent *) override;
27
28private:
29 int m_currentPage;
30 QImage image;
31 std::unique_ptr<Poppler::Document> doc;
32 QString backendString;
33 bool showTextRects;
34 std::vector<std::unique_ptr<Poppler::TextBox>> textRects;
35};
36
37PDFDisplay::PDFDisplay(std::unique_ptr<Poppler::Document> &&d, bool qpainter, QWidget *parent) : QWidget(parent)
38{
39 showTextRects = false;
40 doc = std::move(d);
41 m_currentPage = 0;
42 if (qpainter) {
43 backendString = QStringLiteral("QPainter");
44 doc->setRenderBackend(Poppler::Document::QPainterBackend);
45 } else {
46 backendString = QStringLiteral("Splash");
47 doc->setRenderBackend(Poppler::Document::SplashBackend);
48 }
49 doc->setRenderHint(hint: Poppler::Document::Antialiasing, on: true);
50 doc->setRenderHint(hint: Poppler::Document::TextAntialiasing, on: true);
51}
52
53void PDFDisplay::setShowTextRects(bool show)
54{
55 showTextRects = show;
56}
57
58void PDFDisplay::display()
59{
60 if (doc) {
61 std::unique_ptr<Poppler::Page> page = doc->page(index: m_currentPage);
62 if (page) {
63 qDebug() << "Displaying page using" << backendString << "backend: " << m_currentPage;
64 QTime t = QTime::currentTime();
65 image = page->renderToImage();
66 qDebug() << "Rendering took" << t.msecsTo(t: QTime::currentTime()) << "msecs";
67 if (showTextRects) {
68 QPainter painter(&image);
69 painter.setPen(Qt::red);
70 textRects = page->textList();
71 for (const std::unique_ptr<Poppler::TextBox> &tb : textRects) {
72 painter.drawRect(rect: tb->boundingBox());
73 }
74 } else {
75 textRects.clear();
76 }
77 update();
78 }
79 } else {
80 qWarning() << "doc not loaded";
81 }
82}
83
84PDFDisplay::~PDFDisplay() { }
85
86void PDFDisplay::paintEvent(QPaintEvent *e)
87{
88 QPainter paint(this); // paint widget
89 if (!image.isNull()) {
90 paint.drawImage(x: 0, y: 0, image);
91 } else {
92 qWarning() << "null image";
93 }
94}
95
96void PDFDisplay::keyPressEvent(QKeyEvent *e)
97{
98 if (e->key() == Qt::Key_Down) {
99 if (m_currentPage + 1 < doc->numPages()) {
100 m_currentPage++;
101 display();
102 }
103 } else if (e->key() == Qt::Key_Up) {
104 if (m_currentPage > 0) {
105 m_currentPage--;
106 display();
107 }
108 } else if (e->key() == Qt::Key_Q) {
109 exit(status: 0);
110 }
111}
112
113void PDFDisplay::mousePressEvent(QMouseEvent *e)
114{
115 int i = 0;
116 for (const std::unique_ptr<Poppler::TextBox> &tb : textRects) {
117 if (tb->boundingBox().contains(p: e->pos())) {
118 const QString tt = QStringLiteral("Text: \"%1\"\nIndex in text list: %2").arg(a: tb->text()).arg(a: i);
119 QToolTip::showText(pos: e->globalPosition().toPoint(), text: tt, w: this);
120 break;
121 }
122 ++i;
123 }
124}
125
126int main(int argc, char **argv)
127{
128 QApplication a(argc, argv); // QApplication required!
129
130 if (argc < 2 || (argc == 3 && strcmp(s1: argv[2], s2: "-extract") != 0 && strcmp(s1: argv[2], s2: "-qpainter") != 0 && strcmp(s1: argv[2], s2: "-textRects") != 0) || argc > 3) {
131 // use argument as file name
132 qWarning() << "usage: test-poppler-qt6 filename [-extract|-qpainter|-textRects]";
133 exit(status: 1);
134 }
135
136 std::unique_ptr<Poppler::Document> doc = Poppler::Document::load(filePath: QFile::decodeName(localFileName: argv[1]));
137 if (!doc) {
138 qWarning() << "doc not loaded";
139 exit(status: 1);
140 }
141
142 if (doc->isLocked()) {
143 qWarning() << "document locked (needs password)";
144 exit(status: 0);
145 }
146
147 // output some meta-data
148 auto pdfVersion = doc->getPdfVersion();
149 qDebug() << " PDF Version: " << qPrintable(QStringLiteral("%1.%2").arg(pdfVersion.major).arg(pdfVersion.minor));
150 qDebug() << " Title: " << doc->info(QStringLiteral("Title"));
151 qDebug() << " Subject: " << doc->info(QStringLiteral("Subject"));
152 qDebug() << " Author: " << doc->info(QStringLiteral("Author"));
153 qDebug() << " Key words: " << doc->info(QStringLiteral("Keywords"));
154 qDebug() << " Creator: " << doc->info(QStringLiteral("Creator"));
155 qDebug() << " Producer: " << doc->info(QStringLiteral("Producer"));
156 qDebug() << " Date created: " << doc->date(QStringLiteral("CreationDate")).toString();
157 qDebug() << " Date modified: " << doc->date(QStringLiteral("ModDate")).toString();
158 qDebug() << "Number of pages: " << doc->numPages();
159 qDebug() << " Linearised: " << doc->isLinearized();
160 qDebug() << " Encrypted: " << doc->isEncrypted();
161 qDebug() << " OK to print: " << doc->okToPrint();
162 qDebug() << " OK to copy: " << doc->okToCopy();
163 qDebug() << " OK to change: " << doc->okToChange();
164 qDebug() << "OK to add notes: " << doc->okToAddNotes();
165 qDebug() << " Page mode: " << doc->pageMode();
166 qDebug() << " Metadata: " << doc->metadata();
167
168 if (doc->hasEmbeddedFiles()) {
169 qDebug() << "Embedded files:";
170 foreach (Poppler::EmbeddedFile *file, doc->embeddedFiles()) {
171 qDebug() << " " << file->name();
172 }
173 qDebug();
174 } else {
175 qDebug() << "No embedded files";
176 }
177
178 if (doc->numPages() <= 0) {
179 qDebug() << "Doc has no pages";
180 return 0;
181 }
182
183 {
184 std::unique_ptr<Poppler::Page> page = doc->page(index: 0);
185 if (page) {
186 qDebug() << "Page 1 size: " << page->pageSize().width() / 72 << "inches x " << page->pageSize().height() / 72 << "inches";
187 }
188 }
189
190 if (argc == 2 || (argc == 3 && strcmp(s1: argv[2], s2: "-qpainter") == 0) || (argc == 3 && strcmp(s1: argv[2], s2: "-textRects") == 0)) {
191 bool useQPainter = (argc == 3 && strcmp(s1: argv[2], s2: "-qpainter") == 0);
192 PDFDisplay test(std::move(doc), useQPainter); // create picture display
193 test.setWindowTitle(QStringLiteral("Poppler-Qt6 Test"));
194 test.setShowTextRects(argc == 3 && strcmp(s1: argv[2], s2: "-textRects") == 0);
195 test.display();
196 test.show(); // show it
197
198 return a.exec(); // start event loop
199 } else {
200 std::unique_ptr<Poppler::Page> page = doc->page(index: 0);
201
202 QLabel *l = new QLabel(page->text(rect: QRectF()), nullptr);
203 l->show();
204 return a.exec();
205 }
206}
207
208#include "test-poppler-qt6.moc"
209

source code of poppler/qt6/tests/test-poppler-qt6.cpp