okular/core/tilesmanager_p.h
Albert Astals Cid 2d8b2c7e95 Add support for cancellable image rendering and text extraction
Summary:
Only supported by the pdf backend if using poppler >= 0.63

Sadly had to change the generator API

Text cancellation is a bit wobbly still since poppler has large parts
of the code where doesn't check for the cancellation flag, but that
is something that will get automagically fixed for us if the poppler
side is improved

Test Plan: Needs https://bugs.freedesktop.org/show_bug.cgi?id=104263

Reviewers: ervin, rkflx

Reviewed By: ervin, rkflx

Subscribers: #okular

Tags: #okular

Differential Revision: https://phabricator.kde.org/D9328
2018-02-01 22:53:28 +01:00

208 lines
6.9 KiB
C++

/***************************************************************************
* Copyright (C) 2012 by Mailson Menezes <mailson@gmail.com> *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef _OKULAR_TILES_MANAGER_P_H_
#define _OKULAR_TILES_MANAGER_P_H_
#include "okularcore_export.h"
#include "area.h"
class QPixmap;
namespace Okular {
class Tile;
/**
* Node in the quadtree structure used by the tiles manager to store tiles.
*
* Except for the first level, the tiles manager stores tiles in a quadtree
* structure.
* Each node stores the pixmap of a tile and its location on the page.
* There's a limit on the size of the pixmaps (TILES_MAXSIZE, defined in
* tilesmanager.cpp), and tiles that are bigger than that value are split into
* four children tiles, which are stored as children of the original tile.
* If children tiles are still too big, they are recursively split again.
* If the zoom level changes and a big tile goes below the limit, it is merged
* back into a leaf tile.
*/
class TileNode
{
public:
TileNode();
bool isValid() const;
/**
* Location on the page in normalized coords
*/
NormalizedRect rect;
/**
* Associated pixmap or NULL if not present
*
* For each node, it is guaranteed that there's no more than one pixmap
* along the path from the root to the node itself.
* In fact, it is very frequent that a leaf node has no pixmap and one
* of its ancestors has. Such a situation shows, for example, when the
* parent tile still has a dirty tile from a previous lower zoom level.
*/
QPixmap *pixmap;
/**
* Rotation of this individual tile.
*
* A rotation to the page does not immediately rotates the pixmaps in
* cache. This operation happens when pixmaps are going to be used.
*/
Rotation rotation;
/**
* Whether the tile needs to be repainted (after a zoom or rotation)
* If a tile doesn't have a pixmap but all its children are updated
* (dirty = false), the parent tile is also considered updated.
*/
bool dirty;
/**
* Distance between the tile and the viewport.
* This is used by the evicting algorithm.
*/
double distance;
/**
* Children tiles
* When a tile is split into multiple tiles, they're added as children.
* nTiles can be either 0 (in leaf tiles) or 4 (in split tiles).
*/
TileNode *tiles;
int nTiles;
TileNode *parent;
};
/**
* @short Tiles management
*
* This class has direct access to all tiles and handles how they should be
* stored, deleted and retrieved. Each tiles manager only handles one page.
*
* The tiles manager is a tree of tiles. At first the page is divided in a 4x4
* grid of 16 tiles. Then each of these tiles can be recursively split in 4
* subtiles so that we keep the size of each pixmap inside a safe interval.
*/
class TilesManager
{
public:
enum TileLeaf
{
TerminalTile, ///< Return tiles without children
PixmapTile ///< Return only tiles with pixmap
};
TilesManager( int pageNumber, int width, int height, Rotation rotation = Rotation0 );
~TilesManager();
/**
* Sets the pixmap of the tiles covered by @p rect (which represents
* the location of @p pixmap on the page).
* @p pixmap may cover an area which contains multiple tiles. So each
* tile we get a cropped part of the @p pixmap.
*
* Also it checks the dimensions of the given parameters against the
* current request as to avoid setting pixmaps of late requests.
*/
void setPixmap( const QPixmap *pixmap, const NormalizedRect &rect, bool isPartialPixmap );
/**
* Checks whether all tiles intersecting with @p rect are available.
* Returns false if at least one tile needs to be repainted (the tile
* is dirty).
*/
bool hasPixmap( const NormalizedRect &rect );
/**
* Returns a list of all tiles intersecting with @p rect.
*
* As to avoid requests of big areas, each traversed tile is checked
* for its size and split if necessary.
*
* @param tileLeaf Indicate the type of tile to return
*/
QList<Tile> tilesAt( const NormalizedRect &rect, TileLeaf tileLeaf );
/**
* The total memory consumed by the tiles manager
*/
qulonglong totalMemory() const;
/**
* Removes at least @p numberOfBytes bytes worth of tiles (least ranked
* tiles are removed first).
* Set @p visibleRect to the visible region of the page. Set a
* @p visiblePageNumber if the current page is not visible.
* Visible tiles are not discarded.
*/
void cleanupPixmapMemory( qulonglong numberOfBytes, const NormalizedRect &visibleRect, int visiblePageNumber );
/**
* Checks whether a given region has already been requested
*/
bool isRequesting( const NormalizedRect &rect, int pageWidth, int pageHeight ) const;
/**
* Sets a region to be requested so the tiles manager knows which
* pixmaps to expect and discard those not useful anymore (late pixmaps)
*/
void setRequest( const NormalizedRect &rect, int pageWidth, int pageHeight );
/**
* Inform the new size of the page and mark all tiles to repaint
*/
void setSize( int width, int height );
/**
* Gets the width of the page in tiles manager
*/
int width() const;
/**
* Gets the height of the page in tiles manager
*/
int height() const;
/**
* Inform the new rotation of the page
*/
void setRotation( Rotation rotation );
Rotation rotation() const;
/**
* Mark all tiles as dirty
*/
void markDirty();
/**
* Returns a rotated NormalizedRect given a @p rotation
*/
static NormalizedRect toRotatedRect( const NormalizedRect &rect, Rotation rotation );
/**
* Returns a non rotated version of @p rect, which is rotated by @p rotation
*/
static NormalizedRect fromRotatedRect( const NormalizedRect &rect, Rotation rotation );
private:
class Private;
Private * const d;
friend class Private;
};
}
#endif // _OKULAR_TILES_MANAGER_P_H_