diff --git a/src/adaptors/UBImportPDF.cpp b/src/adaptors/UBImportPDF.cpp index 2a0811d8..b178b154 100644 --- a/src/adaptors/UBImportPDF.cpp +++ b/src/adaptors/UBImportPDF.cpp @@ -61,7 +61,7 @@ bool UBImportPDF::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFi QString filepath = UBPersistenceManager::persistenceManager()->addPdfFileToDocument(pDocument, pFile.fileName(), uuid); - PDFRenderer *pdfRenderer = PDFRenderer::rendererForUuid(uuid, pDocument->persistencePath() + "/" + filepath); // renderer is automatically deleted when not used anymore + PDFRenderer *pdfRenderer = PDFRenderer::rendererForUuid(uuid, pDocument->persistencePath() + "/" + filepath, true); // renderer is automatically deleted when not used anymore if (!pdfRenderer->isValid()) { diff --git a/src/pdf/PDFRenderer.cpp b/src/pdf/PDFRenderer.cpp index a7a8c793..57e9b36d 100644 --- a/src/pdf/PDFRenderer.cpp +++ b/src/pdf/PDFRenderer.cpp @@ -30,7 +30,7 @@ PDFRenderer::~PDFRenderer() // NOOP } -PDFRenderer* PDFRenderer::rendererForUuid(const QUuid &uuid, const QString &filename) +PDFRenderer* PDFRenderer::rendererForUuid(const QUuid &uuid, const QString &filename, bool importingFile) { if (sRenderers.contains(uuid)) { @@ -38,7 +38,7 @@ PDFRenderer* PDFRenderer::rendererForUuid(const QUuid &uuid, const QString &file } else { - PDFRenderer *newRenderer = new XPDFRenderer(filename); + PDFRenderer *newRenderer = new XPDFRenderer(filename,importingFile); newRenderer->setRefCount(0); newRenderer->setFileUuid(uuid); diff --git a/src/pdf/PDFRenderer.h b/src/pdf/PDFRenderer.h index 5f68ed28..63945cd1 100644 --- a/src/pdf/PDFRenderer.h +++ b/src/pdf/PDFRenderer.h @@ -31,7 +31,7 @@ class PDFRenderer : public QObject Q_OBJECT public: - static PDFRenderer* rendererForUuid(const QUuid &uuid, const QString &filename); + static PDFRenderer* rendererForUuid(const QUuid &uuid, const QString &filename, bool importingFile = false); virtual ~PDFRenderer(); virtual bool isValid() const = 0; diff --git a/src/pdf/XPDFRenderer.cpp b/src/pdf/XPDFRenderer.cpp index 30717935..5ef2851b 100644 --- a/src/pdf/XPDFRenderer.cpp +++ b/src/pdf/XPDFRenderer.cpp @@ -19,18 +19,11 @@ #include -#include -#include -#include -#include -#include - - #include "core/memcheck.h" QAtomicInt XPDFRenderer::sInstancesCount = 0; -XPDFRenderer::XPDFRenderer(const QString &filename) +XPDFRenderer::XPDFRenderer(const QString &filename, bool importingFile) : mDocument(0) { if (!globalParams) @@ -44,7 +37,13 @@ XPDFRenderer::XPDFRenderer(const QString &filename) mDocument = new PDFDoc(new GString(filename.toUtf8().data()), 0, 0, 0); // the filename GString is deleted on PDFDoc desctruction sInstancesCount.ref(); - + bThumbGenerated = !importingFile; + bPagesGenerated = false; + mPagesMap.clear(); + mThumbs.clear(); + mThumbMap.clear(); + mScaleX = 0.0; + mScaleY = 0.0; } XPDFRenderer::~XPDFRenderer() @@ -135,47 +134,114 @@ int XPDFRenderer::pageRotation(int pageNumber) const return 0; } - void XPDFRenderer::render(QPainter *p, int pageNumber, const QRectF &bounds) { + if (isValid()) + { + qreal xscale = p->worldTransform().m11(); + qreal yscale = p->worldTransform().m22(); + bool bZoomChanged = false; + bool bFirstThumbnail = false; + + if(fabs(mScaleX - xscale) > 0.1 || fabs(mScaleY - yscale) > 0.1) + { + mScaleX = xscale; + mScaleY = yscale; + bZoomChanged = true; + } + + // First verify if the thumbnails and the pages are generated + if(!bThumbGenerated) + { + if(pageNumber == 1) + { + bFirstThumbnail = true; + } + + if(!mThumbMap[pageNumber - 1]) + { + + // Generate the thumbnail + mThumbs << *createPDFImage(pageNumber, xscale, yscale, bounds); + mThumbMap[pageNumber - 1] = true; + if(pageNumber == mDocument->getNumPages()) + { + bThumbGenerated = true; + } + } + } + else if(!bPagesGenerated || bZoomChanged) + { + if(!mPagesMap[pageNumber - 1] || bZoomChanged) + { + // Generate the page + mNumPageToPageMap[pageNumber] = *createPDFImage(pageNumber, xscale, yscale, bounds); + mPagesMap[pageNumber - 1] = true; + if(mPagesMap.size() == mDocument->getNumPages()) + { + bPagesGenerated = true; + } + } + } + + QImage pdfImage; + + if(!bThumbGenerated || bFirstThumbnail) + { + pdfImage = mThumbs.at(pageNumber - 1); + } + else + { + pdfImage = mNumPageToPageMap[pageNumber]; + } + + QTransform savedTransform = p->worldTransform(); + p->resetTransform(); + QTime t; + t.start(); + p->drawImage(QPointF(savedTransform.dx() + mSliceX, savedTransform.dy() + mSliceY), pdfImage); + //qDebug() << "XPDFRenderer::render(...) execution time: " << t.elapsed() << "ms"; + p->setWorldTransform(savedTransform); + } +} + +QImage* XPDFRenderer::createPDFImage(int pageNumber, const qreal xscale, const qreal yscale, const QRectF &bounds) +{ + QImage* img = new QImage(); if (isValid()) { SplashColor paperColor = {0xFF, 0xFF, 0xFF}; // white - SplashOutputDev splash(splashModeRGB8, 1, gFalse, paperColor); - splash.startDoc(mDocument->getXRef()); + mSplash = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor); + mSplash->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.; + const qreal xScale = xscale; + const qreal yScale = yscale; + mSliceX = 0.; + mSliceY = 0.; if (bounds.isNull()) { - mDocument->displayPage(&splash, pageNumber, hResolution * xScale, vResolution * yScale, + mDocument->displayPage(mSplash, pageNumber, hResolution * xScale, vResolution * yScale, rotation, useMediaBox, crop, printing); } else { - sliceX = bounds.x() * xScale; - sliceY = bounds.y() * yScale; + mSliceX = bounds.x() * xScale; + mSliceY = 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); + mDocument->displayPageSlice(mSplash, pageNumber, hResolution * xScale, vResolution * yScale, + rotation, useMediaBox, crop, printing, mSliceX, mSliceY, 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); + mpSplashBitmap = mSplash->getBitmap(); + img = new QImage(mpSplashBitmap->getDataPtr(), mpSplashBitmap->getWidth(), mpSplashBitmap->getHeight(), mpSplashBitmap->getWidth() * 3, QImage::Format_RGB888); } -} \ No newline at end of file + return img; +} diff --git a/src/pdf/XPDFRenderer.h b/src/pdf/XPDFRenderer.h index 5b2dedcc..63d4bbd4 100644 --- a/src/pdf/XPDFRenderer.h +++ b/src/pdf/XPDFRenderer.h @@ -30,7 +30,7 @@ class XPDFRenderer : public PDFRenderer Q_OBJECT public: - XPDFRenderer(const QString &filename); + XPDFRenderer(const QString &filename, bool importingFile = false); virtual ~XPDFRenderer(); bool isValid() const;