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.
116 lines
3.9 KiB
116 lines
3.9 KiB
/*
|
|
* copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
|
|
*
|
|
* 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., 675 mass ave, cambridge, ma 02139, usa.
|
|
*/
|
|
#include "kis_tiled_random_accessor.h"
|
|
|
|
|
|
const TQ_UINT32 KisTiledRandomAccessor::CACHESIZE = 4; // Define the number of tiles we keep in cache
|
|
|
|
KisTiledRandomAccessor::KisTiledRandomAccessor(KisTiledDataManager *ktm, TQ_INT32 x, TQ_INT32 y, bool writable) : m_ktm(ktm), m_tilesCache(new KisTileInfo*[4]), m_tilesCacheSize(0), m_pixelSize (m_ktm->pixelSize()), m_writable(writable)
|
|
{
|
|
Q_ASSERT(ktm != 0);
|
|
moveTo(x, y);
|
|
}
|
|
|
|
KisTiledRandomAccessor::~KisTiledRandomAccessor()
|
|
{
|
|
for( uint i = 0; i < m_tilesCacheSize; i++)
|
|
{
|
|
m_tilesCache[i]->tile->removeReader();
|
|
m_tilesCache[i]->oldtile->removeReader();
|
|
delete m_tilesCache[i];
|
|
}
|
|
delete m_tilesCache;
|
|
}
|
|
|
|
void KisTiledRandomAccessor::moveTo(TQ_INT32 x, TQ_INT32 y)
|
|
{
|
|
// Look in the cache if the tile if the data is available
|
|
for( uint i = 0; i < m_tilesCacheSize; i++)
|
|
{
|
|
if( x >= m_tilesCache[i]->area_x1 && x <= m_tilesCache[i]->area_x2 &&
|
|
y >= m_tilesCache[i]->area_y1 && y <= m_tilesCache[i]->area_y2 )
|
|
{
|
|
KisTileInfo* kti = m_tilesCache[i];
|
|
TQ_UINT32 offset = x - kti->area_x1 + (y -kti->area_y1) * KisTile::WIDTH;
|
|
offset *= m_pixelSize;
|
|
m_data = kti->data + offset;
|
|
m_oldData = kti->oldData + offset;
|
|
if(i > 0)
|
|
{
|
|
memmove(m_tilesCache+1,m_tilesCache, i * sizeof(KisTileInfo*));
|
|
m_tilesCache[0] = kti;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
// The tile wasn't in cache
|
|
if(m_tilesCacheSize == KisTiledRandomAccessor::CACHESIZE )
|
|
{ // Remove last element of cache
|
|
m_tilesCache[CACHESIZE-1]->tile->removeReader();
|
|
m_tilesCache[CACHESIZE-1]->oldtile->removeReader();
|
|
delete m_tilesCache[CACHESIZE-1];
|
|
} else {
|
|
m_tilesCacheSize++;
|
|
}
|
|
TQ_UINT32 col = xToCol( x );
|
|
TQ_UINT32 row = yToRow( y );
|
|
KisTileInfo* kti = fetchTileData(col, row);
|
|
TQ_UINT32 offset = x - kti->area_x1 + (y - kti->area_y1) * KisTile::WIDTH;
|
|
offset *= m_pixelSize;
|
|
m_data = kti->data + offset;
|
|
m_oldData = kti->oldData + offset;
|
|
memmove(m_tilesCache+1,m_tilesCache, (KisTiledRandomAccessor::CACHESIZE-1) * sizeof(KisTileInfo*));
|
|
m_tilesCache[0] = kti;
|
|
}
|
|
|
|
|
|
TQ_UINT8 * KisTiledRandomAccessor::rawData() const
|
|
{
|
|
return m_data;
|
|
}
|
|
|
|
|
|
const TQ_UINT8 * KisTiledRandomAccessor::oldRawData() const
|
|
{
|
|
#ifdef DEBUG
|
|
kdWarning(!m_ktm->hasCurrentMemento(), DBG_AREA_TILES) << "Accessing oldRawData() when no transaction is in progress.\n";
|
|
#endif
|
|
return m_oldData;
|
|
}
|
|
|
|
KisTiledRandomAccessor::KisTileInfo* KisTiledRandomAccessor::fetchTileData(TQ_INT32 col, TQ_INT32 row)
|
|
{
|
|
KisTileInfo* kti = new KisTileInfo;
|
|
kti->tile = m_ktm->getTile(col, row, m_writable);
|
|
|
|
kti->tile->addReader();
|
|
|
|
kti->data = kti->tile->data();
|
|
|
|
kti->area_x1 = col * KisTile::HEIGHT;
|
|
kti->area_y1 = row * KisTile::WIDTH;
|
|
kti->area_x2 = kti->area_x1 + KisTile::HEIGHT - 2;
|
|
kti->area_y2 = kti->area_y1 + KisTile::WIDTH - 2;
|
|
|
|
// set old data
|
|
kti->oldtile = m_ktm->getOldTile(col, row, kti->tile);
|
|
kti->oldtile->addReader();
|
|
kti->oldData = kti->oldtile->data();
|
|
return kti;
|
|
}
|