diff --git a/kpdf/QOutputDev.cpp b/kpdf/QOutputDev.cpp index b281770540b9810bcc66b100c80dc8c9847d16d6..9a67c5e6765169de246cf7829fe7ab22cea828fa 100644 --- a/kpdf/QOutputDev.cpp +++ b/kpdf/QOutputDev.cpp @@ -75,6 +75,7 @@ void QOutputDev::endPage() bw = getBitmap()->getWidth(); dataPtr = getBitmap()->getDataPtr(); m_image = QImage((uchar*)dataPtr.rgb8, bw, bh, 32, 0, 0, QImage::IgnoreEndian); + m_image.setAlphaBuffer( false ); } void QOutputDev::updateFont(GfxState *state) diff --git a/kpdf/document.cpp b/kpdf/document.cpp index 5d969294670ff6a691be32969a255dc1308732a9..af4961d2c3e8800c8f5f58acfe6c13a03c79ea8c 100644 --- a/kpdf/document.cpp +++ b/kpdf/document.cpp @@ -14,6 +14,7 @@ // local includes #include "PDFDoc.h" +#include "QOutputDev.h" //#include "TextOutputDev.h" #include "kpdf_error.h" @@ -71,8 +72,8 @@ bool KPDFDocument::openFile( const QString & docFile ) GString *filename = new GString( QFile::encodeName( docFile ) ); delete d->pdfdoc; - d->pdfdoc = new PDFDoc( filename, 0, 0 ); deletePages(); + d->pdfdoc = new PDFDoc( filename, 0, 0 ); if ( !d->pdfdoc->isOk() || d->pdfdoc->getNumPages() < 1 ) { @@ -89,7 +90,7 @@ bool KPDFDocument::openFile( const QString & docFile ) uint pageCount = d->pdfdoc->getNumPages(); d->pages.resize( pageCount ); for ( uint i = 0; i < pageCount ; i++ ) - d->pages[i] = new KPDFPage( i, d->pdfdoc->getPageWidth(i+1), d->pdfdoc->getPageHeight(i+1) ); + d->pages[i] = new KPDFPage( i, d->pdfdoc->getPageWidth(i+1), d->pdfdoc->getPageHeight(i+1), d->pdfdoc->getPageRotate(i+1) ); //filter = NONE; TODO sendFilteredPageList(); @@ -237,11 +238,52 @@ void KPDFDocument::slotChangeZoom( float /*offset*/ ) { } + void KPDFDocument::addObserver( KPDFDocumentObserver * pObserver ) { d->observers.push_back( pObserver ); } +void KPDFDocument::requestPixmap( uint /*page*/, int /*width*/, int /*height*/ ) +{ + //think at this.. Syncronous or Asyncronous that's the problem! (shakespeare) +} + +void KPDFDocument::requestThumbnail( uint page, int width, int height ) +{ +// TODO FIXME BEGIN :: TEMP CODE. ONLY A TEST. quick in-place thumbnail gen + KPDFPage * kp = d->pages[page]; + if ( !kp ) + return; + if ( !kp->hasThumbnail( width, height ) && d->pdfdoc && kp->width() > 0 && kp->height() > 0 ) + { + // make thumbnail pixmap + SplashColor paperColor; + paperColor.rgb8 = splashMakeRGB8( 0xff, 0xff, 0xff ); + QOutputDev odev( paperColor ); + odev.startDoc( d->pdfdoc->getXRef() ); + double fakeDpiX = width * 72.0 / kp->width(), + fakeDpiY = height * 72.0 / kp->height(); + d->docLock.lock(); + d->pdfdoc->displayPage( &odev, page + 1, fakeDpiX, fakeDpiY, 0, true, false ); + d->docLock.unlock(); + + // It can happen (but with zero+ probability :-) that the output + // image doesn't have the right size. In that case scale it. + if ( odev.getImage().size() != QSize( width, height ) ) + { + QImage scaled( odev.getImage().smoothScale( width, height ) ); + kp->setThumbnail( scaled ); + } + else + kp->setThumbnail( odev.getImage() ); + + foreachObserver( notifyThumbnailChanged( page ) ); + } +// TODO FIXME END :: TEMP CODE. ONLY A TEST. +} + + void KPDFDocument::sendFilteredPageList() { // make up a value list of the pages [1,2,3..] diff --git a/kpdf/document.h b/kpdf/document.h index baa53ed9f92f0a39af08da430746075b208f3a6e..9c2f13073aa3005a98ee60b55ccae2d1d292d95c 100644 --- a/kpdf/document.h +++ b/kpdf/document.h @@ -50,9 +50,6 @@ public: KPDFDocument(); ~KPDFDocument(); - // observers related methods - void addObserver( KPDFDocumentObserver * pObserver ); - // document handling bool openFile( const QString & docFile ); void close(); @@ -64,9 +61,10 @@ public: bool atEnd() const; const KPDFPage * page( uint page ) const; - //FIXME TEMP, REMOVE THIS!!!!! (for experiments only..) - void makeThumbnail( uint page, int width, int height ) const {}; - void makePixmap( uint page ) const {}; + // observers related methods + void addObserver( KPDFDocumentObserver * pObserver ); + void requestPixmap( uint page, int width, int height ); + void requestThumbnail( uint page, int width, int height ); public slots: // document commands via slots diff --git a/kpdf/kpdf_part.cpp b/kpdf/kpdf_part.cpp index 864361974a3135e4d15ad4cf02471b9b2af6db93..b9036bd635cd63d4b59ed1002b4cd985fa5f1258 100644 --- a/kpdf/kpdf_part.cpp +++ b/kpdf/kpdf_part.cpp @@ -84,15 +84,15 @@ Part::Part(QWidget *parentWidget, const char *widgetName, connect( document, SIGNAL( pageChanged() ), this, SLOT( updateActions() ) ); // build widgets - QSplitter *split = new QSplitter(parentWidget, widgetName); + QSplitter *split = new QSplitter( parentWidget, widgetName ); split->setOpaqueResize( true ); - m_thumbnailList = new ThumbnailList(split, document); + m_thumbnailList = new ThumbnailList( split, document ); m_thumbnailList->setMaximumWidth( 125 ); m_thumbnailList->setMinimumWidth( 50 ); document->addObserver( m_thumbnailList ); - m_pageWidget = new KPDF::PageWidget(split, document); + m_pageWidget = new KPDF::PageWidget( split, document ); connect( m_pageWidget, SIGNAL( urlDropped( const KURL& ) ), SLOT( openURL( const KURL & ))); //connect(m _pageWidget, SIGNAL( rightClick() ), this, SIGNAL( rightClick() )); document->addObserver( m_pageWidget ); diff --git a/kpdf/page.cpp b/kpdf/page.cpp index 87c0fda43cdb4368c88714e520a01502ba36f142..669d530bfb9acefe7382dc31e703329c5a4a76a8 100644 --- a/kpdf/page.cpp +++ b/kpdf/page.cpp @@ -17,9 +17,11 @@ #include "TextOutputDev.h" #include "page.h" +class PageOverlay { /*fake temp class*/ }; + #include -KPDFPage::KPDFPage( uint page, float w, float h ) - : m_number( page ), m_width( w ), m_height( h ), m_zoom( 1 ), +KPDFPage::KPDFPage( uint page, float w, float h, int r ) + : m_number( page ), m_width( w ), m_height( h ), m_rotate( r ), m_pixmap( 0 ), m_thumbnail( 0 ), m_text( 0 ), m_overlay( 0 ) { /* m_thumbnail = new QPixmap( "/a.png", "PNG" ); @@ -38,22 +40,17 @@ KPDFPage::~KPDFPage() delete m_overlay; } -/** DRAWING **/ -void KPDFPage::drawPixmap( QPainter * p, const QRect & limits ) const // MUTEXED -{ - //threadLock.lock(); - +//BEGIN drawing functions +void KPDFPage::drawPixmap( QPainter * p, const QRect & limits, int /*width*/, int /*height*/ ) const +{// ### if ( m_pixmap ) p->drawPixmap( limits.topLeft(), *m_pixmap, limits ); else p->fillRect( limits, Qt::blue ); - - //threadLock.unlock(); } void KPDFPage::drawThumbnail( QPainter * p, const QRect & limits, int width, int height ) const // OK { - //threadLock.lock(); if ( m_thumbnail ) { if ( m_thumbnail->width() == width && m_thumbnail->height() == height ) @@ -66,68 +63,54 @@ void KPDFPage::drawThumbnail( QPainter * p, const QRect & limits, int width, int } else p->fillRect( limits, QApplication::palette().active().base() ); - //threadLock.unlock(); } +//END drawing functions - -/** FIND **/ -bool KPDFPage::hasText( QString & text ) +//BEGIN contents set methods +bool KPDFPage::hasPixmap( int width, int height ) const { - //FIXME - return text.isNull(); + return m_pixmap ? ( m_pixmap->width() == width && m_pixmap->height() == height ) : false; } -/* -const QRect & KPDFPage::textPosition() -{ - //FIXME - return QRect(); -} -*/ - -/** SLOTS **/ -void KPDFPage::slotSetZoom( float /*scale*/ ) +bool KPDFPage::hasThumbnail( int width, int height ) const { - + return m_thumbnail ? ( m_thumbnail->width() == width && m_thumbnail->height() == height ) : false; } -void KPDFPage::slotSetContents( QPixmap * pix ) // MUTEXED +void KPDFPage::setPixmap( const QImage & image ) { - if ( !pix ) - return; - - threadLock.lock(); - delete m_pixmap; - m_pixmap = new QPixmap( pix->width() + 6, pix->height() + 6 ); - bitBlt( m_pixmap, 1,1, pix, 0,0, pix->width(),pix->height() ); - QPainter paint( m_pixmap ); - paint.drawRect( 0,0, pix->width()+1, pix->height()+1 ); - paint.end(); - //update page size (in pixels) - m_size = m_pixmap->size(); - - threadLock.unlock(); + m_pixmap = new QPixmap( image ); } -void KPDFPage::slotSetThumbnail( QPixmap * thumb ) // MUTEXED -{ - if ( !thumb ) - return; - - threadLock.lock(); +void KPDFPage::setPixmapOverlay( /*someClass*/ ) +{ //TODO this +} +void KPDFPage::setThumbnail( const QImage & image ) +{ delete m_thumbnail; - m_thumbnail = new QPixmap( *thumb ); - - threadLock.unlock(); + m_thumbnail = new QPixmap( image ); } -void KPDFPage::slotSetOverlay() // MUTEXED +void KPDFPage::setTextPage( TextOutputDev * textPage ) { - threadLock.lock(); - //TODO this - threadLock.unlock(); + delete m_text; + m_text = 0; + if ( m_text ) + m_text = textPage; +} +//END contents set methods + +//BEGIN [FIND] +/*bool KPDFPage::hasText( QString & text ) +{ //TODO this + return text.isNull(); } -#include "page.moc" +const QRect & KPDFPage::textPosition() +{ //TODO this + return QRect(); +}*/ +//END [FIND] + diff --git a/kpdf/page.h b/kpdf/page.h index 027b2ce55aa13c4e50c2c2428d52521bc209aebf..dceb11a5da844901dbb063b3764726bd11153371 100644 --- a/kpdf/page.h +++ b/kpdf/page.h @@ -10,16 +10,14 @@ #ifndef _KPDF_PAGE_H_ #define _KPDF_PAGE_H_ -#include -#include -#include - class QPixmap; -class QString; -class QRect; +class QPainter; +class QImage; +//class QString; +//class QRect; class TextOutputDev; -class PageOverlay{ /*fake temp*/ }; +class PageOverlay; /** * @short Collector for all the data belonging to a page. @@ -33,46 +31,37 @@ class PageOverlay{ /*fake temp*/ }; * class is destroyed. */ -class KPDFPage : public QObject +class KPDFPage { - Q_OBJECT - public: - KPDFPage( uint number, float width, float height ); + KPDFPage( uint number, float width, float height, int rotation ); ~KPDFPage(); - // page properties + // query properties (const read-only methods) uint number() const { return m_number; } float width() const { return m_width; } float height() const { return m_height; } float ratio() const { return m_height / m_width; } - - // rendering - void drawPixmap( QPainter * p, const QRect & rect ) const; + float rotation() const { return m_rotate; } + bool hasPixmap( int width, int height ) const; + bool hasThumbnail( int width, int height ) const; + void drawPixmap( QPainter * p, const QRect & rect, int width, int height ) const; void drawThumbnail( QPainter * p, const QRect & rect, int width, int height ) const; - float currentZoom() const { return m_zoom; } - const QSize & currentSize() const { return m_size; } - - // find related methods - bool hasText( QString & text ); - //const QRect & textPosition(); -signals: - void changed( KPDFPage * thisPage ); + // page contents setup + void setPixmap( const QImage & image ); + void setPixmapOverlay( /*..DOMdescription..*/ ); + void setThumbnail( const QImage & image ); + void setTextPage( TextOutputDev * ); -private slots: - void slotSetZoom( float scale ); - void slotSetContents( QPixmap * ); - void slotSetThumbnail( QPixmap * ); - void slotSetOverlay( /*..DOMdescription..*/ ); + // FIND command + //bool hasText( QString & text ); + //const QRect & textPosition(); private: - QMutex threadLock; - uint m_number; float m_width, m_height; - float m_zoom; - QSize m_size; + int m_rotate; QPixmap * m_pixmap; QPixmap * m_thumbnail; TextOutputDev * m_text; diff --git a/kpdf/thumbnaillist.cpp b/kpdf/thumbnaillist.cpp index 66fee63a3f672900dd23405fc5943fbd7581d853..a6c811c86c7b13e1a2a2eba6aca07a8f9c3af460 100644 --- a/kpdf/thumbnaillist.cpp +++ b/kpdf/thumbnaillist.cpp @@ -78,7 +78,7 @@ void ThumbnailList::pageSetup( const QValueList & pages ) void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ ) { - // deselect previous page + // deselect previous thumbnail if ( m_selected ) m_selected->setSelected( false ); m_selected = 0; @@ -119,31 +119,35 @@ void ThumbnailList::keyPressEvent( QKeyEvent * keyEvent ) { if ( thumbnails.count() < 1 ) return keyEvent->ignore(); + + int nextPage = -1; if ( keyEvent->key() == Key_Up ) { if ( !m_selected ) - m_document->slotSetCurrentPage( 0 ); + nextPage = 0; else if ( vectorIndex > 0 ) - m_document->slotSetCurrentPage( thumbnails[ vectorIndex - 1 ]->pageNumber() ); - else - return keyEvent->ignore(); + nextPage = thumbnails[ vectorIndex - 1 ]->pageNumber(); } else if ( keyEvent->key() == Key_Down ) { if ( !m_selected ) - m_document->slotSetCurrentPage( 0 ); + nextPage = 0; else if ( vectorIndex < (int)thumbnails.count() - 1 ) - m_document->slotSetCurrentPage( thumbnails[ vectorIndex + 1 ]->pageNumber() ); - else - return keyEvent->ignore(); + nextPage = thumbnails[ vectorIndex + 1 ]->pageNumber(); } else if ( keyEvent->key() == Key_Home ) - m_document->slotSetCurrentPage( thumbnails[ 0 ]->pageNumber() ); + nextPage = thumbnails[ 0 ]->pageNumber(); else if ( keyEvent->key() == Key_End ) - m_document->slotSetCurrentPage( thumbnails[ thumbnails.count() - 1 ]->pageNumber() ); - else + nextPage = thumbnails[ thumbnails.count() - 1 ]->pageNumber(); + + if ( nextPage == -1 ) return keyEvent->ignore(); + keyEvent->accept(); + if ( m_selected ) + m_selected->setSelected( false ); + m_selected = 0; + m_document->slotSetCurrentPage( nextPage ); } void ThumbnailList::contentsMousePressEvent( QMouseEvent * e ) @@ -171,6 +175,9 @@ void ThumbnailList::viewportResizeEvent(QResizeEvent *e) // right place and recalculate the contents area if ( e->size().width() != e->oldSize().width() ) { + // runs the timer avoiding a thumbnail regeneration by 'contentsMoving' + requestThumbnails( 2000 ); + // resize and reposition items int totalHeight = 0, newWidth = e->size().width(); @@ -190,7 +197,7 @@ void ThumbnailList::viewportResizeEvent(QResizeEvent *e) if ( m_selected ) ensureVisible( 0, childY( m_selected ) + m_selected->height()/2, 0, visibleHeight()/2 ); } - else if ( e->size().height() > e->oldSize().height() ) + else if ( e->size().height() <= e->oldSize().height() ) return; // update thumbnails since width has changed or height has increased requestThumbnails( 500 ); @@ -217,7 +224,7 @@ void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContents if ( top > vHeight ) break; else if ( top + t->height() > 0 ) - m_document->makeThumbnail( t->pageNumber(), t->width(), t->height() ); + m_document->requestThumbnail( t->pageNumber(), t->previewWidth(), t->previewHeight() ); } } //END internal SLOTS