summaryrefslogtreecommitdiffstats
path: root/kfile-plugins/pdf/poppler-qt/poppler-page.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kfile-plugins/pdf/poppler-qt/poppler-page.cc')
-rw-r--r--kfile-plugins/pdf/poppler-qt/poppler-page.cc362
1 files changed, 362 insertions, 0 deletions
diff --git a/kfile-plugins/pdf/poppler-qt/poppler-page.cc b/kfile-plugins/pdf/poppler-qt/poppler-page.cc
new file mode 100644
index 00000000..a42aa15c
--- /dev/null
+++ b/kfile-plugins/pdf/poppler-qt/poppler-page.cc
@@ -0,0 +1,362 @@
+/* poppler-page.cc: qt interface to poppler
+ * Copyright (C) 2005, Net Integration Technologies, Inc.
+ * Copyright (C) 2005-2006, Albert Astals Cid <aacid@kde.org>
+ * Copyright (C) 2005, Tobias Koening <tokoe@kde.org>
+ * Copyright (C) 2005, Stefan Kebekus <stefan.kebekus@math.uni-koeln.de>
+ * Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at>
+ * Copyright (C) 2006, Jerry Epplin <jepplin@globalvelocity.com>
+ * Copyright (C) 2007, 2010, Pino Toscano <pino@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <poppler-qt.h>
+#include <qfile.h>
+#include <qimage.h>
+#include <config.h>
+#include <GlobalParams.h>
+#include <PDFDoc.h>
+#include <Catalog.h>
+#include <ErrorCodes.h>
+#include <TextOutputDev.h>
+#include <Link.h>
+#if defined(HAVE_SPLASH)
+#include <SplashOutputDev.h>
+#include <splash/SplashBitmap.h>
+#endif
+
+#include "poppler-private.h"
+#include "poppler-page-transition-private.h"
+
+namespace Poppler {
+
+class PageData {
+ public:
+ const Document *doc;
+ int index;
+ PageTransition *transition;
+};
+
+Page::Page(const Document *doc, int index) {
+ data = new PageData();
+ data->index = index;
+ data->doc = doc;
+ data->transition = 0;
+}
+
+Page::~Page()
+{
+ delete data->transition;
+ delete data;
+}
+
+void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, bool doLinks) const
+{
+ renderToPixmap(q, x, y, w, h, 72.0, 72.0, doLinks);
+}
+
+void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, double xres, double yres, bool doLinks) const
+{
+ QImage img = renderToImage(xres, yres, doLinks);
+ *q = new QPixmap( img );
+}
+
+QImage Page::renderToImage(double xres, double yres, bool doLinks) const
+{
+#if defined(HAVE_SPLASH)
+ SplashOutputDev *output_dev;
+ SplashBitmap *bitmap;
+ SplashColorPtr color_ptr;
+ output_dev = data->doc->data->getOutputDev();
+
+ data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, xres, yres,
+ 0, false, true, false, -1, -1, -1, -1);
+ bitmap = output_dev->getBitmap ();
+ color_ptr = bitmap->getDataPtr ();
+ int bw = output_dev->getBitmap()->getWidth();
+ int bh = output_dev->getBitmap()->getHeight();
+ SplashColorPtr dataPtr = output_dev->getBitmap()->getDataPtr();
+
+ if (QImage::BigEndian == QImage::systemByteOrder())
+ {
+ uchar c;
+ int count = bw * bh * 4;
+ for (int k = 0; k < count; k += 4)
+ {
+ c = dataPtr[k];
+ dataPtr[k] = dataPtr[k+3];
+ dataPtr[k+3] = c;
+
+ c = dataPtr[k+1];
+ dataPtr[k+1] = dataPtr[k+2];
+ dataPtr[k+2] = c;
+ }
+ }
+
+ // construct a qimage SHARING the raw bitmap data in memory
+ QImage img( dataPtr, bw, bh, 32, 0, 0, QImage::IgnoreEndian );
+ img = img.copy();
+ // unload underlying xpdf bitmap
+ output_dev->startPage( 0, NULL );
+
+ return img;
+#else
+ (void)xres;
+ (void)xres;
+ (void)doLinks;
+
+ return QImage();
+#endif
+}
+
+QString Page::getText(const Rectangle &r) const
+{
+ TextOutputDev *output_dev;
+ GooString *s;
+ PDFRectangle *rect;
+ QString result;
+ ::Page *p;
+
+ output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);
+ data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72,
+ 0, false, false, false, -1, -1, -1, -1);
+ p = data->doc->data->doc.getCatalog()->getPage(data->index + 1);
+ if (r.isNull())
+ {
+ rect = p->getCropBox();
+ s = output_dev->getText(rect->x1, rect->y1, rect->x2, rect->y2);
+ }
+ else
+ {
+ double height, y1, y2;
+ height = p->getCropHeight();
+ y1 = height - r.m_y2;
+ y2 = height - r.m_y1;
+ s = output_dev->getText(r.m_x1, y1, r.m_x2, y2);
+ }
+
+ result = QString::fromUtf8(s->getCString());
+
+ delete output_dev;
+ delete s;
+ return result;
+}
+
+QValueList<TextBox*> Page::textList() const
+{
+ TextOutputDev *output_dev;
+
+ QValueList<TextBox*> output_list;
+
+ output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);
+
+ data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72,
+ 0, false, false, false, -1, -1, -1, -1);
+
+ TextWordList *word_list = output_dev->makeWordList();
+
+ if (!word_list) {
+ delete output_dev;
+ return output_list;
+ }
+
+ for (int i = 0; i < word_list->getLength(); i++) {
+ TextWord *word = word_list->get(i);
+ GooString *word_str = word->getText();
+ QString string = QString::fromUtf8(word_str->getCString());
+ delete word_str;
+ double xMin, yMin, xMax, yMax;
+ word->getBBox(&xMin, &yMin, &xMax, &yMax);
+
+ TextBox* text_box = new TextBox(string, Rectangle(xMin, yMin, xMax, yMax));
+
+ output_list.append(text_box);
+ }
+
+ delete word_list;
+ delete output_dev;
+
+ return output_list;
+}
+
+PageTransition *Page::getTransition() const
+{
+ if (!data->transition)
+ {
+ Object o;
+ PageTransitionParams params;
+ params.dictObj = data->doc->data->doc.getCatalog()->getPage(data->index + 1)->getTrans(&o);
+ data->transition = new PageTransition(params);
+ o.free();
+ }
+ return data->transition;
+}
+
+QSize Page::pageSize() const
+{
+ ::Page *p;
+
+ p = data->doc->data->doc.getCatalog()->getPage(data->index + 1);
+ if ( ( Page::Landscape == orientation() ) || (Page::Seascape == orientation() ) ) {
+ return QSize( (int)p->getCropHeight(), (int)p->getCropWidth() );
+ } else {
+ return QSize( (int)p->getCropWidth(), (int)p->getCropHeight() );
+ }
+}
+
+Page::Orientation Page::orientation() const
+{
+ ::Page *p = data->doc->data->doc.getCatalog()->getPage(data->index + 1);
+
+ int rotation = p->getRotate();
+ switch (rotation) {
+ case 90:
+ return Page::Landscape;
+ break;
+ case 180:
+ return Page::UpsideDown;
+ break;
+ case 270:
+ return Page::Seascape;
+ break;
+ default:
+ return Page::Portrait;
+ }
+}
+
+QValueList<Link*> Page::links() const
+{
+ QValueList<Link*> popplerLinks;
+
+#if defined(HAVE_SPLASH)
+ Links *xpdfLinks = data->doc->data->doc.getLinks(data->index + 1);
+ for (int i = 0; i < xpdfLinks->getNumLinks(); ++i)
+ {
+ ::Link *xpdfLink = xpdfLinks->getLink(i);
+
+ double left, top, right, bottom;
+ int leftAux, topAux, rightAux, bottomAux;
+ xpdfLink->getRect( &left, &top, &right, &bottom );
+ QRect linkArea;
+
+ data->doc->data->m_outputDev->cvtUserToDev( left, top, &leftAux, &topAux );
+ data->doc->data->m_outputDev->cvtUserToDev( right, bottom, &rightAux, &bottomAux );
+ linkArea.setLeft(leftAux);
+ linkArea.setTop(topAux);
+ linkArea.setRight(rightAux);
+ linkArea.setBottom(bottomAux);
+
+ if (!xpdfLink->isOk()) continue;
+
+ Link *popplerLink = NULL;
+ ::LinkAction *a = xpdfLink->getAction();
+ if ( a )
+ {
+ switch ( a->getKind() )
+ {
+ case actionGoTo:
+ {
+ LinkGoTo * g = (LinkGoTo *) a;
+ // create link: no ext file, namedDest, object pointer
+ popplerLink = new LinkGoto( linkArea, QString::null, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), data->doc->data ) ) );
+ }
+ break;
+
+ case actionGoToR:
+ {
+ LinkGoToR * g = (LinkGoToR *) a;
+ // copy link file
+ const QString fileName = UnicodeParsedString( g->getFileName() );
+ // ceate link: fileName, namedDest, object pointer
+ popplerLink = new LinkGoto( linkArea, fileName, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), data->doc->data ) ) );
+ }
+ break;
+
+ case actionLaunch:
+ {
+ LinkLaunch * e = (LinkLaunch *)a;
+ GooString * p = e->getParams();
+ popplerLink = new LinkExecute( linkArea, e->getFileName()->getCString(), p ? p->getCString() : 0 );
+ }
+ break;
+
+ case actionNamed:
+ {
+ const char * name = ((LinkNamed *)a)->getName()->getCString();
+ if ( !strcmp( name, "NextPage" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::PageNext );
+ else if ( !strcmp( name, "PrevPage" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::PagePrev );
+ else if ( !strcmp( name, "FirstPage" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::PageFirst );
+ else if ( !strcmp( name, "LastPage" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::PageLast );
+ else if ( !strcmp( name, "GoBack" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::HistoryBack );
+ else if ( !strcmp( name, "GoForward" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::HistoryForward );
+ else if ( !strcmp( name, "Quit" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::Quit );
+ else if ( !strcmp( name, "GoToPage" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::GoToPage );
+ else if ( !strcmp( name, "Find" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::Find );
+ else if ( !strcmp( name, "FullScreen" ) )
+ popplerLink = new LinkAction( linkArea, LinkAction::Presentation );
+ else if ( !strcmp( name, "Close" ) )
+ {
+ // acroread closes the document always, doesnt care whether
+ // its presentation mode or not
+ // popplerLink = new LinkAction( linkArea, LinkAction::EndPresentation );
+ popplerLink = new LinkAction( linkArea, LinkAction::Close );
+ }
+ else
+ {
+ // TODO
+ }
+ }
+ break;
+
+ case actionURI:
+ {
+ popplerLink = new LinkBrowse( linkArea, ((LinkURI *)a)->getURI()->getCString() );
+ }
+ break;
+
+ case actionMovie:
+ case actionSound:
+ case actionRendition:
+ case actionJavaScript:
+ case actionOCGState:
+ break;
+
+ case actionUnknown:
+ break;
+ }
+ }
+
+ if (popplerLink)
+ {
+ popplerLinks.append(popplerLink);
+ }
+ }
+
+ delete xpdfLinks;
+#endif
+
+ return popplerLinks;
+}
+
+}