First part of the porting to a threaded api for generators

- made comicbook, tiff and kimgio a threaded generator

svn path=/trunk/playground/graphics/okular/; revision=626761
This commit is contained in:
Tobias Koenig 2007-01-24 15:06:45 +00:00
parent f7f9b3df41
commit d227a94e79
27 changed files with 399 additions and 340 deletions

View file

@ -48,6 +48,7 @@ set(okularcore_SRCS
core/sourcereference.cpp
core/textdocumentgenerator.cpp
core/textpage.cpp
core/threadedgenerator.cpp
core/utils.cpp
)
@ -65,6 +66,7 @@ install( FILES
core/sourcereference.h
core/textdocumentgenerator.h
core/textpage.h
core/threadedgenerator.h
core/utils.h
DESTINATION ${INCLUDE_INSTALL_DIR}/okular/core )

View file

@ -547,7 +547,7 @@ void Document::Private::sendGeneratorRequest()
cleanupPixmapMemory( pixmapBytes );
// submit the request to the generator
if ( m_generator->canGeneratePixmap( request->asynchronous() ) )
if ( m_generator->canRequestPixmap() )
{
kWarning() << "sending request id=" << request->id() << " " <<request->width() << "x" << request->height() << "@" << request->pageNumber() << " async == " << request->asynchronous() << endl;
m_pixmapRequestsStack.removeAll ( request );
@ -555,7 +555,7 @@ void Document::Private::sendGeneratorRequest()
if ( (int)m_rotation % 2 )
request->swap();
m_generator->generatePixmap ( request );
m_generator->requestPixmap( request );
}
else
// pino (7/4/2006): set the polling interval from 10 to 30
@ -1255,7 +1255,7 @@ void Document::requestPixmaps( const QLinkedList< PixmapRequest * > & requests )
// or else (if gen is running) it will be started when the new contents will
//come from generator (in requestDone())</NO>
// all handling of requests put into sendGeneratorRequest
// if ( generator->canGeneratePixmap() )
// if ( generator->canRequestPixmap() )
d->sendGeneratorRequest();
}
@ -1267,7 +1267,7 @@ void Document::requestTextPage( uint page )
// Memory management for TextPages
d->m_generator->generateSyncTextPage( kp );
d->m_generator->requestTextPage( kp );
}
void Document::addPageAnnotation( int page, Annotation * annotation )
@ -2047,7 +2047,7 @@ KPrintDialogPage* Document::printConfigurationWidget() const
void Document::requestDone( PixmapRequest * req )
{
#ifndef NDEBUG
if ( !d->m_generator->canGeneratePixmap( req->asynchronous() ) )
if ( !d->m_generator->canRequestPixmap() )
kDebug() << "requestDone with generator not in READY state." << endl;
#endif

View file

@ -41,6 +41,21 @@ bool Generator::loadDocumentFromData( const QByteArray &, QVector< Page * > & )
return false;
}
bool Generator::canRequestPixmap() const
{
return canGeneratePixmap();
}
void Generator::requestPixmap( PixmapRequest *request )
{
generatePixmap( request );
}
void Generator::requestTextPage( Page *page )
{
generateSyncTextPage( page );
}
void Generator::generateSyncTextPage( Page* )
{
}

View file

@ -197,24 +197,23 @@ class OKULAR_EXPORT Generator : public QObject
virtual bool closeDocument() = 0;
/**
* This method returns whether the generator can create pixmaps for
* each page in a synchronous or asynchronous way, depending on @p async.
* This method returns whether the generator is ready to
* handle a new pixmap request.
*/
virtual bool canGeneratePixmap( bool async ) const = 0;
virtual bool canRequestPixmap() const;
/**
* This method is called to create a pixmap for a page. The page number,
* width and height is encapsulated in the page @p request.
* This method can be called to trigger the generation of
* a new pixmap as described by @p request.
*/
virtual void generatePixmap( PixmapRequest * request ) = 0;
virtual void requestPixmap( PixmapRequest * request );
/**
* This method is called to create a so called 'text page' for the given @p page.
*
* A text page is an abstract description of the readable text of the page.
* It's used for search and text extraction.
* This method can be called to trigger the generation of
* a text page for the given @p page.
* @see TextPage
*/
virtual void generateSyncTextPage( Page *page );
virtual void requestTextPage( Page * page );
/**
* Returns the general information object of the document or 0 if
@ -334,6 +333,26 @@ class OKULAR_EXPORT Generator : public QObject
*/
void signalRequestDone( PixmapRequest * request );
/**
* This method is called to check whether the generator is ready
* to handle a new request for pixmap generation.
*/
virtual bool canGeneratePixmap() const = 0;
/**
* This method is called to create a pixmap for a page. The page number,
* width and height is encapsulated in the page @p request.
*/
virtual void generatePixmap( PixmapRequest * request ) = 0;
/**
* This method is called to create a so called 'text page' for the given @p page.
*
* A text page is an abstract description of the readable text of the page.
* It's used for search and text extraction.
*/
virtual void generateSyncTextPage( Page *page );
/**
* Returns a pointer to the document.
*/

View file

@ -238,7 +238,7 @@ bool TextDocumentGenerator::closeDocument()
return true;
}
bool TextDocumentGenerator::canGeneratePixmap( bool ) const
bool TextDocumentGenerator::canGeneratePixmap() const
{
return true;
}

View file

@ -93,11 +93,6 @@ class OKULAR_EXPORT TextDocumentGenerator : public Generator
bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
bool closeDocument();
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
bool hasFeature( GeneratorFeature feature ) const;
// [INHERITED] print document using already configured kprinter
@ -110,6 +105,12 @@ class OKULAR_EXPORT TextDocumentGenerator : public Generator
const Okular::DocumentInfo* generateDocumentInfo();
const Okular::DocumentSynopsis* generateDocumentSynopsis();
protected:
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
private:
class Private;
Private* const d;

109
core/threadedgenerator.cpp Normal file
View file

@ -0,0 +1,109 @@
/***************************************************************************
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org> *
* *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include "core/page.h"
#include "core/textpage.h"
#include "threadedgenerator.h"
#include "threadedgenerator_p.h"
using namespace Okular;
class ThreadedGenerator::Private
{
public:
Private( ThreadedGenerator *parent )
: mParent( parent ), mReady( true )
{
mPixmapGenerationThread = new PixmapGenerationThread( mParent );
mParent->connect( mPixmapGenerationThread, SIGNAL( finished() ),
mParent, SLOT( pixmapGenerationFinished() ),
Qt::QueuedConnection );
}
~Private()
{
if ( mPixmapGenerationThread )
mPixmapGenerationThread->wait();
delete mPixmapGenerationThread;
}
void pixmapGenerationFinished();
void textpageGenerationFinished();
ThreadedGenerator *mParent;
PixmapGenerationThread *mPixmapGenerationThread;
bool mReady;
};
void ThreadedGenerator::Private::pixmapGenerationFinished()
{
PixmapRequest *request = mPixmapGenerationThread->request();
mPixmapGenerationThread->endGeneration();
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( mPixmapGenerationThread->image() ) ) );
mReady = true;
mParent->signalRequestDone( request );
}
void ThreadedGenerator::Private::textpageGenerationFinished()
{
}
ThreadedGenerator::ThreadedGenerator()
: d( new Private( this ) )
{
}
ThreadedGenerator::~ThreadedGenerator()
{
delete d;
}
bool ThreadedGenerator::canRequestPixmap() const
{
return d->mReady;
}
void ThreadedGenerator::requestPixmap( PixmapRequest * request )
{
d->mReady = false;
d->mPixmapGenerationThread->startGeneration( request );
}
void ThreadedGenerator::requestTextPage( Page* )
{
}
TextPage* ThreadedGenerator::textPage( Page* )
{
return 0;
}
bool ThreadedGenerator::canGeneratePixmap() const
{
// dummy implementation
return false;
}
void ThreadedGenerator::generatePixmap( PixmapRequest* )
{
// dummy implementation
}
void ThreadedGenerator::generateSyncTextPage( Page* )
{
// dummy implementation
}
#include "threadedgenerator.moc"

102
core/threadedgenerator.h Normal file
View file

@ -0,0 +1,102 @@
/***************************************************************************
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org> *
* *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef OKULAR_THREADEDGENERATOR_H
#define OKULAR_THREADEDGENERATOR_H
#include <okular/core/okular_export.h>
#include <okular/core/generator.h>
namespace Okular {
/**
* ThreadedGenerator is meant to be a base class for Okular generators
* which supports multithreaded generation of page pixmaps, text pages
* and other data structures.
*/
class OKULAR_EXPORT ThreadedGenerator : public Generator
{
friend class PixmapGenerationThread;
friend class TextPageGenerationThread;
Q_OBJECT
public:
/**
* Creates a new threaded generator.
*/
ThreadedGenerator();
/**
* Destroys the threaded generator.
*/
~ThreadedGenerator();
/**
* Returns whether the generator is ready to
* handle a new pixmap generation request.
*/
bool canRequestPixmap() const;
/**
* This method can be called to trigger the generation of
* a new pixmap as described by @p request.
*/
void requestPixmap( PixmapRequest * request );
/**
* This method can be called to trigger the generation of
* a text page for the given @p page.
* @see TextPage
*/
void requestTextPage( Page * page );
protected:
/**
* Returns the image of the page as specified in
* the passed pixmap @p request.
*
* Note: This method is executed in its own separated thread!
*/
virtual QImage image( PixmapRequest *page ) = 0;
/**
* Returns the text page for the given @p page.
*
* Note: This method is executed in its own separated thread!
*/
virtual TextPage* textPage( Page *page );
/**
* @internal
*/
bool canGeneratePixmap() const;
/**
* @internal
*/
void generatePixmap( PixmapRequest* );
/**
* @internal
*/
void generateSyncTextPage( Page* );
private:
class Private;
Private* const d;
Q_PRIVATE_SLOT( d, void pixmapGenerationFinished() )
Q_PRIVATE_SLOT( d, void textpageGenerationFinished() )
};
}
#endif

View file

@ -0,0 +1,65 @@
/***************************************************************************
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org> *
* *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef OKULAR_THREADEDGENERATOR_P_H
#define OKULAR_THREADEDGENERATOR_P_H
#include <QtCore/QThread>
namespace Okular {
class PixmapGenerationThread : public QThread
{
public:
PixmapGenerationThread( ThreadedGenerator *generator )
: mGenerator( generator ), mRequest( 0 )
{
}
void startGeneration( PixmapRequest *request )
{
mRequest = request;
start( QThread::InheritPriority );
}
void endGeneration()
{
mRequest = 0;
}
PixmapRequest *request() const
{
return mRequest;
}
QImage image() const
{
return mImage;
}
protected:
virtual void run()
{
mImage = QImage();
if ( mRequest )
mImage = mGenerator->image( mRequest );
}
private:
ThreadedGenerator *mGenerator;
PixmapRequest *mRequest;
QImage mImage;
};
}
#endif

View file

@ -148,7 +148,7 @@ const Okular::DocumentFonts * CHMGenerator::generateDocumentFonts()
return 0L;
}
bool CHMGenerator::canGeneratePixmap ( bool /*async*/ ) const
bool CHMGenerator::canGeneratePixmap () const
{
bool isLocked = true;
if ( syncLock.tryLock() ) {

View file

@ -38,11 +38,6 @@ class CHMGenerator : public Okular::Generator
const Okular::DocumentSynopsis * generateDocumentSynopsis();
const Okular::DocumentFonts * generateDocumentFonts();
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
bool hasFeature( GeneratorFeature feature ) const;
QVariant metaData( const QString & key, const QVariant & option ) const;
@ -50,6 +45,11 @@ class CHMGenerator : public Okular::Generator
public slots:
void slotCompleted();
protected:
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
private:
void additionalRequestData ();
void recursiveExploreNodes(DOM::Node node,Okular::TextPage *tp);

View file

@ -7,7 +7,6 @@
* (at your option) any later version. *
***************************************************************************/
#include <QtCore/QThread>
#include <QtGui/QPainter>
#include <kprinter.h>
@ -18,78 +17,13 @@
OKULAR_EXPORT_PLUGIN(ComicBookGenerator)
class GeneratorThread : public QThread
{
public:
GeneratorThread();
void startGeneration( Okular::PixmapRequest* request, ComicBook::Document *document );
void endGeneration();
Okular::PixmapRequest *request() const;
QImage image();
private:
void run();
Okular::PixmapRequest* mRequest;
QImage mImage;
ComicBook::Document* mDocument;
};
GeneratorThread::GeneratorThread()
: QThread(), mRequest( 0 ), mDocument( 0 )
{
}
void GeneratorThread::startGeneration( Okular::PixmapRequest* request, ComicBook::Document *document )
{
mRequest = request;
mDocument = document;
start( QThread::InheritPriority );
}
void GeneratorThread::endGeneration()
{
mRequest = 0;
mDocument = 0;
}
Okular::PixmapRequest* GeneratorThread::request() const
{
return mRequest;
}
QImage GeneratorThread::image()
{
const QImage image = mImage;
mImage = QImage();
return image;
}
void GeneratorThread::run()
{
int width = mRequest->width();
int height = mRequest->height();
mImage = mDocument->pageImage( mRequest->pageNumber() );
mImage = mImage.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
}
ComicBookGenerator::ComicBookGenerator()
: Generator(), mReady( false )
: ThreadedGenerator()
{
mThread = new GeneratorThread();
connect( mThread, SIGNAL( finished() ), this, SLOT( threadFinished() ), Qt::QueuedConnection );
}
ComicBookGenerator::~ComicBookGenerator()
{
if ( mThread )
mThread->wait();
delete mThread;
}
bool ComicBookGenerator::loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector )
@ -105,55 +39,22 @@ bool ComicBookGenerator::loadDocument( const QString & fileName, QVector<Okular:
pagesVector[i] = page;
}
mReady = true;
return true;
}
bool ComicBookGenerator::closeDocument()
{
mReady = false;
return true;
}
bool ComicBookGenerator::canGeneratePixmap( bool ) const
QImage ComicBookGenerator::image( Okular::PixmapRequest * request )
{
return mReady;
}
void ComicBookGenerator::generatePixmap( Okular::PixmapRequest * request )
{
mReady = false;
if ( request->asynchronous() ) {
mThread->startGeneration( request, &mDocument );
return;
}
int width = request->width();
int height = request->height();
QImage image = mDocument.pageImage( request->pageNumber() );
image = image.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image ) ) );
mReady = true;
// signal that the request has been accomplished
signalRequestDone( request );
}
void ComicBookGenerator::threadFinished()
{
Okular::PixmapRequest *request = mThread->request();
mThread->endGeneration();
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( mThread->image() ) ) );
mReady = true;
signalRequestDone( request );
return image.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
}
bool ComicBookGenerator::print( KPrinter& printer )

View file

@ -10,13 +10,11 @@
#ifndef GENERATOR_COMICBOOK_H
#define GENERATOR_COMICBOOK_H
#include <okular/core/generator.h>
#include <okular/core/threadedgenerator.h>
#include "document.h"
class GeneratorThread;
class ComicBookGenerator : public Okular::Generator
class ComicBookGenerator : public Okular::ThreadedGenerator
{
Q_OBJECT
@ -28,22 +26,16 @@ class ComicBookGenerator : public Okular::Generator
bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
bool closeDocument();
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
// [INHERITED] print document using already configured kprinter
bool print( KPrinter& printer );
bool hasFeature( GeneratorFeature feature ) const;
private Q_SLOTS:
void threadFinished();
protected:
QImage image( Okular::PixmapRequest * request );
private:
ComicBook::Document mDocument;
GeneratorThread *mThread;
bool mReady;
};
#endif

View file

@ -93,7 +93,7 @@ bool DjVuGenerator::closeDocument()
return true;
}
bool DjVuGenerator::canGeneratePixmap( bool /*async*/ ) const
bool DjVuGenerator::canGeneratePixmap() const
{
return ready;
}

View file

@ -30,10 +30,6 @@ class DjVuGenerator : public Okular::Generator
bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
bool closeDocument();
// pixmap generation
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
// document information
const Okular::DocumentInfo * generateDocumentInfo();
const Okular::DocumentSynopsis * generateDocumentSynopsis();
@ -44,6 +40,11 @@ class DjVuGenerator : public Okular::Generator
private slots:
void djvuImageGenerated( int page, const QImage & img );
protected:
// pixmap generation
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
private:
void loadPages( QVector<Okular::Page*> & pagesVector, int rotation );
Okular::ObjectRect* convertKDjVuLink( int page, KDjVu::Link * link ) const;

View file

@ -69,7 +69,7 @@ bool DviGenerator::closeDocument()
return true;
}
bool DviGenerator::canGeneratePixmap ( bool /*async*/ ) const
bool DviGenerator::canGeneratePixmap () const
{
return ready;
}

View file

@ -29,11 +29,6 @@ class DviGenerator : public Okular::Generator
bool loadDocument( const QString & fileName, QVector< Okular::Page * > & pagesVector );
bool closeDocument();
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
// document information
const Okular::DocumentInfo *generateDocumentInfo();
@ -42,6 +37,12 @@ class DviGenerator : public Okular::Generator
bool hasFeature( GeneratorFeature feature ) const;
protected:
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
private:
double m_resolution;

View file

@ -451,9 +451,11 @@ kWarning() << "generator running : " << pixGenerator->running() << endl;
}
bool GSGenerator::canGeneratePixmap( bool async ) const
bool GSGenerator::canGeneratePixmap() const
{
// kWarning () << "ready Async/Sync " << (! docLock.locked()) << "/ " << (( pixGenerator ) ? !syncLock.locked() : true) << " asking for async: " << async << endl;
bool async = true;
bool isLocked = true;
if (async)
{

View file

@ -38,10 +38,6 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu
const Okular::DocumentSynopsis * generateDocumentSynopsis() { return 0L; }
const Okular::DocumentFonts * generateDocumentFonts() { return 0L; }
// page contents generation
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request ) ;
// page size management
Okular::PageSize::List pageSizes() const;
void pageSizeChanged( const Okular::PageSize &, const Okular::PageSize & );
@ -67,6 +63,11 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu
void slotPixmapGenerated(const QImage* img);
void slotAsyncPixmapGenerated(QPixmap * img);
protected:
// page contents generation
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request ) ;
private:
// conversion handling
bool m_converted;

View file

@ -16,7 +16,8 @@
OKULAR_EXPORT_PLUGIN(KIMGIOGenerator)
KIMGIOGenerator::KIMGIOGenerator() : Generator()
KIMGIOGenerator::KIMGIOGenerator()
: ThreadedGenerator()
{
}
@ -57,23 +58,15 @@ bool KIMGIOGenerator::closeDocument()
return true;
}
bool KIMGIOGenerator::canGeneratePixmap( bool /* async */ ) const
{
return true;
}
void KIMGIOGenerator::generatePixmap( Okular::PixmapRequest * request )
QImage KIMGIOGenerator::image( Okular::PixmapRequest * request )
{
// perform a smooth scaled generation
int width = request->width();
int height = request->height();
if ( request->page()->rotation() % 2 == 1 )
qSwap( width, height );
QImage image = m_img.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image ) ) );
// signal that the request has been accomplished
signalRequestDone(request);
return m_img.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
}
bool KIMGIOGenerator::print( KPrinter& printer )

View file

@ -10,11 +10,11 @@
#ifndef _OKULAR_GENERATOR_KIMGIO_H_
#define _OKULAR_GENERATOR_KIMGIO_H_
#include <okular/core/generator.h>
#include <okular/core/threadedgenerator.h>
#include <qimage.h>
#include <QtGui/QImage>
class KIMGIOGenerator : public Okular::Generator
class KIMGIOGenerator : public Okular::ThreadedGenerator
{
Q_OBJECT
public:
@ -26,15 +26,14 @@ class KIMGIOGenerator : public Okular::Generator
bool loadDocumentFromData( const QByteArray & fileData, QVector<Okular::Page*> & pagesVector );
bool closeDocument();
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
// [INHERITED] print document using already configured kprinter
bool print( KPrinter& printer );
bool hasFeature( GeneratorFeature feature ) const;
protected:
QImage image( Okular::PixmapRequest * request );
private:
QImage m_img;
};

View file

@ -593,7 +593,7 @@ bool PDFGenerator::isAllowed( Okular::Permissions permissions ) const
return b;
}
bool PDFGenerator::canGeneratePixmap( bool /* async */) const
bool PDFGenerator::canGeneratePixmap() const
{
return ready;
}

View file

@ -70,11 +70,6 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface
// [INHERITED] document information
bool isAllowed( Okular::Permissions permissions ) const;
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
// [INHERITED] print page using an already configured kprinter
bool print( KPrinter& printer );
@ -95,6 +90,11 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface
// (async related) receive data from the generator thread
void threadFinished();
protected:
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
private:
bool init(QVector<Okular::Page*> & pagesVector, const QString &walletKey);

View file

@ -12,7 +12,6 @@
#include <qimage.h>
#include <qlist.h>
#include <qpainter.h>
#include <qthread.h>
#include <kglobal.h>
#include <klocale.h>
#include <kprinter.h>
@ -34,100 +33,6 @@ class TIFFGenerator::Private
TIFF* tiff;
};
class TIFFGeneratorThread : public QThread
{
public:
TIFFGeneratorThread();
void startGeneration( Okular::PixmapRequest* request, TIFF* tiff );
void endGeneration();
Okular::PixmapRequest *request() const;
QImage takeImage();
private:
void run();
Okular::PixmapRequest* m_request;
QImage m_img;
TIFF* m_tiff;
};
TIFFGeneratorThread::TIFFGeneratorThread()
: QThread(), m_request( 0 ), m_tiff( 0 )
{
}
void TIFFGeneratorThread::startGeneration( Okular::PixmapRequest* request, TIFF* tiff )
{
m_request = request;
m_tiff = tiff;
start( QThread::InheritPriority );
}
void TIFFGeneratorThread::endGeneration()
{
m_request = 0;
m_tiff = 0;
}
Okular::PixmapRequest* TIFFGeneratorThread::request() const
{
return m_request;
}
QImage TIFFGeneratorThread::takeImage()
{
QImage p = m_img;
m_img = QImage();
return p;
}
void TIFFGeneratorThread::run()
{
bool generated = false;
if ( TIFFSetDirectory( m_tiff, m_request->page()->number() ) )
{
int rotation = m_request->page()->rotation();
uint32 width = (uint32)m_request->page()->width();
uint32 height = (uint32)m_request->page()->height();
if ( rotation % 2 == 1 )
qSwap( width, height );
QImage image( width, height, QImage::Format_RGB32 );
uint32 * data = (uint32 *)image.bits();
// read data
if ( TIFFReadRGBAImageOriented( m_tiff, width, height, data, ORIENTATION_TOPLEFT ) != 0 )
{
// an image read by ReadRGBAImage is ABGR, we need ARGB, so swap red and blue
uint32 size = width * height;
for ( uint32 i = 0; i < size; ++i )
{
uint32 red = ( data[i] & 0x00FF0000 ) >> 16;
uint32 blue = ( data[i] & 0x000000FF ) << 16;
data[i] = ( data[i] & 0xFF00FF00 ) + red + blue;
}
int reqwidth = m_request->width();
int reqheight = m_request->height();
if ( rotation % 2 == 1 )
qSwap( reqwidth, reqheight );
m_img = image.scaled( reqwidth, reqheight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
generated = true;
}
}
if ( !generated )
{
m_img = QImage( m_request->width(), m_request->height(), QImage::Format_RGB32 );
m_img.fill( qRgb( 255, 255, 255 ) );
}
}
static QDateTime convertTIFFDateTime( const char* tiffdate )
{
if ( !tiffdate )
@ -138,11 +43,10 @@ static QDateTime convertTIFFDateTime( const char* tiffdate )
OKULAR_EXPORT_PLUGIN(TIFFGenerator)
TIFFGenerator::TIFFGenerator() : Okular::Generator(),
d( new Private ), ready( false ), m_docInfo( 0 )
TIFFGenerator::TIFFGenerator()
: Okular::ThreadedGenerator(),
d( new Private ), m_docInfo( 0 )
{
thread = new TIFFGeneratorThread();
connect( thread, SIGNAL( finished() ), this, SLOT( slotThreadFinished() ), Qt::QueuedConnection );
}
TIFFGenerator::~TIFFGenerator()
@ -152,13 +56,8 @@ TIFFGenerator::~TIFFGenerator()
TIFFClose( d->tiff );
d->tiff = 0;
}
if ( thread )
{
thread->wait();
}
delete thread;
delete m_docInfo;
delete m_docInfo;
delete d;
}
@ -170,8 +69,6 @@ bool TIFFGenerator::loadDocument( const QString & fileName, QVector<Okular::Page
loadPages( pagesVector );
ready = true;
return true;
}
@ -186,26 +83,11 @@ bool TIFFGenerator::closeDocument()
m_docInfo = 0;
}
ready = false;
return true;
}
bool TIFFGenerator::canGeneratePixmap( bool /*async*/ ) const
QImage TIFFGenerator::image( Okular::PixmapRequest * request )
{
return ready;
}
void TIFFGenerator::generatePixmap( Okular::PixmapRequest * request )
{
ready = false;
if ( request->asynchronous() )
{
thread->startGeneration( request, d->tiff );
return;
}
bool generated = false;
QImage img;
@ -248,12 +130,7 @@ void TIFFGenerator::generatePixmap( Okular::PixmapRequest * request )
img.fill( qRgb( 255, 255, 255 ) );
}
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( img ) ) );
ready = true;
// signal that the request has been accomplished
signalRequestDone( request );
return img;
}
const Okular::DocumentInfo * TIFFGenerator::generateDocumentInfo()
@ -292,18 +169,6 @@ const Okular::DocumentInfo * TIFFGenerator::generateDocumentInfo()
return m_docInfo;
}
void TIFFGenerator::slotThreadFinished()
{
Okular::PixmapRequest * request = thread->request();
thread->endGeneration();
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( thread->takeImage() ) ) );
ready = true;
signalRequestDone( request );
}
void TIFFGenerator::loadPages( QVector<Okular::Page*> & pagesVector )
{
if ( !d->tiff )

View file

@ -10,11 +10,9 @@
#ifndef _OKULAR_GENERATOR_TIFF_H_
#define _OKULAR_GENERATOR_TIFF_H_
#include <okular/core/generator.h>
#include <okular/core/threadedgenerator.h>
class TIFFGeneratorThread;
class TIFFGenerator : public Okular::Generator
class TIFFGenerator : public Okular::ThreadedGenerator
{
Q_OBJECT
public:
@ -24,25 +22,19 @@ class TIFFGenerator : public Okular::Generator
bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
bool closeDocument();
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
const Okular::DocumentInfo * generateDocumentInfo();
bool print( KPrinter& printer );
private slots:
void slotThreadFinished();
protected:
QImage image( Okular::PixmapRequest * request );
private:
class Private;
Private * const d;
TIFFGeneratorThread* thread;
void loadPages( QVector<Okular::Page*> & pagesVector );
bool ready;
Okular::DocumentInfo * m_docInfo;
};

View file

@ -651,7 +651,7 @@ bool XpsGenerator::closeDocument()
return true;
}
bool XpsGenerator::canGeneratePixmap( bool /*async*/ ) const
bool XpsGenerator::canGeneratePixmap() const
{
return true;
}

View file

@ -210,12 +210,11 @@ class XpsGenerator : public Okular::Generator
bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
bool closeDocument();
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request );
const Okular::DocumentInfo * generateDocumentInfo();
private slots:
protected:
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
private:
XpsFile *m_xpsFile;