File indexing completed on 2024-04-28 04:32:47
0001 /* 0002 SPDX-FileCopyrightText: 2012 Mailson Menezes <mailson@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #ifndef _OKULAR_TILES_MANAGER_P_H_ 0007 #define _OKULAR_TILES_MANAGER_P_H_ 0008 0009 #include "area.h" 0010 #include "okularcore_export.h" 0011 0012 class QPixmap; 0013 0014 namespace Okular 0015 { 0016 class Tile; 0017 0018 /** 0019 * Node in the quadtree structure used by the tiles manager to store tiles. 0020 * 0021 * Except for the first level, the tiles manager stores tiles in a quadtree 0022 * structure. 0023 * Each node stores the pixmap of a tile and its location on the page. 0024 * There's a limit on the size of the pixmaps (TILES_MAXSIZE, defined in 0025 * tilesmanager.cpp), and tiles that are bigger than that value are split into 0026 * four children tiles, which are stored as children of the original tile. 0027 * If children tiles are still too big, they are recursively split again. 0028 * If the zoom level changes and a big tile goes below the limit, it is merged 0029 * back into a leaf tile. 0030 */ 0031 class TileNode 0032 { 0033 public: 0034 TileNode(); 0035 0036 bool isValid() const; 0037 0038 /** 0039 * Location on the page in normalized coords 0040 */ 0041 NormalizedRect rect; 0042 0043 /** 0044 * Associated pixmap or NULL if not present 0045 * 0046 * For each node, it is guaranteed that there's no more than one pixmap 0047 * along the path from the root to the node itself. 0048 * In fact, it is very frequent that a leaf node has no pixmap and one 0049 * of its ancestors has. Such a situation shows, for example, when the 0050 * parent tile still has a dirty tile from a previous lower zoom level. 0051 */ 0052 QPixmap *pixmap; 0053 0054 /** 0055 * Rotation of this individual tile. 0056 * 0057 * A rotation to the page does not immediately rotates the pixmaps in 0058 * cache. This operation happens when pixmaps are going to be used. 0059 */ 0060 Rotation rotation; 0061 0062 /** 0063 * Whether the tile needs to be repainted (after a zoom or rotation) 0064 * If a tile doesn't have a pixmap but all its children are updated 0065 * (dirty = false), the parent tile is also considered updated. 0066 */ 0067 bool dirty; 0068 0069 /** 0070 Whether the tile contains a partially rendered pixmap. 0071 Some backends, such as PDF, can send partial updates that contain 0072 only some of the page's elements (e.g. only a background image) drawn. 0073 */ 0074 bool partial; 0075 0076 /** 0077 * Distance between the tile and the viewport. 0078 * This is used by the evicting algorithm. 0079 */ 0080 double distance; 0081 0082 /** 0083 * Children tiles 0084 * When a tile is split into multiple tiles, they're added as children. 0085 * nTiles can be either 0 (in leaf tiles) or 4 (in split tiles). 0086 */ 0087 TileNode *tiles; 0088 int nTiles; 0089 TileNode *parent; 0090 }; 0091 0092 /** 0093 * @short Tiles management 0094 * 0095 * This class has direct access to all tiles and handles how they should be 0096 * stored, deleted and retrieved. Each tiles manager only handles one page. 0097 * 0098 * The tiles manager is a tree of tiles. At first the page is divided in a 4x4 0099 * grid of 16 tiles. Then each of these tiles can be recursively split in 4 0100 * subtiles so that we keep the size of each pixmap inside a safe interval. 0101 */ 0102 class TilesManager 0103 { 0104 public: 0105 enum TileLeaf { 0106 TerminalTile, ///< Return tiles without children 0107 PixmapTile ///< Return only tiles with pixmap 0108 }; 0109 0110 TilesManager(int pageNumber, int width, int height, Rotation rotation = Rotation0); 0111 ~TilesManager(); 0112 0113 TilesManager(const TilesManager &) = delete; 0114 TilesManager &operator=(const TilesManager &) = delete; 0115 0116 /** 0117 * Sets the pixmap of the tiles covered by @p rect (which represents 0118 * the location of @p pixmap on the page). 0119 * @p pixmap may cover an area which contains multiple tiles. So each 0120 * tile we get a cropped part of the @p pixmap. 0121 * 0122 * Also it checks the dimensions of the given parameters against the 0123 * current request as to avoid setting pixmaps of late requests. 0124 */ 0125 void setPixmap(const QPixmap *pixmap, const NormalizedRect &rect, bool isPartialPixmap); 0126 0127 /** 0128 * Checks whether all tiles intersecting with @p rect are available. 0129 * Returns false if at least one tile needs to be repainted (the tile 0130 * is dirty). 0131 */ 0132 bool hasPixmap(const NormalizedRect &rect); 0133 0134 /** 0135 * Returns a list of all tiles intersecting with @p rect. 0136 * 0137 * As to avoid requests of big areas, each traversed tile is checked 0138 * for its size and split if necessary. 0139 * 0140 * @param rect The normalized rectangular area 0141 * @param tileLeaf Indicate the type of tile to return 0142 */ 0143 QList<Tile> tilesAt(const NormalizedRect &rect, TileLeaf tileLeaf); 0144 0145 /** 0146 * The total memory consumed by the tiles manager 0147 */ 0148 qulonglong totalMemory() const; 0149 0150 /** 0151 * Removes at least @p numberOfBytes bytes worth of tiles (least ranked 0152 * tiles are removed first). 0153 * Set @p visibleRect to the visible region of the page. Set a 0154 * @p visiblePageNumber if the current page is not visible. 0155 * Visible tiles are not discarded. 0156 */ 0157 void cleanupPixmapMemory(qulonglong numberOfBytes, const NormalizedRect &visibleRect, int visiblePageNumber); 0158 0159 /** 0160 * Checks whether a given region has already been requested 0161 */ 0162 bool isRequesting(const NormalizedRect &rect, int pageWidth, int pageHeight) const; 0163 0164 /** 0165 * Sets a region to be requested so the tiles manager knows which 0166 * pixmaps to expect and discard those not useful anymore (late pixmaps) 0167 */ 0168 void setRequest(const NormalizedRect &rect, int pageWidth, int pageHeight); 0169 0170 /** 0171 * Inform the new size of the page and mark all tiles to repaint 0172 */ 0173 void setSize(int width, int height); 0174 0175 /** 0176 * Gets the width of the page in tiles manager 0177 */ 0178 int width() const; 0179 0180 /** 0181 * Gets the height of the page in tiles manager 0182 */ 0183 int height() const; 0184 0185 /** 0186 * Inform the new rotation of the page 0187 */ 0188 void setRotation(Rotation rotation); 0189 Rotation rotation() const; 0190 0191 /** 0192 * Mark all tiles as dirty 0193 */ 0194 void markDirty(); 0195 0196 /** 0197 * Returns a rotated NormalizedRect given a @p rotation 0198 */ 0199 static NormalizedRect toRotatedRect(const NormalizedRect &rect, Rotation rotation); 0200 0201 /** 0202 * Returns a non rotated version of @p rect, which is rotated by @p rotation 0203 */ 0204 static NormalizedRect fromRotatedRect(const NormalizedRect &rect, Rotation rotation); 0205 0206 private: 0207 class Private; 0208 Private *const d; 0209 friend class Private; 0210 }; 0211 0212 } 0213 0214 #endif // _OKULAR_TILES_MANAGER_P_H_