Split tile structure in Tile and TileNode

The new class TileNode represents a node in the tree structure
whereas Tile is just a data structure to store the pixmap and tile rect
and is used outside tiles manager.
remotes/origin/KDE/4.10
Mailson Menezes 14 years ago
parent da54ffdd8e
commit f91f55d117
  1. 8
      core/document.cpp
  2. 123
      core/tilesmanager.cpp
  3. 38
      core/tilesmanager_p.h
  4. 28
      ui/pagepainter.cpp
  5. 12
      ui/pageview.cpp

@ -1109,9 +1109,9 @@ void DocumentPrivate::sendGeneratorRequest()
{ {
Tile tile = *tIt; Tile tile = *tIt;
if ( tilesRect.isNull() ) if ( tilesRect.isNull() )
tilesRect = tile.rect; tilesRect = tile.rect();
else else
tilesRect |= tile.rect; tilesRect |= tile.rect();
++tIt; ++tIt;
} }
@ -1319,9 +1319,9 @@ void DocumentPrivate::refreshPixmaps( int pageNumber )
{ {
Tile tile = *tIt; Tile tile = *tIt;
if ( tilesRect.isNull() ) if ( tilesRect.isNull() )
tilesRect = tile.rect; tilesRect = tile.rect();
else else
tilesRect |= tile.rect; tilesRect |= tile.rect();
tIt++; tIt++;
} }

@ -16,7 +16,7 @@
using namespace Okular; 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. // Order tiles by its dirty state and then by distance from the viewport.
if ( t1->dirty == t2->dirty ) if ( t1->dirty == t2->dirty )
@ -30,22 +30,22 @@ class TilesManager::Private
public: public:
Private(); Private();
bool hasPixmap( const NormalizedRect &rect, const Tile &tile ) const; bool hasPixmap( const NormalizedRect &rect, const TileNode &tile ) const;
void tilesAt( const NormalizedRect &rect, Tile &tile, QList<Tile> &result, bool allowEmpty ); void tilesAt( const NormalizedRect &rect, TileNode &tile, QList<Tile> &result, bool allowEmpty );
void setPixmap( const QPixmap *pixmap, const NormalizedRect &rect, Tile &tile ); void setPixmap( const QPixmap *pixmap, const NormalizedRect &rect, TileNode &tile );
/** /**
* Mark @p tile and all its children as dirty * Mark @p tile and all its children as dirty
*/ */
static void markDirty( Tile &tile ); static void markDirty( TileNode &tile );
/** /**
* Deletes all tiles, recursively * Deletes all tiles, recursively
*/ */
void deleteTiles( const Tile &tile ); void deleteTiles( const TileNode &tile );
void markParentDirty( const Tile &tile ); void markParentDirty( const TileNode &tile );
void rankTiles( Tile &tile, QList<Tile*> &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber ); void rankTiles( TileNode &tile, QList<TileNode*> &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber );
/** /**
* Since the tile can be large enough to occupy a significant amount of * 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 * 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 * than an arbitrary value. Only tiles intersecting the desired region
* are split. There's no need to do this for the entire page. * 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 * Checks whether the tile's size is bigger than an arbitrary value and
* performs the split operation returning true. * performs the split operation returning true.
* Otherwise it just returns false, without performing any operation. * 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 // The page is split in a 4x4 grid of tiles
Tile tiles[16]; TileNode tiles[16];
int width; int width;
int height; int height;
int pageNumber; int pageNumber;
@ -113,7 +113,7 @@ TilesManager::~TilesManager()
delete d; delete d;
} }
void TilesManager::Private::deleteTiles( const Tile &tile ) void TilesManager::Private::deleteTiles( const TileNode &tile )
{ {
if ( tile.pixmap ) 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; 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 ); QRect pixmapRect = TilesManager::toRotatedRect( rect, rotation ).geometry( width, height );
@ -318,7 +318,7 @@ bool TilesManager::hasPixmap( const NormalizedRect &rect )
return true; 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 ) ) if ( !tile.rect.intersects( rect ) )
return true; return true;
@ -352,7 +352,7 @@ QList<Tile> TilesManager::tilesAt( const NormalizedRect &rect, bool allowEmpty )
return result; return result;
} }
void TilesManager::Private::tilesAt( const NormalizedRect &rect, Tile &tile, QList<Tile> &result, bool allowEmpty ) void TilesManager::Private::tilesAt( const NormalizedRect &rect, TileNode &tile, QList<Tile> &result, bool allowEmpty )
{ {
if ( !tile.rect.intersects( rect ) ) if ( !tile.rect.intersects( rect ) )
return; return;
@ -363,10 +363,12 @@ void TilesManager::Private::tilesAt( const NormalizedRect &rect, Tile &tile, QLi
if ( ( allowEmpty && tile.nTiles == 0 ) || ( !allowEmpty && tile.pixmap ) ) if ( ( allowEmpty && tile.nTiles == 0 ) || ( !allowEmpty && tile.pixmap ) )
{ {
Tile newTile = tile; NormalizedRect rotatedRect;
if ( rotation != Rotation0 ) if ( rotation != Rotation0 )
newTile.rect = TilesManager::toRotatedRect( tile.rect, rotation ); rotatedRect = TilesManager::toRotatedRect( tile.rect, rotation );
result.append( newTile ); else
rotatedRect = tile.rect;
result.append( Tile( rotatedRect, tile.pixmap, tile.isValid() ) );
} }
else else
{ {
@ -382,7 +384,7 @@ long TilesManager::totalMemory() const
void TilesManager::cleanupPixmapMemory( qulonglong numberOfBytes, const NormalizedRect &visibleRect, int visiblePageNumber ) void TilesManager::cleanupPixmapMemory( qulonglong numberOfBytes, const NormalizedRect &visibleRect, int visiblePageNumber )
{ {
QList<Tile*> rankedTiles; QList<TileNode*> rankedTiles;
for ( int i = 0; i < 16; ++i ) for ( int i = 0; i < 16; ++i )
{ {
d->rankTiles( d->tiles[ i ], rankedTiles, visibleRect, visiblePageNumber ); d->rankTiles( d->tiles[ i ], rankedTiles, visibleRect, visiblePageNumber );
@ -391,7 +393,7 @@ void TilesManager::cleanupPixmapMemory( qulonglong numberOfBytes, const Normaliz
while ( numberOfBytes > 0 && !rankedTiles.isEmpty() ) while ( numberOfBytes > 0 && !rankedTiles.isEmpty() )
{ {
Tile *tile = rankedTiles.takeLast(); TileNode *tile = rankedTiles.takeLast();
if ( !tile->pixmap ) if ( !tile->pixmap )
continue; 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 ) if ( !tile.parent )
return; return;
@ -425,7 +427,7 @@ void TilesManager::Private::markParentDirty( const Tile &tile )
} }
} }
void TilesManager::Private::rankTiles( Tile &tile, QList<Tile*> &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber ) void TilesManager::Private::rankTiles( TileNode &tile, QList<TileNode*> &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber )
{ {
// If the page is visible, visibleRect is not null. // If the page is visible, visibleRect is not null.
// Otherwise we use the number of one of the visible pages to calculate the // 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; 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 ); QRect tileRect = tile.rect.geometry( width, height );
if ( tileRect.width()*tileRect.height() < TILES_MAXSIZE ) if ( tileRect.width()*tileRect.height() < TILES_MAXSIZE )
@ -487,7 +489,7 @@ bool TilesManager::Private::splitBigTiles( Tile &tile, const NormalizedRect &rec
return true; return true;
} }
void TilesManager::Private::split( Tile &tile, const NormalizedRect &rect ) void TilesManager::Private::split( TileNode &tile, const NormalizedRect &rect )
{ {
if ( tile.nTiles != 0 ) if ( tile.nTiles != 0 )
return; return;
@ -496,7 +498,7 @@ void TilesManager::Private::split( Tile &tile, const NormalizedRect &rect )
return; return;
tile.nTiles = 4; tile.nTiles = 4;
tile.tiles = new Tile[4]; tile.tiles = new TileNode[4];
double hCenter = (tile.rect.left + tile.rect.right)/2; double hCenter = (tile.rect.left + tile.rect.right)/2;
double vCenter = (tile.rect.top + tile.rect.bottom)/2; double vCenter = (tile.rect.top + tile.rect.bottom)/2;
@ -562,7 +564,7 @@ NormalizedRect TilesManager::toRotatedRect( const NormalizedRect &rect, Rotation
return newRect; return newRect;
} }
Tile::Tile() TileNode::TileNode()
: pixmap( 0 ) : pixmap( 0 )
, dirty ( true ) , dirty ( true )
, distance( -1 ) , distance( -1 )
@ -572,7 +574,72 @@ Tile::Tile()
{ {
} }
bool Tile::isValid() const bool TileNode::isValid() const
{ {
return pixmap && !dirty; 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;
}

@ -33,20 +33,40 @@ namespace Okular {
class OKULAR_EXPORT Tile class OKULAR_EXPORT Tile
{ {
public: 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; QPixmap *pixmap;
/** /**
* Whether the tile needs to be repainted (after a zoom or rotation) * 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. * This is used by the evicting algorithm.
*/ */
double distance; double distance;
/** /**
* Children tiles * Children tiles
* When a tile is split into multiple tiles it doesn't cease to exist. * 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 * 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) * its tiles (eg: when we need to list all tiles from an small area)
*/ */
Tile *tiles; TileNode *tiles;
int nTiles; int nTiles;
TileNode *parent;
Tile *parent;
}; };
/** /**

@ -245,16 +245,16 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
while ( tIt != tEnd ) while ( tIt != tEnd )
{ {
Okular::Tile tile = *tIt; Okular::Tile tile = *tIt;
QRect tileRect = tile.rect.geometry( scaledWidth, scaledHeight ); QRect tileRect = tile.rect().geometry( scaledWidth, scaledHeight );
QRect limitsInTile = limits & tileRect; 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() ) if ( tile.pixmap()->width() == tileRect.width() && tile.pixmap()->height() == tileRect.height() )
destPainter->drawPixmap( limitsInTile.topLeft(), *(tile.pixmap), destPainter->drawPixmap( limitsInTile.topLeft(), *(tile.pixmap()),
limitsInTile.translated( -tileRect.topLeft() ) ); limitsInTile.translated( -tileRect.topLeft() ) );
else else
destPainter->drawPixmap( tile.rect.geometry( scaledWidth, scaledHeight ), destPainter->drawPixmap( tile.rect().geometry( scaledWidth, scaledHeight ),
*(tile.pixmap) ); *(tile.pixmap()) );
} }
tIt++; tIt++;
} }
@ -301,24 +301,24 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
while ( tIt != tEnd ) while ( tIt != tEnd )
{ {
Okular::Tile tile = *tIt; Okular::Tile tile = *tIt;
QRect tileRect = tile.rect.geometry( scaledWidth, scaledHeight ); QRect tileRect = tile.rect().geometry( scaledWidth, scaledHeight );
QRect limitsInTile = limits & tileRect; 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; 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() ) ); limitsInTile.translated( -tileRect.topLeft() ) );
} }
else else
{ {
double xScale = tile.pixmap->width() / (double)tileRect.width(); double xScale = tile.pixmap()->width() / (double)tileRect.width();
double yScale = tile.pixmap->height() / (double)tileRect.height(); double yScale = tile.pixmap()->height() / (double)tileRect.height();
QTransform transform( xScale, 0, 0, yScale, 0, 0 ); 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() ) ); transform.mapRect( limitsInTile ).translated( -transform.mapRect( tileRect ).topLeft() ) );
} }
} }

@ -4055,9 +4055,9 @@ void PageView::slotRequestVisiblePixmaps( int newValue )
if ( !tile.isValid() ) if ( !tile.isValid() )
{ {
if ( tilesRect.isNull() ) if ( tilesRect.isNull() )
tilesRect = tile.rect; tilesRect = tile.rect();
else else
tilesRect |= tile.rect; tilesRect |= tile.rect();
} }
tIt++; tIt++;
@ -4134,9 +4134,9 @@ void PageView::slotRequestVisiblePixmaps( int newValue )
if ( !tile.isValid() ) if ( !tile.isValid() )
{ {
if ( tilesRect.isNull() ) if ( tilesRect.isNull() )
tilesRect = tile.rect; tilesRect = tile.rect();
else else
tilesRect |= tile.rect; tilesRect |= tile.rect();
} }
tIt++; tIt++;
@ -4182,9 +4182,9 @@ void PageView::slotRequestVisiblePixmaps( int newValue )
if ( !tile.isValid() ) if ( !tile.isValid() )
{ {
if ( tilesRect.isNull() ) if ( tilesRect.isNull() )
tilesRect = tile.rect; tilesRect = tile.rect();
else else
tilesRect |= tile.rect; tilesRect |= tile.rect();
} }
tIt++; tIt++;

Loading…
Cancel
Save