diff --git a/core/page.cpp b/core/page.cpp index 26546cced..4b718d8ec 100644 --- a/core/page.cpp +++ b/core/page.cpp @@ -31,6 +31,7 @@ #include "document_p.h" #include "form.h" #include "form_p.h" +#include "observer.h" #include "pagecontroller_p.h" #include "pagesize.h" #include "pagetransition.h" @@ -134,7 +135,7 @@ Page::Page( uint page, double w, double h, Rotation o ) Page::~Page() { deletePixmaps(); - deleteTilesManagers(); + qDeleteAll( d->m_tilesManagers ); deleteRects(); d->deleteHighlights(); deleteAnnotations(); @@ -204,7 +205,7 @@ void Page::setBoundingBox( const NormalizedRect& bbox ) bool Page::hasPixmap( int id, int width, int height, const NormalizedRect &rect ) const { - if ( id == 3 ) + if ( id == PAGEVIEW_ID ) { TilesManager *tm = tilesManager( id ); if ( !tm ) @@ -213,11 +214,10 @@ bool Page::hasPixmap( int id, int width, int height, const NormalizedRect &rect d->m_tilesManagers.insert( id, tm ); } - // TODO: mark tiles as dirty - if ( width != tm->width || height != tm->height ) + if ( width != tm->width() || height != tm->height() ) { - tm->width = width; - tm->height = height; + tm->setWidth( width ); + tm->setHeight( height ); return false; } diff --git a/core/tilesmanager.cpp b/core/tilesmanager.cpp index 9b1a468ad..136287687 100644 --- a/core/tilesmanager.cpp +++ b/core/tilesmanager.cpp @@ -14,11 +14,14 @@ using namespace Okular; TilesManager::TilesManager( int width, int height ) - : width( width ), height( height ) + : m_width( width ), m_height( height ) { + const double dim = 0.25; for ( int i = 0; i < 16; ++i ) { - mTiles[ i ] = 0; + int x = i % 4; + int y = i / 4; + m_tiles[ i ].rect = NormalizedRect( x*dim, y*dim, x*dim+dim, y*dim+dim ); } } @@ -26,11 +29,34 @@ TilesManager::~TilesManager() { for ( int i = 0; i < 16; ++i ) { - if ( mTiles[ i ] ) - { - delete mTiles[ i ]; - mTiles[ i ] = 0; - } + if ( m_tiles[ i ] ) + delete m_tiles[ i ].pixmap; + } +} + +void TilesManager::setWidth( int width ) +{ + if ( width == m_width ) + return; + + m_width = width; + + for ( int i = 0; i < 16; ++i ) + { + m_tiles[ i ].dirty = true; + } +} + +void TilesManager::setHeight( int height ) +{ + if ( height == m_height ) + return; + + m_height = height; + + for ( int i = 0; i < 16; ++i ) + { + m_tiles[ i ].dirty = true; } } @@ -42,7 +68,7 @@ void TilesManager::setPixmap( QPixmap *pixmap, const NormalizedRect &rect ) int right = rect.right/dim; int bottom = rect.bottom/dim; - const QRect pixmapRect = rect.geometry( width, height ); + const QRect pixmapRect = rect.geometry( m_width, m_height ); for ( int y = top; y < bottom; y++ ) { @@ -50,15 +76,12 @@ void TilesManager::setPixmap( QPixmap *pixmap, const NormalizedRect &rect ) { const NormalizedRect tileRect( x*dim, y*dim, x*dim+dim, y*dim+dim ); int index = 4*y+x; - if ( !mTiles[ index ] ) - mTiles[ index ] = new Tile(); - Tile *tile = mTiles[ index ]; - tile->rect = tileRect; - if ( tile->pixmap ) - delete (tile->pixmap); + if ( m_tiles[ index ].pixmap ) + delete (m_tiles[ index ].pixmap); - tile->pixmap = new QPixmap( pixmap->copy( tileRect.geometry( width, height ).translated( -pixmapRect.topLeft() ) ) ); + m_tiles[ index ].pixmap = new QPixmap( pixmap->copy( tileRect.geometry( m_width, m_height ).translated( -pixmapRect.topLeft() ) ) ); + m_tiles[ index ].dirty = false; } } @@ -78,17 +101,10 @@ bool TilesManager::hasPixmap( const NormalizedRect &rect ) for ( int x = left; x < right; x++ ) { int index = 4*y + x; - if ( !mTiles[ index ] ) + if ( !m_tiles[ index ].pixmap ) return false; - if ( !mTiles[ index ]->pixmap ) - return false; - - const NormalizedRect tileRect( x*dim, y*dim, x*dim+dim, y*dim+dim ); - QRect tileQRect = tileRect.geometry( width, height ); - if ( tileQRect.width() != mTiles[ index ]->pixmap->width() ) - return false; - if ( tileQRect.height() != mTiles[ index ]->pixmap->height() ) + if ( m_tiles[ index ].dirty ) return false; } } @@ -96,9 +112,9 @@ bool TilesManager::hasPixmap( const NormalizedRect &rect ) return true; } -QList TilesManager::tilesAt( const NormalizedRect &rect ) const +QList TilesManager::tilesAt( const NormalizedRect &rect ) const { - QList result; + QList result; const double dim = 0.25; int left = rect.left/dim; @@ -111,19 +127,7 @@ QList TilesManager::tilesAt( const NormalizedRect &rect ) const for ( int x = left; x < right; x++ ) { int index = 4*y + x; - if ( mTiles[ index ] ) - { - if ( !mTiles[ index ]->pixmap ) - continue; - - const NormalizedRect tileRect( x*dim, y*dim, x*dim+dim, y*dim+dim ); - QRect tileQRect = tileRect.geometry( width, height ); - if ( tileQRect.width() == mTiles[ index ]->pixmap->width() - && tileQRect.height() == mTiles[ index ]->pixmap->height() ) - { - result.append( mTiles[ index ] ); - } - } + result.append( m_tiles[ index ] ); } } @@ -132,9 +136,11 @@ QList TilesManager::tilesAt( const NormalizedRect &rect ) const Tile::Tile() : pixmap( 0 ) + , dirty ( true ) { } -Tile::~Tile() { - delete pixmap; +bool Tile::isValid() const +{ + return pixmap && !dirty; } diff --git a/core/tilesmanager.h b/core/tilesmanager.h index 0e3e0b3cf..e65dbeda8 100644 --- a/core/tilesmanager.h +++ b/core/tilesmanager.h @@ -16,7 +16,17 @@ class QPixmap; namespace Okular { -class Tile; +class OKULAR_EXPORT Tile +{ + public: + Tile(); + + bool isValid() const; + + NormalizedRect rect; + QPixmap *pixmap; + uint dirty : 1; +}; class OKULAR_EXPORT TilesManager { @@ -26,23 +36,17 @@ class OKULAR_EXPORT TilesManager void setPixmap( QPixmap *pixmap, const NormalizedRect &rect ); bool hasPixmap( const NormalizedRect &rect ); - QList tilesAt( const NormalizedRect &rect ) const; + QList tilesAt( const NormalizedRect &rect ) const; - int width; - int height; + inline int width() const { return m_width; } + void setWidth( int width ); + inline int height() const { return m_height; } + void setHeight( int height ); private: - Tile *mTiles[16]; -}; - -class OKULAR_EXPORT Tile -{ - public: - Tile(); - virtual ~Tile(); - - NormalizedRect rect; - QPixmap *pixmap; + Tile m_tiles[16]; + int m_width; + int m_height; }; } diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp index 8fe998f94..13363295a 100644 --- a/ui/pagepainter.cpp +++ b/ui/pagepainter.cpp @@ -238,12 +238,13 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula { if ( tilesManager ) { - QList tiles = tilesManager->tilesAt( crop ); - QList::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd(); + QList tiles = tilesManager->tilesAt( crop ); + QList::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd(); while ( tIt != tEnd ) { - Okular::Tile *tile = *tIt; - destPainter->drawPixmap( tile->rect.geometry( scaledWidth, scaledHeight ).topLeft(), *(tile->pixmap) ); + Okular::Tile tile = *tIt; + if ( tile.pixmap ) + destPainter->drawPixmap( tile.rect.geometry( scaledWidth, scaledHeight ), *(tile.pixmap) ); tIt++; } } diff --git a/ui/pageview.cpp b/ui/pageview.cpp index cced04ea4..a9e624baa 100644 --- a/ui/pageview.cpp +++ b/ui/pageview.cpp @@ -76,6 +76,7 @@ #include "core/generator.h" #include "core/movie.h" #include "core/sourcereference.h" +#include "core/tilesmanager.h" #include "settings.h" static int pageflags = PagePainter::Accessibility | PagePainter::EnhanceLinks | @@ -3983,26 +3984,19 @@ void PageView::slotRequestVisiblePixmaps( int newValue ) #ifdef PAGEVIEW_DEBUG kWarning() << "rerequesting visible pixmaps for page" << i->pageNumber() << "!"; #endif - const double dim = 0.25; - int left = vItem->rect.left/dim; - int top = vItem->rect.top/dim; - int right = ceil( vItem->rect.right/dim ); - int bottom = ceil( vItem->rect.bottom/dim ); - - for ( int y = top; y < bottom; y++ ) + QList tiles = i->page()->tilesManager( PAGEVIEW_ID )->tilesAt( vItem->rect ); + QList::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd(); + while ( tIt != tEnd ) { - for ( int x = left; x < right; x++ ) + Okular::Tile tile = *tIt; + if ( !tile.isValid() ) { - const Okular::NormalizedRect tileRect( x*dim, y*dim, x*dim+dim, y*dim+dim ); - - if ( !i->page()->hasPixmap( PAGEVIEW_ID, i->uncroppedWidth(), i->uncroppedHeight(), tileRect ) ) - { - Okular::PixmapRequest * p = new Okular::PixmapRequest( - PAGEVIEW_ID, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRIO, true ); - p->setNormalizedRect( tileRect ); - requestedPixmaps.push_back( p ); - } + Okular::PixmapRequest * p = new Okular::PixmapRequest( + PAGEVIEW_ID, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRIO, true ); + p->setNormalizedRect( tile.rect ); + requestedPixmaps.push_back( p ); } + tIt++; } }