You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
7.1 KiB
234 lines
7.1 KiB
/*
|
|
* Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
|
|
*
|
|
* 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 <tqglobal.h>
|
|
#include <tqvaluevector.h>
|
|
|
|
#include <ksharedptr.h>
|
|
|
|
#include "kis_tile_global.h"
|
|
#include "kis_tile.h"
|
|
#include "kis_memento.h"
|
|
|
|
class KisTiledDataManager;
|
|
typedef KSharedPtr<KisTiledDataManager> KisTiledDataManagerSP;
|
|
|
|
class KisDataManager;
|
|
typedef KSharedPtr<KisDataManager> KisDataManagerSP;
|
|
|
|
class KisTiledIterator;
|
|
class KisTiledRandomAccessor;
|
|
class KoStore;
|
|
|
|
class KisTileDataWrapper : public KShared {
|
|
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 KSharedPtr<KisTileDataWrapper> 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 KShared {
|
|
|
|
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_
|
|
|