XPDFRenderer.cpp 5.26 KB
Newer Older
Claudio Valerio's avatar
Claudio Valerio committed
1 2 3
/*
 * 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
Claudio Valerio's avatar
Claudio Valerio committed
4
 * the Free Software Foundation, either version 2 of the License, or
Claudio Valerio's avatar
Claudio Valerio committed
5 6 7 8 9 10 11 12 13 14
 * (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, see <http://www.gnu.org/licenses/>.
 */
Claudio Valerio's avatar
Claudio Valerio committed
15 16 17 18 19 20 21

#include "XPDFRenderer.h"

#include <QtGui>

#include <frameworks/UBPlatformUtils.h>

22 23
#include "core/memcheck.h"

Claudio Valerio's avatar
Claudio Valerio committed
24 25
QAtomicInt XPDFRenderer::sInstancesCount = 0;

Didier's avatar
Didier committed
26
XPDFRenderer::XPDFRenderer(const QString &filename, bool importingFile)
Claudio Valerio's avatar
Claudio Valerio committed
27
    : mDocument(0)
Claudio Valerio's avatar
Claudio Valerio committed
28 29
    , mpSplashBitmap(0)
    , mSplash(0)
Claudio Valerio's avatar
Claudio Valerio committed
30
{
31
    Q_UNUSED(importingFile);
Claudio Valerio's avatar
Claudio Valerio committed
32 33 34 35 36 37 38 39 40 41 42 43 44 45
    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());
    }

    mDocument = new PDFDoc(new GString(filename.toUtf8().data()), 0, 0, 0); // the filename GString is deleted on PDFDoc desctruction
    sInstancesCount.ref();
}

XPDFRenderer::~XPDFRenderer()
{
Claudio Valerio's avatar
Claudio Valerio committed
46 47 48 49 50
    if(mSplash){
        delete mSplash;
        mSplash = NULL;
    }

Claudio Valerio's avatar
Claudio Valerio committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
    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);

115 116
		cropWidth = mDocument->getPageCropWidth(pageNumber) * this->dpiForRendering / 72.0;
        cropHeight = mDocument->getPageCropHeight(pageNumber) * this->dpiForRendering / 72.0;
Claudio Valerio's avatar
Claudio Valerio committed
117

118
        if (rotate == 90 || rotate == 270)
Claudio Valerio's avatar
Claudio Valerio committed
119
        {
120 121 122 123
            //switching width and height
			qreal tmpVar = cropWidth;
			cropWidth = cropHeight;
			cropHeight = tmpVar;
Claudio Valerio's avatar
Claudio Valerio committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137
        }
    }
    return QSizeF(cropWidth, cropHeight);
}


int XPDFRenderer::pageRotation(int pageNumber) const
{
    if (mDocument)
        return  mDocument->getPageRotate(pageNumber);
    else
        return 0;
}

138
void XPDFRenderer::render(QPainter *p, int pageNumber, const QRectF &bounds)
139
{
Didier's avatar
Didier committed
140 141 142 143 144
    if (isValid())
    {
        qreal xscale = p->worldTransform().m11();
        qreal yscale = p->worldTransform().m22();

145
        QImage *pdfImage = createPDFImage(pageNumber, xscale, yscale, bounds);
Didier's avatar
Didier committed
146 147
        QTransform savedTransform = p->worldTransform();
        p->resetTransform();
Claudio Valerio's avatar
Claudio Valerio committed
148
        p->drawImage(QPointF(savedTransform.dx() + mSliceX, savedTransform.dy() + mSliceY), *pdfImage);
Didier's avatar
Didier committed
149
        p->setWorldTransform(savedTransform);
150
        delete pdfImage;
151
	}
Didier's avatar
Didier committed
152 153
}

154
QImage* XPDFRenderer::createPDFImage(int pageNumber, qreal xscale, qreal yscale, const QRectF &bounds)
Didier's avatar
Didier committed
155
{
Claudio Valerio's avatar
Claudio Valerio committed
156 157 158
    if (isValid())
    {
        SplashColor paperColor = {0xFF, 0xFF, 0xFF}; // white
Claudio Valerio's avatar
Claudio Valerio committed
159 160
        if(mSplash)
            delete mSplash;
Didier's avatar
Didier committed
161 162
        mSplash = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
        mSplash->startDoc(mDocument->getXRef());
Claudio Valerio's avatar
Claudio Valerio committed
163 164 165 166
        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;
Didier's avatar
Didier committed
167 168
        mSliceX = 0.;
        mSliceY = 0.;
Claudio Valerio's avatar
Claudio Valerio committed
169 170 171

        if (bounds.isNull())
        {
172
			mDocument->displayPage(mSplash, pageNumber, this->dpiForRendering * xscale, this->dpiForRendering *yscale,
Claudio Valerio's avatar
Claudio Valerio committed
173 174 175 176
                                   rotation, useMediaBox, crop, printing);
        }
        else
        {
177
			mSliceX = bounds.x() * xscale;
178 179 180
            mSliceY = bounds.y() * yscale;
            qreal sliceW = bounds.width() * xscale;
            qreal sliceH = bounds.height() * yscale;
Claudio Valerio's avatar
Claudio Valerio committed
181

182 183
            mDocument->displayPageSlice(mSplash, pageNumber, this->dpiForRendering * xscale, this->dpiForRendering * yscale,
				rotation, useMediaBox, crop, printing, mSliceX, mSliceY, sliceW, sliceH);
Claudio Valerio's avatar
Claudio Valerio committed
184 185
        }

Didier's avatar
Didier committed
186
        mpSplashBitmap = mSplash->getBitmap();
Claudio Valerio's avatar
Claudio Valerio committed
187
    }
188
    return new QImage(mpSplashBitmap->getDataPtr(), mpSplashBitmap->getWidth(), mpSplashBitmap->getHeight(), mpSplashBitmap->getWidth() * 3, QImage::Format_RGB888);
Didier's avatar
Didier committed
189
}