1
/* poppler-page.cc: qt interface to poppler
2
* Copyright (C) 2005, Net Integration Technologies, Inc.
3
* Copyright (C) 2005-2006, 2010 Albert Astals Cid <aacid@kde.org>
4
* Copyright (C) 2005, Tobias Koening <tokoe@kde.org>
5
* Copyright (C) 2005, Stefan Kebekus <stefan.kebekus@math.uni-koeln.de>
6
* Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at>
7
* Copyright (C) 2006, Jerry Epplin <jepplin@globalvelocity.com>
8
* Copyright (C) 2007, 2010, Pino Toscano <pino@kde.org>
9
* Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2, or (at your option)
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
26
#include <poppler-qt.h>
30
#include <GlobalParams.h>
33
#include <ErrorCodes.h>
34
#include <TextOutputDev.h>
36
#if defined(HAVE_SPLASH)
37
#include <SplashOutputDev.h>
38
#include <splash/SplashBitmap.h>
41
#include "poppler-private.h"
42
#include "poppler-page-transition-private.h"
46
Page::Page(const Document *doc, int index) {
47
data = new PageData();
51
data->page = doc->data->doc.getPage(data->index + 1);
56
delete data->transition;
60
void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, bool doLinks) const
62
renderToPixmap(q, x, y, w, h, 72.0, 72.0, doLinks);
65
void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, double xres, double yres, bool doLinks) const
67
QImage img = renderToImage(xres, yres, doLinks);
68
*q = new QPixmap( img );
71
QImage Page::renderToImage(double xres, double yres, bool doLinks) const
73
#if defined(HAVE_SPLASH)
74
SplashOutputDev *output_dev;
76
SplashColorPtr color_ptr;
77
output_dev = data->doc->data->getOutputDev();
79
data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, xres, yres,
80
0, false, true, false, -1, -1, -1, -1);
81
bitmap = output_dev->getBitmap ();
82
color_ptr = bitmap->getDataPtr ();
83
int bw = output_dev->getBitmap()->getWidth();
84
int bh = output_dev->getBitmap()->getHeight();
85
SplashColorPtr dataPtr = output_dev->getBitmap()->getDataPtr();
87
if (QImage::BigEndian == QImage::systemByteOrder())
90
int count = bw * bh * 4;
91
for (int k = 0; k < count; k += 4)
94
dataPtr[k] = dataPtr[k+3];
98
dataPtr[k+1] = dataPtr[k+2];
103
// construct a qimage SHARING the raw bitmap data in memory
104
QImage img( dataPtr, bw, bh, 32, 0, 0, QImage::IgnoreEndian );
106
// unload underlying xpdf bitmap
107
output_dev->startPage( 0, NULL );
119
QString Page::getText(const Rectangle &r) const
121
TextOutputDev *output_dev;
127
output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);
128
data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72,
129
0, false, false, false, -1, -1, -1, -1);
133
rect = p->getCropBox();
134
s = output_dev->getText(rect->x1, rect->y1, rect->x2, rect->y2);
138
double height, y1, y2;
139
height = p->getCropHeight();
140
y1 = height - r.m_y2;
141
y2 = height - r.m_y1;
142
s = output_dev->getText(r.m_x1, y1, r.m_x2, y2);
145
result = QString::fromUtf8(s->getCString());
152
QValueList<TextBox*> Page::textList() const
154
TextOutputDev *output_dev;
156
QValueList<TextBox*> output_list;
158
output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);
160
data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72,
161
0, false, false, false, -1, -1, -1, -1);
163
TextWordList *word_list = output_dev->makeWordList();
170
for (int i = 0; i < word_list->getLength(); i++) {
171
TextWord *word = word_list->get(i);
172
GooString *word_str = word->getText();
173
QString string = QString::fromUtf8(word_str->getCString());
175
double xMin, yMin, xMax, yMax;
176
word->getBBox(&xMin, &yMin, &xMax, &yMax);
178
TextBox* text_box = new TextBox(string, Rectangle(xMin, yMin, xMax, yMax));
180
output_list.append(text_box);
189
PageTransition *Page::getTransition() const
191
if (!data->transition)
194
PageTransitionParams params;
195
params.dictObj = data->page->getTrans(&o);
196
data->transition = new PageTransition(params);
199
return data->transition;
202
QSize Page::pageSize() const
207
if ( ( Page::Landscape == orientation() ) || (Page::Seascape == orientation() ) ) {
208
return QSize( (int)p->getCropHeight(), (int)p->getCropWidth() );
210
return QSize( (int)p->getCropWidth(), (int)p->getCropHeight() );
214
Page::Orientation Page::orientation() const
216
::Page *p = data->page;
218
int rotation = p->getRotate();
221
return Page::Landscape;
224
return Page::UpsideDown;
227
return Page::Seascape;
230
return Page::Portrait;
234
QValueList<Link*> Page::links() const
236
QValueList<Link*> popplerLinks;
238
#if defined(HAVE_SPLASH)
239
Links *xpdfLinks = data->doc->data->doc.getLinks(data->index + 1);
240
for (int i = 0; i < xpdfLinks->getNumLinks(); ++i)
242
::Link *xpdfLink = xpdfLinks->getLink(i);
244
double left, top, right, bottom;
245
int leftAux, topAux, rightAux, bottomAux;
246
xpdfLink->getRect( &left, &top, &right, &bottom );
249
data->doc->data->m_outputDev->cvtUserToDev( left, top, &leftAux, &topAux );
250
data->doc->data->m_outputDev->cvtUserToDev( right, bottom, &rightAux, &bottomAux );
251
linkArea.setLeft(leftAux);
252
linkArea.setTop(topAux);
253
linkArea.setRight(rightAux);
254
linkArea.setBottom(bottomAux);
256
if (!xpdfLink->isOk()) continue;
258
Link *popplerLink = NULL;
259
::LinkAction *a = xpdfLink->getAction();
262
switch ( a->getKind() )
266
LinkGoTo * g = (LinkGoTo *) a;
267
// create link: no ext file, namedDest, object pointer
268
popplerLink = new LinkGoto( linkArea, QString::null, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), data->doc->data ) ) );
274
LinkGoToR * g = (LinkGoToR *) a;
276
const QString fileName = UnicodeParsedString( g->getFileName() );
277
// ceate link: fileName, namedDest, object pointer
278
popplerLink = new LinkGoto( linkArea, fileName, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), data->doc->data ) ) );
284
LinkLaunch * e = (LinkLaunch *)a;
285
GooString * p = e->getParams();
286
popplerLink = new LinkExecute( linkArea, e->getFileName()->getCString(), p ? p->getCString() : 0 );
292
const char * name = ((LinkNamed *)a)->getName()->getCString();
293
if ( !strcmp( name, "NextPage" ) )
294
popplerLink = new LinkAction( linkArea, LinkAction::PageNext );
295
else if ( !strcmp( name, "PrevPage" ) )
296
popplerLink = new LinkAction( linkArea, LinkAction::PagePrev );
297
else if ( !strcmp( name, "FirstPage" ) )
298
popplerLink = new LinkAction( linkArea, LinkAction::PageFirst );
299
else if ( !strcmp( name, "LastPage" ) )
300
popplerLink = new LinkAction( linkArea, LinkAction::PageLast );
301
else if ( !strcmp( name, "GoBack" ) )
302
popplerLink = new LinkAction( linkArea, LinkAction::HistoryBack );
303
else if ( !strcmp( name, "GoForward" ) )
304
popplerLink = new LinkAction( linkArea, LinkAction::HistoryForward );
305
else if ( !strcmp( name, "Quit" ) )
306
popplerLink = new LinkAction( linkArea, LinkAction::Quit );
307
else if ( !strcmp( name, "GoToPage" ) )
308
popplerLink = new LinkAction( linkArea, LinkAction::GoToPage );
309
else if ( !strcmp( name, "Find" ) )
310
popplerLink = new LinkAction( linkArea, LinkAction::Find );
311
else if ( !strcmp( name, "FullScreen" ) )
312
popplerLink = new LinkAction( linkArea, LinkAction::Presentation );
313
else if ( !strcmp( name, "Close" ) )
315
// acroread closes the document always, doesnt care whether
316
// its presentation mode or not
317
// popplerLink = new LinkAction( linkArea, LinkAction::EndPresentation );
318
popplerLink = new LinkAction( linkArea, LinkAction::Close );
329
popplerLink = new LinkBrowse( linkArea, ((LinkURI *)a)->getURI()->getCString() );
335
case actionRendition:
336
case actionJavaScript:
347
popplerLinks.append(popplerLink);