Merge the new functions of ThreadedGenerator into the base Generator: this means that there's again only a single base Generator that can provide the multithreading for the generation of contents, just pixmaps for now.

svn path=/trunk/playground/graphics/okular/; revision=628853
This commit is contained in:
Pino Toscano 2007-01-31 18:31:19 +00:00
parent 763bb521b7
commit 6068c76df6
22 changed files with 188 additions and 111 deletions

View file

@ -627,7 +627,7 @@ void Document::Private::sendGeneratorRequest()
cleanupPixmapMemory( pixmapBytes );
// submit the request to the generator
if ( m_generator->canRequestPixmap() )
if ( m_generator->canGeneratePixmap() )
{
kWarning() << "sending request id=" << request->id() << " " <<request->width() << "x" << request->height() << "@" << request->pageNumber() << " async == " << request->asynchronous() << endl;
m_pixmapRequestsStack.removeAll ( request );
@ -635,7 +635,7 @@ void Document::Private::sendGeneratorRequest()
if ( (int)m_rotation % 2 )
request->swap();
m_generator->requestPixmap( request );
m_generator->generatePixmap( request );
}
else
// pino (7/4/2006): set the polling interval from 10 to 30
@ -1328,7 +1328,7 @@ void Document::requestTextPage( uint page )
// Memory management for TextPages
d->m_generator->requestTextPage( kp );
d->m_generator->generateTextPage( kp );
}
void Document::addPageAnnotation( int page, Annotation * annotation )
@ -2148,7 +2148,7 @@ QStringList Document::supportedMimeTypes() const
void Document::requestDone( PixmapRequest * req )
{
#ifndef NDEBUG
if ( !d->m_generator->canRequestPixmap() )
if ( !d->m_generator->canGeneratePixmap() )
kDebug() << "requestDone with generator not in READY state." << endl;
#endif

View file

@ -14,23 +14,82 @@
#include "document.h"
#include "generator.h"
#include "page.h"
#include "threadedgenerator_p.h"
using namespace Okular;
class Generator::Private
{
public:
Private()
: m_document( 0 )
Private( Generator *parent )
: m_document( 0 ),
m_generator( parent ),
mPixmapReady( true ),
mTextPageReady( true )
{
mPixmapGenerationThread = new PixmapGenerationThread( m_generator );
QObject::connect( mPixmapGenerationThread, SIGNAL( finished() ),
m_generator, SLOT( pixmapGenerationFinished() ),
Qt::QueuedConnection );
mTextPageGenerationThread = new TextPageGenerationThread( m_generator );
QObject::connect( mTextPageGenerationThread, SIGNAL( finished() ),
m_generator, SLOT( textpageGenerationFinished() ),
Qt::QueuedConnection );
}
~Private()
{
if ( mPixmapGenerationThread )
mPixmapGenerationThread->wait();
delete mPixmapGenerationThread;
if ( mTextPageGenerationThread )
mTextPageGenerationThread->wait();
delete mTextPageGenerationThread;
}
void pixmapGenerationFinished();
void textpageGenerationFinished();
Document * m_document;
QSet< GeneratorFeature > m_features;
Generator *m_generator;
PixmapGenerationThread *mPixmapGenerationThread;
TextPageGenerationThread *mTextPageGenerationThread;
bool mPixmapReady;
bool mTextPageReady;
};
void Generator::Private::pixmapGenerationFinished()
{
PixmapRequest *request = mPixmapGenerationThread->request();
mPixmapGenerationThread->endGeneration();
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( mPixmapGenerationThread->image() ) ) );
mPixmapReady = true;
m_generator->signalPixmapRequestDone( request );
}
void Generator::Private::textpageGenerationFinished()
{
Page *page = mTextPageGenerationThread->page();
mTextPageGenerationThread->endGeneration();
mTextPageReady = true;
if ( mTextPageGenerationThread->textPage() )
page->setTextPage( mTextPageGenerationThread->textPage() );
}
Generator::Generator()
: d( new Private )
: d( new Private( this ) )
{
}
@ -44,33 +103,56 @@ bool Generator::loadDocumentFromData( const QByteArray &, QVector< Page * > & )
return false;
}
bool Generator::canRequestPixmap() const
bool Generator::canGeneratePixmap() const
{
return canGeneratePixmap();
return d->mPixmapReady;
}
void Generator::requestPixmap( PixmapRequest *request )
void Generator::generatePixmap( PixmapRequest *request )
{
generatePixmap( request );
}
d->mPixmapReady = false;
bool Generator::canRequestTextPage() const
{
return canGenerateTextPage();
}
if ( hasFeature( Threaded ) )
{
d->mPixmapGenerationThread->startGeneration( request );
return;
}
void Generator::requestTextPage( Page *page )
{
generateSyncTextPage( page );
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image( request ) ) ) );
d->mPixmapReady = true;
d->m_generator->signalPixmapRequestDone( request );
}
bool Generator::canGenerateTextPage() const
{
return true;
return d->mTextPageReady;
}
void Generator::generateSyncTextPage( Page* )
void Generator::generateTextPage( Page *page )
{
d->mTextPageReady = false;
if ( hasFeature( Threaded ) )
{
d->mTextPageGenerationThread->startGeneration( page );
return;
}
page->setTextPage( textPage( page ) );
d->mTextPageReady = true;
}
QImage Generator::image( PixmapRequest * )
{
return QImage();
}
TextPage* Generator::textPage( Page* )
{
return 0;
}
const DocumentInfo * Generator::generateDocumentInfo()

View file

@ -141,6 +141,9 @@ class OKULAR_EXPORT ExportFormat
*/
class OKULAR_EXPORT Generator : public QObject
{
friend class PixmapGenerationThread;
friend class TextPageGenerationThread;
Q_OBJECT
public:
@ -150,6 +153,7 @@ class OKULAR_EXPORT Generator : public QObject
*/
enum GeneratorFeature
{
Threaded,
TextExtraction, ///< Whether the Generator can extract text from the document in the form of TextPage's
ReadRawData, ///< Whether the Generator can read a document directly from its raw data.
PageSizes ///< Whether the Generator can change the size of the document pages.
@ -200,26 +204,26 @@ class OKULAR_EXPORT Generator : public QObject
* This method returns whether the generator is ready to
* handle a new pixmap request.
*/
virtual bool canRequestPixmap() const;
virtual bool canGeneratePixmap() const;
/**
* This method can be called to trigger the generation of
* a new pixmap as described by @p request.
*/
virtual void requestPixmap( PixmapRequest * request );
virtual void generatePixmap( PixmapRequest * request );
/**
* This method returns whether the generator is ready to
* handle a new text page request.
*/
virtual bool canRequestTextPage() const;
virtual bool canGenerateTextPage() const;
/**
* This method can be called to trigger the generation of
* a text page for the given @p page.
* @see TextPage
*/
virtual void requestTextPage( Page * page );
virtual void generateTextPage( Page * page );
/**
* Returns the general information object of the document or 0 if
@ -340,30 +344,21 @@ class OKULAR_EXPORT Generator : public QObject
void signalPixmapRequestDone( 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 check whether the generator is ready
* to handle a new request for text page generation.
*/
virtual bool canGenerateTextPage() const;
/**
* This method is called to create a so called 'text page' for the given @p page.
* Returns the image of the page as specified in
* the passed pixmap @p request.
*
* A text page is an abstract description of the readable text of the page.
* It's used for search and text extraction.
* @warning this method may be executed in its own separated thread if the
* @ref Threaded is enabled!
*/
virtual void generateSyncTextPage( Page *page );
virtual QImage image( PixmapRequest *page );
/**
* Returns the text page for the given @p page.
*
* @warning this method may be executed in its own separated thread if the
* @ref Threaded is enabled!
*/
virtual TextPage* textPage( Page *page );
/**
* Returns a pointer to the document.
@ -378,6 +373,9 @@ class OKULAR_EXPORT Generator : public QObject
private:
class Private;
Private* const d;
Q_PRIVATE_SLOT( d, void pixmapGenerationFinished() )
Q_PRIVATE_SLOT( d, void textpageGenerationFinished() )
};
/**

View file

@ -317,9 +317,9 @@ void TextDocumentGenerator::generatePixmap( Okular::PixmapRequest * request )
signalPixmapRequestDone( request );
}
void TextDocumentGenerator::generateSyncTextPage( Okular::Page * page )
Okular::TextPage* TextDocumentGenerator::textPage( Okular::Page * page )
{
page->setTextPage( d->createTextPage( page->number() ) );
return d->createTextPage( page->number() );
}
bool TextDocumentGenerator::print( KPrinter& printer )

View file

@ -117,6 +117,10 @@ 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() const;
void generatePixmap( Okular::PixmapRequest * request );
// [INHERITED] print document using already configured kprinter
bool print( KPrinter& printer );
@ -128,10 +132,7 @@ class OKULAR_EXPORT TextDocumentGenerator : public Generator
const Okular::DocumentSynopsis* generateDocumentSynopsis();
protected:
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
Okular::TextPage* textPage( Okular::Page *page );
private:
class Private;

View file

@ -17,7 +17,7 @@ namespace Okular {
class PixmapGenerationThread : public QThread
{
public:
PixmapGenerationThread( ThreadedGenerator *generator )
PixmapGenerationThread( Generator *generator )
: mGenerator( generator ), mRequest( 0 )
{
}
@ -54,7 +54,7 @@ class PixmapGenerationThread : public QThread
}
private:
ThreadedGenerator *mGenerator;
Generator *mGenerator;
PixmapRequest *mRequest;
QImage mImage;
};
@ -63,7 +63,7 @@ class PixmapGenerationThread : public QThread
class TextPageGenerationThread : public QThread
{
public:
TextPageGenerationThread( ThreadedGenerator *generator )
TextPageGenerationThread( Generator *generator )
: mGenerator( generator ), mPage( 0 )
{
}
@ -100,7 +100,7 @@ class TextPageGenerationThread : public QThread
}
private:
ThreadedGenerator *mGenerator;
Generator *mGenerator;
Page *mPage;
TextPage *mTextPage;
};

View file

@ -346,7 +346,7 @@ void CHMGenerator::additionalRequestData()
}
}
void CHMGenerator::generateSyncTextPage( Okular::Page * page )
Okular::TextPage* CHMGenerator::textPage( Okular::Page * page )
{
syncLock.lock();
double zoomP=Okular::Settings::zoomFactor();
@ -355,8 +355,8 @@ void CHMGenerator::generateSyncTextPage( Okular::Page * page )
preparePageForSyncOperation(zoom, m_file->getUrlForPage ( page->number() + 1 ));
Okular::TextPage *tp=new Okular::TextPage();
recursiveExploreNodes( m_syncGen->htmlDocument(), tp);
page->setTextPage(tp);
syncLock.unlock();
return tp;
}
QVariant CHMGenerator::metaData( const QString &key, const QVariant &option ) const

View file

@ -38,15 +38,16 @@ class CHMGenerator : public Okular::Generator
const Okular::DocumentSynopsis * generateDocumentSynopsis();
const Okular::DocumentFonts * generateDocumentFonts();
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
QVariant metaData( const QString & key, const QVariant & option ) const;
public slots:
void slotCompleted();
protected:
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
Okular::TextPage* textPage( Okular::Page *page );
private:
void additionalRequestData ();

View file

@ -18,8 +18,9 @@
OKULAR_EXPORT_PLUGIN(ComicBookGenerator)
ComicBookGenerator::ComicBookGenerator()
: ThreadedGenerator()
: Generator()
{
setFeature( Threaded );
}
ComicBookGenerator::~ComicBookGenerator()

View file

@ -10,11 +10,11 @@
#ifndef GENERATOR_COMICBOOK_H
#define GENERATOR_COMICBOOK_H
#include <okular/core/threadedgenerator.h>
#include <core/generator.h>
#include "document.h"
class ComicBookGenerator : public Okular::ThreadedGenerator
class ComicBookGenerator : public Okular::Generator
{
Q_OBJECT

View file

@ -30,6 +30,10 @@ class DjVuGenerator : public Okular::Generator
bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
bool closeDocument();
// pixmap generation
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
// document information
const Okular::DocumentInfo * generateDocumentInfo();
const Okular::DocumentSynopsis * generateDocumentSynopsis();
@ -40,11 +44,6 @@ 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

@ -239,9 +239,9 @@ void DviGenerator::generatePixmap( Okular::PixmapRequest *request )
signalPixmapRequestDone( request );
}
void DviGenerator::generateSyncTextPage( Okular::Page* page )
Okular::TextPage* DviGenerator::textPage( Okular::Page *page )
{
kDebug() << "DviGenerator::generateSyncTextPage( Okular::Page * page )" << endl;
kDebug() << "DviGenerator::textPage( Okular::Page * page )" << endl;
dviPageInfo *pageInfo = new dviPageInfo();
pageSize ps;
@ -255,14 +255,15 @@ void DviGenerator::generateSyncTextPage( Okular::Page* page )
pageInfo->resolution = (double)(pageInfo->width)/ps.width().getLength_in_inch();
// get page text from m_dviRenderer
Okular::TextPage *ktp = 0;
if ( m_dviRenderer )
{
m_dviRenderer->getText( pageInfo );
Okular::TextPage *ktp = extractTextFromPage( pageInfo, page->totalOrientation() );
page->setTextPage( ktp );
ktp = extractTextFromPage( pageInfo, page->totalOrientation() );
}
delete pageInfo;
return ktp;
}
Okular::TextPage *DviGenerator::extractTextFromPage( dviPageInfo *pageInfo, int orientation )

View file

@ -29,17 +29,17 @@ class DviGenerator : public Okular::Generator
bool loadDocument( const QString & fileName, QVector< Okular::Page * > & pagesVector );
bool closeDocument();
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
// document information
const Okular::DocumentInfo *generateDocumentInfo();
// table of contents
const Okular::DocumentSynopsis *generateDocumentSynopsis();
protected:
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
void generateSyncTextPage( Okular::Page * page );
protected:
Okular::TextPage* textPage( Okular::Page *page );
private:
double m_resolution;

View file

@ -38,6 +38,10 @@ 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() const;
void generatePixmap( Okular::PixmapRequest * request );
// page size management
Okular::PageSize::List pageSizes() const;
void pageSizeChanged( const Okular::PageSize &, const Okular::PageSize & );
@ -61,11 +65,6 @@ 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

@ -21,9 +21,10 @@
OKULAR_EXPORT_PLUGIN(KIMGIOGenerator)
KIMGIOGenerator::KIMGIOGenerator()
: ThreadedGenerator()
: Generator()
{
setFeature( ReadRawData );
setFeature( Threaded );
}
KIMGIOGenerator::~KIMGIOGenerator()

View file

@ -10,11 +10,11 @@
#ifndef _OKULAR_GENERATOR_KIMGIO_H_
#define _OKULAR_GENERATOR_KIMGIO_H_
#include <okular/core/threadedgenerator.h>
#include <core/generator.h>
#include <QtGui/QImage>
class KIMGIOGenerator : public Okular::ThreadedGenerator
class KIMGIOGenerator : public Okular::Generator
{
Q_OBJECT
public:

View file

@ -678,22 +678,22 @@ void PDFGenerator::generatePixmap( Okular::PixmapRequest * request )
signalPixmapRequestDone( request );
}
void PDFGenerator::generateSyncTextPage( Okular::Page * page )
Okular::TextPage* PDFGenerator::textPage( Okular::Page *page )
{
kDebug() << "calling generateSyncTextPage( Okular::Page * page )" << endl;
kDebug() << "calling textPage( Okular::Page * page )" << endl;
// build a TextList...
Poppler::Page *pp = pdfdoc->page( page->number() );
docLock.lock();
QList<Poppler::TextBox*> textList = pp->textList((Poppler::Page::Rotation)page->orientation());
docLock.unlock();
delete pp;
// ..and attach it to the page
const double pageWidth = ( page->rotation() % 2 ? page->height() : page->width() );
const double pageHeight = ( page->rotation() % 2 ? page->width() : page->height() );
page->setTextPage( abstractTextPage(textList, pageHeight, pageWidth, (Poppler::Page::Rotation)page->orientation()));
Okular::TextPage *tp = abstractTextPage(textList, pageHeight, pageWidth, (Poppler::Page::Rotation)page->orientation());
qDeleteAll(textList);
return tp;
}
bool PDFGenerator::print( KPrinter& printer )

View file

@ -70,6 +70,10 @@ 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() const;
void generatePixmap( Okular::PixmapRequest * request );
// [INHERITED] print page using an already configured kprinter
bool print( KPrinter& printer );
@ -84,15 +88,13 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface
Okular::ExportFormat::List exportFormats() const;
bool exportTo( const QString &fileName, const Okular::ExportFormat &format );
protected:
Okular::TextPage* textPage( Okular::Page *page );
private slots:
// (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

@ -44,9 +44,10 @@ static QDateTime convertTIFFDateTime( const char* tiffdate )
OKULAR_EXPORT_PLUGIN(TIFFGenerator)
TIFFGenerator::TIFFGenerator()
: Okular::ThreadedGenerator(),
: Okular::Generator(),
d( new Private ), m_docInfo( 0 )
{
setFeature( Threaded );
}
TIFFGenerator::~TIFFGenerator()

View file

@ -10,9 +10,9 @@
#ifndef _OKULAR_GENERATOR_TIFF_H_
#define _OKULAR_GENERATOR_TIFF_H_
#include <okular/core/threadedgenerator.h>
#include <core/generator.h>
class TIFFGenerator : public Okular::ThreadedGenerator
class TIFFGenerator : public Okular::Generator
{
Q_OBJECT
public:

View file

@ -651,21 +651,13 @@ bool XpsGenerator::closeDocument()
return true;
}
bool XpsGenerator::canGeneratePixmap() const
{
return true;
}
void XpsGenerator::generatePixmap( Okular::PixmapRequest * request )
QImage XpsGenerator::image( Okular::PixmapRequest * request )
{
QSize size( (int)request->page()->width(), (int)request->page()->height() );
QImage image( size, QImage::Format_RGB32 );
XpsPage *pageToRender = m_xpsFile->page( request->page()->number() );
pageToRender->renderToImage( &image );
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image ) ) );
// signal that the request has been accomplished
signalPixmapRequestDone( request );
return image;
}
const Okular::DocumentInfo * XpsGenerator::generateDocumentInfo()

View file

@ -213,8 +213,7 @@ class XpsGenerator : public Okular::Generator
const Okular::DocumentInfo * generateDocumentInfo();
protected:
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest * request );
QImage image( Okular::PixmapRequest *page );
private:
XpsFile *m_xpsFile;