|
|
|
|
|
|
|
#include "XPDFRenderer.h"
|
|
|
|
|
|
|
|
#include <QtGui>
|
|
|
|
|
|
|
|
#include <frameworks/UBPlatformUtils.h>
|
|
|
|
|
|
|
|
#include <splash/SplashBitmap.h>
|
|
|
|
#include <xpdf/Object.h>
|
|
|
|
#include <xpdf/GlobalParams.h>
|
|
|
|
#include <xpdf/SplashOutputDev.h>
|
|
|
|
#include <xpdf/PDFDoc.h>
|
|
|
|
|
|
|
|
QAtomicInt XPDFRenderer::sInstancesCount = 0;
|
|
|
|
|
|
|
|
XPDFRenderer::XPDFRenderer(const QString &filename)
|
|
|
|
: mDocument(0)
|
|
|
|
{
|
|
|
|
if (!globalParams)
|
|
|
|
{
|
|
|
|
// globalParams must be allocated once and never be deleted
|
|
|
|
// note that this is *not* an instance variable of this XPDFRenderer class
|
|
|
|
globalParams = new GlobalParams(0);
|
|
|
|
globalParams->setupBaseFonts(QFile::encodeName(UBPlatformUtils::applicationResourcesDirectory() + "/" + "fonts").data());
|
|
|
|
//globalParams->setPrintCommands(gTrue);
|
|
|
|
}
|
|
|
|
|
|
|
|
mDocument = new PDFDoc(new GString(filename.toUtf8().data()), 0, 0, 0); // the filename GString is deleted on PDFDoc desctruction
|
|
|
|
sInstancesCount.ref();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
XPDFRenderer::~XPDFRenderer()
|
|
|
|
{
|
|
|
|
if (mDocument)
|
|
|
|
{
|
|
|
|
delete mDocument;
|
|
|
|
sInstancesCount.deref();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sInstancesCount == 0 && globalParams)
|
|
|
|
{
|
|
|
|
delete globalParams;
|
|
|
|
globalParams = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XPDFRenderer::isValid() const
|
|
|
|
{
|
|
|
|
if (mDocument)
|
|
|
|
{
|
|
|
|
return mDocument->isOk();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int XPDFRenderer::pageCount() const
|
|
|
|
{
|
|
|
|
if (isValid())
|
|
|
|
return mDocument->getNumPages();
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString XPDFRenderer::title() const
|
|
|
|
{
|
|
|
|
if (isValid())
|
|
|
|
{
|
|
|
|
Object pdfInfo;
|
|
|
|
mDocument->getDocInfo(&pdfInfo);
|
|
|
|
if (pdfInfo.isDict())
|
|
|
|
{
|
|
|
|
Object title;
|
|
|
|
Dict *infoDict = pdfInfo.getDict();
|
|
|
|
if (infoDict->lookup((char*)"Title", &title)->isString())
|
|
|
|
{
|
|
|
|
GString *gstring = title.getString();
|
|
|
|
return QString(gstring->getCString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QSizeF XPDFRenderer::pageSizeF(int pageNumber) const
|
|
|
|
{
|
|
|
|
qreal cropWidth = 0;
|
|
|
|
qreal cropHeight = 0;
|
|
|
|
|
|
|
|
if (isValid())
|
|
|
|
{
|
|
|
|
int rotate = mDocument->getPageRotate(pageNumber);
|
|
|
|
|
|
|
|
cropWidth = mDocument->getPageCropWidth(pageNumber);
|
|
|
|
cropHeight = mDocument->getPageCropHeight(pageNumber);
|
|
|
|
|
|
|
|
if ((rotate == 90) || (rotate == 270))
|
|
|
|
{
|
|
|
|
cropWidth = mDocument->getPageCropHeight(pageNumber);
|
|
|
|
cropHeight = mDocument->getPageCropWidth(pageNumber);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QSizeF(cropWidth, cropHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int XPDFRenderer::pageRotation(int pageNumber) const
|
|
|
|
{
|
|
|
|
if (mDocument)
|
|
|
|
return mDocument->getPageRotate(pageNumber);
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void XPDFRenderer::render(QPainter *p, int pageNumber, const QRectF &bounds)
|
|
|
|
{
|
|
|
|
if (isValid())
|
|
|
|
{
|
|
|
|
SplashColor paperColor = {0xFF, 0xFF, 0xFF}; // white
|
|
|
|
SplashOutputDev splash(splashModeRGB8, 1, gFalse, paperColor);
|
|
|
|
splash.startDoc(mDocument->getXRef());
|
|
|
|
int hResolution = 72;
|
|
|
|
int vResolution = 72;
|
|
|
|
int rotation = 0; // in degrees (get it from the worldTransform if we want to support rotation)
|
|
|
|
GBool useMediaBox = gFalse;
|
|
|
|
GBool crop = gTrue;
|
|
|
|
GBool printing = gFalse;
|
|
|
|
const qreal xScale = p->worldTransform().m11();
|
|
|
|
const qreal yScale = p->worldTransform().m22();
|
|
|
|
qreal sliceX = 0.;
|
|
|
|
qreal sliceY = 0.;
|
|
|
|
|
|
|
|
if (bounds.isNull())
|
|
|
|
{
|
|
|
|
mDocument->displayPage(&splash, pageNumber, hResolution * xScale, vResolution * yScale,
|
|
|
|
rotation, useMediaBox, crop, printing);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sliceX = bounds.x() * xScale;
|
|
|
|
sliceY = bounds.y() * yScale;
|
|
|
|
qreal sliceW = bounds.width() * xScale;
|
|
|
|
qreal sliceH = bounds.height() * yScale;
|
|
|
|
|
|
|
|
mDocument->displayPageSlice(&splash, pageNumber, hResolution * xScale, vResolution * yScale,
|
|
|
|
rotation, useMediaBox, crop, printing, sliceX, sliceY, sliceW, sliceH);
|
|
|
|
}
|
|
|
|
|
|
|
|
SplashBitmap *bitmap = splash.getBitmap();
|
|
|
|
QImage pdfImage(bitmap->getDataPtr(), bitmap->getWidth(), bitmap->getHeight(), bitmap->getWidth() * 3, QImage::Format_RGB888);
|
|
|
|
|
|
|
|
QTransform savedTransform = p->worldTransform();
|
|
|
|
p->resetTransform();
|
|
|
|
p->drawImage(QPointF(savedTransform.dx() + sliceX, savedTransform.dy() + sliceY), pdfImage);
|
|
|
|
p->setWorldTransform(savedTransform);
|
|
|
|
}
|
|
|
|
}
|