Resolved bad performance when drawing on top of a PDF

preferencesAboutTextFull
shibakaneki 14 years ago
parent 086c49544a
commit 7138cb9c00
  1. 1
      src/domain/UBGraphicsScene.cpp
  2. 103
      src/pdf/XPDFRenderer.cpp
  3. 20
      src/pdf/XPDFRenderer.h

@ -10,6 +10,7 @@
#include <QtGui> #include <QtGui>
#include <QtWebKit> #include <QtWebKit>
#include <QtSvg> #include <QtSvg>
#include <QGraphicsView>
#include "frameworks/UBGeometryUtils.h" #include "frameworks/UBGeometryUtils.h"
#include "frameworks/UBPlatformUtils.h" #include "frameworks/UBPlatformUtils.h"

@ -5,12 +5,6 @@
#include <frameworks/UBPlatformUtils.h> #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; QAtomicInt XPDFRenderer::sInstancesCount = 0;
XPDFRenderer::XPDFRenderer(const QString &filename) XPDFRenderer::XPDFRenderer(const QString &filename)
@ -27,7 +21,11 @@ XPDFRenderer::XPDFRenderer(const QString &filename)
mDocument = new PDFDoc(new GString(filename.toUtf8().data()), 0, 0, 0); // the filename GString is deleted on PDFDoc desctruction mDocument = new PDFDoc(new GString(filename.toUtf8().data()), 0, 0, 0); // the filename GString is deleted on PDFDoc desctruction
sInstancesCount.ref(); sInstancesCount.ref();
bThumbGenerated = false;
bPagesGenerated = false;
mPagesMap.clear();
mThumbs.clear();
mThumbMap.clear();
} }
XPDFRenderer::~XPDFRenderer() XPDFRenderer::~XPDFRenderer()
@ -118,47 +116,100 @@ int XPDFRenderer::pageRotation(int pageNumber) const
return 0; return 0;
} }
void XPDFRenderer::render(QPainter *p, int pageNumber, const QRectF &bounds) void XPDFRenderer::render(QPainter *p, int pageNumber, const QRectF &bounds)
{ {
if (isValid())
{
// First verify if the thumbnails and the pages are generated
if(!bThumbGenerated)
{
qreal xscale = p->worldTransform().m11();
qreal yscale = p->worldTransform().m22();
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)
{
qreal xscale = p->worldTransform().m11();
qreal yscale = p->worldTransform().m22();
if(!mPagesMap[pageNumber - 1])
{
// Generate the page
mNumPageToPageMap[pageNumber] = *createPDFImage(pageNumber, xscale, yscale, bounds);
mPagesMap[pageNumber - 1] = true;
if(mPagesMap.size() == mDocument->getNumPages())
{
bPagesGenerated = true;
}
}
}
// Warning: verify pagenumber
QImage pdfImage;
if(!bThumbGenerated)
{
pdfImage = mThumbs.at(pageNumber - 1);
}
else
{
pdfImage = mNumPageToPageMap[pageNumber];
}
pdfImage.rect();
QTransform savedTransform = p->worldTransform();
p->resetTransform();
p->drawImage(QPointF(savedTransform.dx() + mSliceX, savedTransform.dy() + mSliceY), pdfImage);
p->setWorldTransform(savedTransform);
}
}
QImage* XPDFRenderer::createPDFImage(int pageNumber, const qreal xscale, const qreal yscale, const QRectF &bounds)
{
QImage* img = new QImage();
if (isValid()) if (isValid())
{ {
SplashColor paperColor = {0xFF, 0xFF, 0xFF}; // white SplashColor paperColor = {0xFF, 0xFF, 0xFF}; // white
SplashOutputDev splash(splashModeRGB8, 1, gFalse, paperColor); mSplash = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
splash.startDoc(mDocument->getXRef()); mSplash->startDoc(mDocument->getXRef());
int hResolution = 72; int hResolution = 72;
int vResolution = 72; int vResolution = 72;
int rotation = 0; // in degrees (get it from the worldTransform if we want to support rotation) int rotation = 0; // in degrees (get it from the worldTransform if we want to support rotation)
GBool useMediaBox = gFalse; GBool useMediaBox = gFalse;
GBool crop = gTrue; GBool crop = gTrue;
GBool printing = gFalse; GBool printing = gFalse;
const qreal xScale = p->worldTransform().m11(); const qreal xScale = xscale;
const qreal yScale = p->worldTransform().m22(); const qreal yScale = yscale;
qreal sliceX = 0.; mSliceX = 0.;
qreal sliceY = 0.; mSliceY = 0.;
if (bounds.isNull()) if (bounds.isNull())
{ {
mDocument->displayPage(&splash, pageNumber, hResolution * xScale, vResolution * yScale, mDocument->displayPage(mSplash, pageNumber, hResolution * xScale, vResolution * yScale,
rotation, useMediaBox, crop, printing); rotation, useMediaBox, crop, printing);
} }
else else
{ {
sliceX = bounds.x() * xScale; mSliceX = bounds.x() * xScale;
sliceY = bounds.y() * yScale; mSliceY = bounds.y() * yScale;
qreal sliceW = bounds.width() * xScale; qreal sliceW = bounds.width() * xScale;
qreal sliceH = bounds.height() * yScale; qreal sliceH = bounds.height() * yScale;
mDocument->displayPageSlice(&splash, pageNumber, hResolution * xScale, vResolution * yScale, mDocument->displayPageSlice(mSplash, pageNumber, hResolution * xScale, vResolution * yScale,
rotation, useMediaBox, crop, printing, sliceX, sliceY, sliceW, sliceH); rotation, useMediaBox, crop, printing, mSliceX, mSliceY, sliceW, sliceH);
} }
SplashBitmap *bitmap = splash.getBitmap(); mpSplashBitmap = mSplash->getBitmap();
QImage pdfImage(bitmap->getDataPtr(), bitmap->getWidth(), bitmap->getHeight(), bitmap->getWidth() * 3, QImage::Format_RGB888); img = new QImage(mpSplashBitmap->getDataPtr(), mpSplashBitmap->getWidth(), mpSplashBitmap->getHeight(), mpSplashBitmap->getWidth() * 3, QImage::Format_RGB888);
QTransform savedTransform = p->worldTransform();
p->resetTransform();
p->drawImage(QPointF(savedTransform.dx() + sliceX, savedTransform.dy() + sliceY), pdfImage);
p->setWorldTransform(savedTransform);
} }
return img;
} }

@ -1,8 +1,13 @@
#ifndef XPDFRENDERER_H #ifndef XPDFRENDERER_H
#define XPDFRENDERER_H #define XPDFRENDERER_H
#include <QImage>
#include "PDFRenderer.h" #include "PDFRenderer.h"
#include <splash/SplashBitmap.h>
#include <xpdf/Object.h>
#include <xpdf/GlobalParams.h>
#include <xpdf/SplashOutputDev.h>
#include <xpdf/PDFDoc.h>
class PDFDoc; class PDFDoc;
@ -29,10 +34,21 @@ class XPDFRenderer : public PDFRenderer
private: private:
void init(); void init();
QImage* createPDFImage(int pageNumber, const qreal xscale = 0.5, const qreal yscale = 0.5, const QRectF &bounds = QRectF());
PDFDoc *mDocument; PDFDoc *mDocument;
QList<QImage> mThumbs;
QMap<int, bool> mPagesMap;
QMap<int, bool> mThumbMap;
QMap<int, QImage> mNumPageToPageMap;
static QAtomicInt sInstancesCount; static QAtomicInt sInstancesCount;
qreal mSliceX;
qreal mSliceY;
int bPD;
bool bThumbGenerated;
bool bPagesGenerated;
SplashBitmap* mpSplashBitmap;
SplashOutputDev* mSplash;
}; };
#endif // XPDFRENDERER_H #endif // XPDFRENDERER_H

Loading…
Cancel
Save