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;
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++;
}

@ -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<Tile> &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<Tile> &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<Tile*> &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber );
void markParentDirty( const TileNode &tile );
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
* 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<Tile> TilesManager::tilesAt( const NormalizedRect &rect, bool allowEmpty )
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 ) )
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<Tile*> rankedTiles;
QList<TileNode*> 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<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.
// 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;
}

@ -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;
};
/**

@ -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() ) );
}
}

@ -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++;

Loading…
Cancel
Save