diff --git a/core/document.cpp b/core/document.cpp index 9253a7cc5..1e1cf249d 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -1109,9 +1109,9 @@ void DocumentPrivate::sendGeneratorRequest() { Tile tile = *tIt; if ( tilesRect.isNull() ) - tilesRect = tile.rect; + tilesRect = tile.rect(); else - tilesRect |= tile.rect; + tilesRect |= tile.rect(); ++tIt; } @@ -1319,9 +1319,9 @@ void DocumentPrivate::refreshPixmaps( int pageNumber ) { Tile tile = *tIt; if ( tilesRect.isNull() ) - tilesRect = tile.rect; + tilesRect = tile.rect(); else - tilesRect |= tile.rect; + tilesRect |= tile.rect(); tIt++; } diff --git a/core/tilesmanager.cpp b/core/tilesmanager.cpp index c376f899e..cf13f7b3a 100644 --- a/core/tilesmanager.cpp +++ b/core/tilesmanager.cpp @@ -16,7 +16,7 @@ using namespace Okular; -static bool rankedTilesLessThan( Tile *t1, Tile *t2 ) +static bool rankedTilesLessThan( TileNode *t1, TileNode *t2 ) { // Order tiles by its dirty state and then by distance from the viewport. if ( t1->dirty == t2->dirty ) @@ -30,22 +30,22 @@ class TilesManager::Private public: Private(); - bool hasPixmap( const NormalizedRect &rect, const Tile &tile ) const; - void tilesAt( const NormalizedRect &rect, Tile &tile, QList &result, bool allowEmpty ); - void setPixmap( const QPixmap *pixmap, const NormalizedRect &rect, Tile &tile ); + bool hasPixmap( const NormalizedRect &rect, const TileNode &tile ) const; + void tilesAt( const NormalizedRect &rect, TileNode &tile, QList &result, bool allowEmpty ); + void setPixmap( const QPixmap *pixmap, const NormalizedRect &rect, TileNode &tile ); /** * Mark @p tile and all its children as dirty */ - static void markDirty( Tile &tile ); + static void markDirty( TileNode &tile ); /** * Deletes all tiles, recursively */ - void deleteTiles( const Tile &tile ); + void deleteTiles( const TileNode &tile ); - void markParentDirty( const Tile &tile ); - void rankTiles( Tile &tile, QList &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber ); + void markParentDirty( const TileNode &tile ); + void rankTiles( TileNode &tile, QList &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber ); /** * Since the tile can be large enough to occupy a significant amount of * space, they may be split in more tiles. This operation is performed @@ -53,17 +53,17 @@ class TilesManager::Private * than an arbitrary value. Only tiles intersecting the desired region * are split. There's no need to do this for the entire page. */ - void split( Tile &tile, const NormalizedRect &rect ); + void split( TileNode &tile, const NormalizedRect &rect ); /** * Checks whether the tile's size is bigger than an arbitrary value and * performs the split operation returning true. * Otherwise it just returns false, without performing any operation. */ - bool splitBigTiles( Tile &tile, const NormalizedRect &rect ); + bool splitBigTiles( TileNode &tile, const NormalizedRect &rect ); // The page is split in a 4x4 grid of tiles - Tile tiles[16]; + TileNode tiles[16]; int width; int height; int pageNumber; @@ -113,7 +113,7 @@ TilesManager::~TilesManager() delete d; } -void TilesManager::Private::deleteTiles( const Tile &tile ) +void TilesManager::Private::deleteTiles( const TileNode &tile ) { if ( tile.pixmap ) { @@ -181,7 +181,7 @@ void TilesManager::markDirty() } } -void TilesManager::Private::markDirty( Tile &tile ) +void TilesManager::Private::markDirty( TileNode &tile ) { tile.dirty = true; @@ -207,7 +207,7 @@ void TilesManager::setPixmap( const QPixmap *pixmap, const NormalizedRect &rect } } -void TilesManager::Private::setPixmap( const QPixmap *pixmap, const NormalizedRect &rect, Tile &tile ) +void TilesManager::Private::setPixmap( const QPixmap *pixmap, const NormalizedRect &rect, TileNode &tile ) { QRect pixmapRect = TilesManager::toRotatedRect( rect, rotation ).geometry( width, height ); @@ -318,7 +318,7 @@ bool TilesManager::hasPixmap( const NormalizedRect &rect ) return true; } -bool TilesManager::Private::hasPixmap( const NormalizedRect &rect, const Tile &tile ) const +bool TilesManager::Private::hasPixmap( const NormalizedRect &rect, const TileNode &tile ) const { if ( !tile.rect.intersects( rect ) ) return true; @@ -352,7 +352,7 @@ QList TilesManager::tilesAt( const NormalizedRect &rect, bool allowEmpty ) return result; } -void TilesManager::Private::tilesAt( const NormalizedRect &rect, Tile &tile, QList &result, bool allowEmpty ) +void TilesManager::Private::tilesAt( const NormalizedRect &rect, TileNode &tile, QList &result, bool allowEmpty ) { if ( !tile.rect.intersects( rect ) ) return; @@ -363,10 +363,12 @@ void TilesManager::Private::tilesAt( const NormalizedRect &rect, Tile &tile, QLi if ( ( allowEmpty && tile.nTiles == 0 ) || ( !allowEmpty && tile.pixmap ) ) { - Tile newTile = tile; + NormalizedRect rotatedRect; if ( rotation != Rotation0 ) - newTile.rect = TilesManager::toRotatedRect( tile.rect, rotation ); - result.append( newTile ); + rotatedRect = TilesManager::toRotatedRect( tile.rect, rotation ); + else + rotatedRect = tile.rect; + result.append( Tile( rotatedRect, tile.pixmap, tile.isValid() ) ); } else { @@ -382,7 +384,7 @@ long TilesManager::totalMemory() const void TilesManager::cleanupPixmapMemory( qulonglong numberOfBytes, const NormalizedRect &visibleRect, int visiblePageNumber ) { - QList rankedTiles; + QList rankedTiles; for ( int i = 0; i < 16; ++i ) { d->rankTiles( d->tiles[ i ], rankedTiles, visibleRect, visiblePageNumber ); @@ -391,7 +393,7 @@ void TilesManager::cleanupPixmapMemory( qulonglong numberOfBytes, const Normaliz while ( numberOfBytes > 0 && !rankedTiles.isEmpty() ) { - Tile *tile = rankedTiles.takeLast(); + TileNode *tile = rankedTiles.takeLast(); if ( !tile->pixmap ) continue; @@ -413,7 +415,7 @@ void TilesManager::cleanupPixmapMemory( qulonglong numberOfBytes, const Normaliz } } -void TilesManager::Private::markParentDirty( const Tile &tile ) +void TilesManager::Private::markParentDirty( const TileNode &tile ) { if ( !tile.parent ) return; @@ -425,7 +427,7 @@ void TilesManager::Private::markParentDirty( const Tile &tile ) } } -void TilesManager::Private::rankTiles( Tile &tile, QList &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber ) +void TilesManager::Private::rankTiles( TileNode &tile, QList &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber ) { // If the page is visible, visibleRect is not null. // Otherwise we use the number of one of the visible pages to calculate the @@ -477,7 +479,7 @@ void TilesManager::setRequest( const NormalizedRect &rect, int pageWidth, int pa d->requestHeight = pageHeight; } -bool TilesManager::Private::splitBigTiles( Tile &tile, const NormalizedRect &rect ) +bool TilesManager::Private::splitBigTiles( TileNode &tile, const NormalizedRect &rect ) { QRect tileRect = tile.rect.geometry( width, height ); if ( tileRect.width()*tileRect.height() < TILES_MAXSIZE ) @@ -487,7 +489,7 @@ bool TilesManager::Private::splitBigTiles( Tile &tile, const NormalizedRect &rec return true; } -void TilesManager::Private::split( Tile &tile, const NormalizedRect &rect ) +void TilesManager::Private::split( TileNode &tile, const NormalizedRect &rect ) { if ( tile.nTiles != 0 ) return; @@ -496,7 +498,7 @@ void TilesManager::Private::split( Tile &tile, const NormalizedRect &rect ) return; tile.nTiles = 4; - tile.tiles = new Tile[4]; + tile.tiles = new TileNode[4]; double hCenter = (tile.rect.left + tile.rect.right)/2; double vCenter = (tile.rect.top + tile.rect.bottom)/2; @@ -562,7 +564,7 @@ NormalizedRect TilesManager::toRotatedRect( const NormalizedRect &rect, Rotation return newRect; } -Tile::Tile() +TileNode::TileNode() : pixmap( 0 ) , dirty ( true ) , distance( -1 ) @@ -572,7 +574,72 @@ Tile::Tile() { } -bool Tile::isValid() const +bool TileNode::isValid() const { return pixmap && !dirty; } + +class Tile::Private +{ + public: + Private(); + + NormalizedRect rect; + QPixmap *pixmap; + bool isValid; +}; + +Tile::Private::Private() + : pixmap( 0 ) + , isValid( false ) +{ +} + +Tile::Tile( const NormalizedRect &rect, QPixmap *pixmap, bool isValid ) + : d( new Tile::Private ) +{ + d->rect = rect; + d->pixmap = pixmap; + d->isValid = isValid; +} + +Tile::Tile( const Tile &t ) + : d( new Tile::Private ) +{ + d->rect = t.d->rect; + d->pixmap = t.d->pixmap; + d->isValid = t.d->isValid; +} + +Tile & Tile::operator=( const Tile &t ) +{ + if ( this == &t ) + return *this; + + d = new Tile::Private; + d->rect = t.d->rect; + d->pixmap = t.d->pixmap; + d->isValid = t.d->isValid; + + return *this; +} + +Tile::~Tile() +{ + delete d; +} + +NormalizedRect Tile::rect() const +{ + return d->rect; +} + +QPixmap * Tile::pixmap() const +{ + return d->pixmap; +} + +bool Tile::isValid() const +{ + return d->isValid; +} diff --git a/core/tilesmanager_p.h b/core/tilesmanager_p.h index 16b084e3c..35c2f73d8 100644 --- a/core/tilesmanager_p.h +++ b/core/tilesmanager_p.h @@ -33,20 +33,40 @@ namespace Okular { class OKULAR_EXPORT Tile { public: - Tile(); + Tile( const NormalizedRect &rect, QPixmap *pixmap, bool isValid ); + Tile( const Tile &t ); + ~Tile(); /** - * True if the pixmap is available and updated + * Location of the tile */ - bool isValid() const; + NormalizedRect rect() const; /** - * Location of the tile + * Pixmap (may also be NULL) */ - NormalizedRect rect; + QPixmap * pixmap() const; + /** - * Pixmap (may also be NULL) + * True if the pixmap is available and updated */ + bool isValid() const; + + Tile & operator=( const Tile &t ); + + private: + class Private; + Private * d; +}; + +class TileNode +{ + public: + TileNode(); + + bool isValid() const; + + NormalizedRect rect; QPixmap *pixmap; /** * Whether the tile needs to be repainted (after a zoom or rotation) @@ -59,7 +79,6 @@ class OKULAR_EXPORT Tile * This is used by the evicting algorithm. */ double distance; - /** * Children tiles * When a tile is split into multiple tiles it doesn't cease to exist. @@ -68,10 +87,9 @@ class OKULAR_EXPORT Tile * consider if a large area should be evaluated without visiting all * its tiles (eg: when we need to list all tiles from an small area) */ - Tile *tiles; + TileNode *tiles; int nTiles; - - Tile *parent; + TileNode *parent; }; /** diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp index 9f0f923cd..a9b4bb45c 100644 --- a/ui/pagepainter.cpp +++ b/ui/pagepainter.cpp @@ -245,16 +245,16 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula while ( tIt != tEnd ) { Okular::Tile tile = *tIt; - QRect tileRect = tile.rect.geometry( scaledWidth, scaledHeight ); + QRect tileRect = tile.rect().geometry( scaledWidth, scaledHeight ); QRect limitsInTile = limits & tileRect; - if ( tile.pixmap && !limitsInTile.isEmpty() ) + if ( tile.pixmap() && !limitsInTile.isEmpty() ) { - if ( tile.pixmap->width() == tileRect.width() && tile.pixmap->height() == tileRect.height() ) - destPainter->drawPixmap( limitsInTile.topLeft(), *(tile.pixmap), + if ( tile.pixmap()->width() == tileRect.width() && tile.pixmap()->height() == tileRect.height() ) + destPainter->drawPixmap( limitsInTile.topLeft(), *(tile.pixmap()), limitsInTile.translated( -tileRect.topLeft() ) ); else - destPainter->drawPixmap( tile.rect.geometry( scaledWidth, scaledHeight ), - *(tile.pixmap) ); + destPainter->drawPixmap( tile.rect().geometry( scaledWidth, scaledHeight ), + *(tile.pixmap()) ); } tIt++; } @@ -301,24 +301,24 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula while ( tIt != tEnd ) { Okular::Tile tile = *tIt; - QRect tileRect = tile.rect.geometry( scaledWidth, scaledHeight ); + QRect tileRect = tile.rect().geometry( scaledWidth, scaledHeight ); QRect limitsInTile = limits & tileRect; - if ( tile.pixmap && !limitsInTile.isEmpty() ) + if ( tile.pixmap() && !limitsInTile.isEmpty() ) { - if ( !tile.pixmap->hasAlpha() ) + if ( !tile.pixmap()->hasAlpha() ) has_alpha = false; - if ( tile.pixmap->width() == tileRect.width() && tile.pixmap->height() == tileRect.height() ) + if ( tile.pixmap()->width() == tileRect.width() && tile.pixmap()->height() == tileRect.height() ) { - p.drawPixmap( limitsInTile.translated( -limits.topLeft() ).topLeft(), *(tile.pixmap), + p.drawPixmap( limitsInTile.translated( -limits.topLeft() ).topLeft(), *(tile.pixmap()), limitsInTile.translated( -tileRect.topLeft() ) ); } else { - double xScale = tile.pixmap->width() / (double)tileRect.width(); - double yScale = tile.pixmap->height() / (double)tileRect.height(); + double xScale = tile.pixmap()->width() / (double)tileRect.width(); + double yScale = tile.pixmap()->height() / (double)tileRect.height(); QTransform transform( xScale, 0, 0, yScale, 0, 0 ); - p.drawPixmap( limitsInTile.translated( -limits.topLeft() ), *(tile.pixmap), + p.drawPixmap( limitsInTile.translated( -limits.topLeft() ), *(tile.pixmap()), transform.mapRect( limitsInTile ).translated( -transform.mapRect( tileRect ).topLeft() ) ); } } diff --git a/ui/pageview.cpp b/ui/pageview.cpp index 6151b0d7e..b766058cd 100644 --- a/ui/pageview.cpp +++ b/ui/pageview.cpp @@ -4055,9 +4055,9 @@ void PageView::slotRequestVisiblePixmaps( int newValue ) if ( !tile.isValid() ) { if ( tilesRect.isNull() ) - tilesRect = tile.rect; + tilesRect = tile.rect(); else - tilesRect |= tile.rect; + tilesRect |= tile.rect(); } tIt++; @@ -4134,9 +4134,9 @@ void PageView::slotRequestVisiblePixmaps( int newValue ) if ( !tile.isValid() ) { if ( tilesRect.isNull() ) - tilesRect = tile.rect; + tilesRect = tile.rect(); else - tilesRect |= tile.rect; + tilesRect |= tile.rect(); } tIt++; @@ -4182,9 +4182,9 @@ void PageView::slotRequestVisiblePixmaps( int newValue ) if ( !tile.isValid() ) { if ( tilesRect.isNull() ) - tilesRect = tile.rect; + tilesRect = tile.rect(); else - tilesRect |= tile.rect; + tilesRect |= tile.rect(); } tIt++;