-
Notifications
You must be signed in to change notification settings - Fork 0
/
pdfimagegenerator.cpp
137 lines (107 loc) · 3.76 KB
/
pdfimagegenerator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# include <QPainter>
# include "pdfimagegenerator.h"
QMatrix PdfImageGenerator::highlightScaleMatrix = QMatrix();
PdfImageGenerator::PdfImageGenerator(const QString &docloc, const int &dpix, const int &dpiy, QObject *parent) : QObject(parent) {
this->pdfDocument = Poppler::Document::load(docloc);
if (pdfDocument) {
pdfDocument->setRenderHint(Poppler::Document::Antialiasing);
pdfDocument->setRenderHint(Poppler::Document::TextAntialiasing);
minpasses = (pdfDocument->numPages() >=2)? 2 : 1;
}
dpiX = dpix;
dpiY = dpiy;
avgw = avgh = passes = 0;
}
PdfImageGenerator::~PdfImageGenerator() {
delete this->pdfDocument;
}
void PdfImageGenerator::requestPage(const int &pnum, const QRectF &matchHighlight) {
if (pnum >= 0) {
if (requestedPages.size() >= 3) {
requestedPages.pop_front();
}
this->requestedPages.append(QPair<int,QRectF>(pnum, matchHighlight));
}
}
void PdfImageGenerator::clearBacklog() {
this->requestedPages.clear();
}
void PdfImageGenerator::setScalefactor(const qreal &sf) {
scaleFactor = sf;
highlightScaleMatrix = QMatrix(scaleFactor * dpiX / 72.0, 0, 0, scaleFactor * dpiY / 72.0, 0, 0);
/* upon resolution change, the pagesize is invalidated */
pageSize = QSize(-1,-1);
avgw = avgh = passes = 0;
}
qreal PdfImageGenerator::getScaleFactor() {
return this->scaleFactor;
}
void PdfImageGenerator::setPageSize(const QSize &s) {
this->pageSize = s;
}
int PdfImageGenerator::getPageCount() {
return this->pdfDocument->numPages();
}
bool PdfImageGenerator::isGood() {
return this->pdfDocument != 0;
}
QDomDocument* PdfImageGenerator::getTocDomDoc() {
return this->pdfDocument->toc();
}
/* === private method implementation ========= */
QImage PdfImageGenerator::generateImage(const int &pno) {
Poppler::Page* pdfPage = this->pdfDocument->page(pno);
QImage image;
if (pdfPage) {
if (!pageSize.isValid()) {
image = pdfPage->renderToImage(dpiX * scaleFactor, dpiY * scaleFactor);
} else {
image = pdfPage->renderToImage(dpiX * scaleFactor, dpiY * scaleFactor, -1, -1, pageSize.width(), pageSize.height());
}
delete pdfPage;
}
return image;
}
void PdfImageGenerator::startGeneration(void) {
int page;
QRectF highlight;
QImage img;
QPair<int,QRectF> demand;
while (!this->requestedPages.isEmpty()) {
demand = requestedPages.takeLast();
page = demand.first;
highlight = demand.second;
img = generateImage(page);
if (!img.isNull()) {
/* image size estimation */
if (this->passes < this->minpasses) {
++passes;
avgw += img.width();
avgh += img.height();
}
/* search result highlight
* cuts out the highlighted word and darkens the rest of the page */
if (highlight.isValid()) {
QRect highlightRect = scaleHighlightRect(highlight);
highlightRect.adjust(-2, -2, 2, 2);
QImage hImage = img.copy(highlightRect);
QPainter painter;
painter.begin(&img);
painter.fillRect(img.rect(), QColor(0, 0, 0, 32));
painter.drawImage(highlightRect, hImage);
painter.end();
}
emit imageFinished(img, page);
}
}
if (this->passes == minpasses) {
pageSize.setWidth((int)(avgw/passes));
pageSize.setHeight((int)(avgh/passes));
++passes;
emit newPageSize(pageSize);
}
emit generationFinished();
}
QRect PdfImageGenerator::scaleHighlightRect(const QRectF &r) const {
return highlightScaleMatrix.mapRect(r).toRect();
}