blob: 680fd0c80326c1113f976e0d5a0de464e27b1f2f [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"
namespace Poppler {
class PageTransitionData {
public:
Object *trans;
};
//------------------------------------------------------------------------
// PageTransition
//------------------------------------------------------------------------
PageTransition::PageTransition(const PageTransitionData &data)
: type(Replace),
duration(1),
alignment(Horizontal),
direction(Inward),
angle(0),
scale(1.0),
rectangular(false)
{
Object obj;
Object *dictObj = data.trans;
if (dictObj->isDict()) {
Dict *transDict = dictObj->getDict();
if (transDict->lookup("S", &obj)->isName()) {
const char *s = obj.getName();
if (strcmp("R", s) == 0)
type = Replace;
else if (strcmp("Split", s) == 0)
type = Split;
else if (strcmp("Blinds", s) == 0)
type = Blinds;
else if (strcmp("Box", s) == 0)
type = Box;
else if (strcmp("Wipe", s) == 0)
type = Wipe;
else if (strcmp("Dissolve", s) == 0)
type = Dissolve;
else if (strcmp("Glitter", s) == 0)
type = Glitter;
else if (strcmp("Fly", s) == 0)
type = Fly;
else if (strcmp("Push", s) == 0)
type = Push;
else if (strcmp("Cover", s) == 0)
type = Cover;
else if (strcmp("Uncover", s) == 0)
type = Push;
else if (strcmp("Fade", s) == 0)
type = Cover;
}
obj.free();
if (transDict->lookup("D", &obj)->isInt()) {
duration = obj.getInt();
}
obj.free();
if (transDict->lookup("Dm", &obj)->isName()) {
const char *dm = obj.getName();
if ( strcmp( "H", dm ) == 0 )
alignment = Horizontal;
else if ( strcmp( "V", dm ) == 0 )
alignment = Vertical;
}
obj.free();
if (transDict->lookup("M", &obj)->isName()) {
const char *m = obj.getName();
if ( strcmp( "I", m ) == 0 )
direction = Inward;
else if ( strcmp( "O", m ) == 0 )
direction = Outward;
}
obj.free();
if (transDict->lookup("Di", &obj)->isInt()) {
angle = obj.getInt();
}
obj.free();
if (transDict->lookup("Di", &obj)->isName()) {
if ( strcmp( "None", obj.getName() ) == 0 )
angle = 0;
}
obj.free();
if (transDict->lookup("SS", &obj)->isReal()) {
scale = obj.getReal();
}
obj.free();
if (transDict->lookup("B", &obj)->isBool()) {
rectangular = obj.getBool();
}
obj.free();
}
}
PageTransition::~PageTransition()
{
}
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
{
SplashOutputDev *output_dev;
SplashColor white;
SplashBitmap *bitmap;
white.rgb8 = splashMakeRGB8(255,255,255);
SplashColorPtr color_ptr;
output_dev = new SplashOutputDev(splashModeRGB8, gFalse, white);
output_dev->startDoc(data->doc->data->doc.getXRef ());
data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72,
0, -1, -1, -1, -1,
true,
false);
bitmap = output_dev->getBitmap ();
color_ptr = bitmap->getDataPtr ();
QImage * img = new QImage( (uchar*)color_ptr.rgb8, bitmap->getWidth(), bitmap->getHeight(), 32, 0, 0, QImage::IgnoreEndian );
*q = new QPixmap( *img );
delete img;
delete output_dev;
}
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, -1, -1, -1, -1,
true,
false);
p = data->doc->data->doc.getCatalog()->getPage(data->index + 1);
if (r.isNull())
{
rect = p->getBox();
s = output_dev->getText(rect->x1, rect->y1, rect->x2, rect->y2);
}
else
{
double height, y1, y2;
height = p->getHeight();
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;
}
PageTransition *Page::getTransition() const
{
if (!data->transition)
{
Object o;
PageTransitionData ptd;
ptd.trans = data->doc->data->doc.getCatalog()->getPage(data->index + 1)->getTrans(&o);
data->transition = new PageTransition(ptd);
o.free();
}
return data->transition;
}
}