/* * Copyright (c) 2004 Boudewijn Rempt * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_TILEDDATAMANAGER_H_ #define KIS_TILEDDATAMANAGER_H_ #include #include #include #include "kis_tile_global.h" #include "kis_tile.h" #include "kis_memento.h" class KisTiledDataManager; typedef TDESharedPtr KisTiledDataManagerSP; class KisDataManager; typedef TDESharedPtr KisDataManagerSP; class KisTiledIterator; class KisTiledRandomAccessor; class KoStore; class KisTileDataWrapper : public TDEShared { KisTile* m_tile; TQ_INT32 m_offset; public: KisTileDataWrapper(KisTile* tile, TQ_INT32 offset); virtual ~KisTileDataWrapper(); TQ_UINT8* data() const { return m_tile->data() + m_offset; } }; typedef TDESharedPtr KisTileDataWrapperSP; /** * KisTiledDataManager implements the interface that KisDataManager defines * * The interface definition is enforced by KisDataManager calling all the methods * which must also be defined in KisTiledDataManager. It is not allowed to change the interface * as other datamangers may also rely on the same interface. * * * Storing undo/redo data * * Offering ordered and unordered iterators over rects of pixels * * (eventually) efficiently loading and saving data in a format * that may allow deferred loading. * * A datamanager knows nothing about the type of pixel data except * how many TQ_UINT8's a single pixel takes. */ class KisTiledDataManager : public TDEShared { protected: KisTiledDataManager(TQ_UINT32 pixelSize, const TQ_UINT8 *defPixel); ~KisTiledDataManager(); KisTiledDataManager(const KisTiledDataManager &dm); KisTiledDataManager & operator=(const KisTiledDataManager &dm); protected: // Allow the baseclass of iterators acces to the interior // derived iterator classes must go through KisTiledIterator friend class KisTiledIterator; friend class KisTiledRandomAccessor; protected: void setDefaultPixel(const TQ_UINT8 *defPixel); const TQ_UINT8 * defaultPixel() const { return m_defPixel;}; KisMementoSP getMemento(); void rollback(KisMementoSP memento); void rollforward(KisMementoSP memento); // For debugging use. bool hasCurrentMemento() const { return m_currentMemento != 0; } protected: /** * Reads and writes the tiles from/onto a KoStore (which is simply a file within a zip file) * */ bool write(KoStore *store); bool read(KoStore *store); protected: TQ_UINT32 pixelSize(); void extent(TQ_INT32 &x, TQ_INT32 &y, TQ_INT32 &w, TQ_INT32 &h) const; TQRect extent() const; void setExtent(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h); protected: void clear(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h, TQ_UINT8 clearValue); void clear(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h, const TQ_UINT8 *clearPixel); void clear(); protected: void paste(KisDataManagerSP data, TQ_INT32 sx, TQ_INT32 sy, TQ_INT32 dx, TQ_INT32 dy, TQ_INT32 w, TQ_INT32 h); protected: /** * Get a read-only pointer to pixel (x, y). */ const TQ_UINT8* pixel(TQ_INT32 x, TQ_INT32 y); /** * Get a read-write pointer to pixel (x, y). */ TQ_UINT8* writablePixel(TQ_INT32 x, TQ_INT32 y); /** * write the specified data to x, y. There is no checking on pixelSize! */ void setPixel(TQ_INT32 x, TQ_INT32 y, const TQ_UINT8 * data); /** * Copy the bytes in the specified rect to a vector. The caller is responsible * for managing the vector. */ void readBytes(TQ_UINT8 * bytes, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h); /** * Copy the bytes in the vector to the specified rect. If there are bytes left * in the vector after filling the rect, they will be ignored. If there are * not enough bytes, the rest of the rect will be filled with the default value * given (by default, 0); */ void writeBytes(const TQ_UINT8 * bytes, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h); /// Get the number of contiguous columns starting at x, valid for all values /// of y between minY and maxY. TQ_INT32 numContiguousColumns(TQ_INT32 x, TQ_INT32 minY, TQ_INT32 maxY); /// Get the number of contiguous rows starting at y, valid for all values /// of x between minX and maxX. TQ_INT32 numContiguousRows(TQ_INT32 y, TQ_INT32 minX, TQ_INT32 maxX); /// Get the row stride at pixel (x, y). This is the number of bytes to add to a /// pointer to pixel (x, y) to access (x, y + 1). TQ_INT32 rowStride(TQ_INT32 x, TQ_INT32 y); // For debugging use TQ_INT32 numTiles() const; private: TQ_UINT32 m_pixelSize; TQ_UINT32 m_numTiles; KisTile *m_defaultTile; KisTile **m_hashTable; KisMementoSP m_currentMemento; TQ_INT32 m_extentMinX; TQ_INT32 m_extentMinY; TQ_INT32 m_extentMaxX; TQ_INT32 m_extentMaxY; TQ_UINT8 *m_defPixel; private: void ensureTileMementoed(TQ_INT32 col, TQ_INT32 row, TQ_UINT32 tileHash, const KisTile *refTile); KisTile *getOldTile(TQ_INT32 col, TQ_INT32 row, KisTile *def); KisTile *getTile(TQ_INT32 col, TQ_INT32 row, bool writeAccess); TQ_UINT32 calcTileHash(TQ_INT32 col, TQ_INT32 row); void updateExtent(TQ_INT32 col, TQ_INT32 row); void recalculateExtent(); void deleteTiles(const KisMemento::DeletedTile *deletedTileList); TQ_INT32 xToCol(TQ_INT32 x) const; TQ_INT32 yToRow(TQ_INT32 y) const; void getContiguousColumnsAndRows(TQ_INT32 x, TQ_INT32 y, TQ_INT32 *columns, TQ_INT32 *rows); TQ_UINT8* pixelPtr(TQ_INT32 x, TQ_INT32 y, bool writable); KisTileDataWrapperSP pixelPtrSafe(TQ_INT32 x, TQ_INT32 y, bool writable); }; inline TQ_UINT32 KisTiledDataManager::pixelSize() { return m_pixelSize; } inline TQ_INT32 KisTiledDataManager::xToCol(TQ_INT32 x) const { if (x >= 0) { return x / KisTile::WIDTH; } else { return -(((-x - 1) / KisTile::WIDTH) + 1); } } inline TQ_INT32 KisTiledDataManager::yToRow(TQ_INT32 y) const { if (y >= 0) { return y / KisTile::HEIGHT; } else { return -(((-y - 1) / KisTile::HEIGHT) + 1); } } // during development the following line helps to check the interface is correct // it should be safe to keep it here even during normal compilation #include "kis_datamanager.h" #endif // KIS_TILEDDATAMANAGER_H_