blob: c40337a4ed64de07510e5b5e4af59510f3fd3315 [file] [log] [blame]
/* poppler-page.cc: qt interface to poppler
* Copyright (C) 2005, Net Integration Technologies, Inc.
* Copyright (C) 2005, Tobias Koening
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <poppler-qt.h>
#include <qfile.h>
#include <qimage.h>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Catalog.h>
#include <ErrorCodes.h>
#include <SplashOutputDev.h>
#include <TextOutputDev.h>
#include <splash/SplashBitmap.h>
#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) const
{
renderToPixmap(q, x, y, w, h, 72.0, 72.0);
}
void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, double xres, double yres) const
{
QImage img = renderToImage(xres, yres);
*q = new QPixmap( img );
}
QImage Page::renderToImage(double xres, double yres) const
{
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, false, 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;
}
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);
QString string = QString::fromUtf8(word->getText()->getCString());
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 = data->doc->data->doc.getCatalog()->getPage(data->index + 1);
return QSize( (int)p->getMediaWidth(), (int)p->getMediaHeight() );
}
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;
}
}
}