diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-06-26 00:29:37 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-06-26 00:29:37 +0000 |
commit | 2785103a6bd4de55bd26d79e34d0fdd4b329a73a (patch) | |
tree | c2738b1095bfdb263da27bc1391403d829522a14 /krita/core/tiles/kis_tileddatamanager.cc | |
parent | f008adb5a77e094eaf6abf3fc0f36958e66896a5 (diff) | |
download | koffice-2785103a6bd4de55bd26d79e34d0fdd4b329a73a.tar.gz koffice-2785103a6bd4de55bd26d79e34d0fdd4b329a73a.zip |
Remove krita* in preparation for name switch from Krita to Chalk
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1238361 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krita/core/tiles/kis_tileddatamanager.cc')
-rw-r--r-- | krita/core/tiles/kis_tileddatamanager.cc | 1044 |
1 files changed, 0 insertions, 1044 deletions
diff --git a/krita/core/tiles/kis_tileddatamanager.cc b/krita/core/tiles/kis_tileddatamanager.cc deleted file mode 100644 index 629b1b38..00000000 --- a/krita/core/tiles/kis_tileddatamanager.cc +++ /dev/null @@ -1,1044 +0,0 @@ -/* - * Copyright (c) 2004 Casper Boemann <[email protected]> - * - * 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. - */ - -#include <tqvaluevector.h> - -#include <kdebug.h> - -#include <KoStore.h> - -#include "kis_global.h" -#include "kis_debug_areas.h" -#include "kis_tileddatamanager.h" -#include "kis_tilediterator.h" -#include "kis_tile.h" -#include "kis_memento.h" -#include "kis_tilemanager.h" - -/* The data area is divided into tiles each say 64x64 pixels (defined at compiletime) - * The tiles are laid out in a matrix that can have negative indexes. - * The matrix grows automatically if needed (a call for writeacces to a tile outside the current extent) - * Even though the matrix has grown it may still not contain tiles at specific positions. They are created on demand - */ - -KisTiledDataManager::KisTiledDataManager(TQ_UINT32 pixelSize, const TQ_UINT8 *defPixel) -{ - m_pixelSize = pixelSize; - - m_defPixel = new TQ_UINT8[m_pixelSize]; - Q_CHECK_PTR(m_defPixel); - memcpy(m_defPixel, defPixel, m_pixelSize); - - m_defaultTile = new KisTile(pixelSize,0,0, m_defPixel); - Q_CHECK_PTR(m_defaultTile); - - m_hashTable = new KisTile * [1024]; - Q_CHECK_PTR(m_hashTable); - - for(int i = 0; i < 1024; i++) - m_hashTable [i] = 0; - m_numTiles = 0; - m_currentMemento = 0; - m_extentMinX = TQ_INT32_MAX; - m_extentMinY = TQ_INT32_MAX; - m_extentMaxX = TQ_INT32_MIN; - m_extentMaxY = TQ_INT32_MIN; -} - -KisTiledDataManager::KisTiledDataManager(const KisTiledDataManager & dm) - : KShared() -{ - m_pixelSize = dm.m_pixelSize; - - m_defPixel = new TQ_UINT8[m_pixelSize]; - Q_CHECK_PTR(m_defPixel); - memcpy(m_defPixel, dm.m_defPixel, m_pixelSize); - - m_defaultTile = new KisTile(*dm.m_defaultTile, dm.m_defaultTile->getCol(), dm.m_defaultTile->getRow()); - Q_CHECK_PTR(m_defaultTile); - - m_hashTable = new KisTile * [1024]; - Q_CHECK_PTR(m_hashTable); - - m_numTiles = 0; - m_currentMemento = 0; - m_extentMinX = dm.m_extentMinX; - m_extentMinY = dm.m_extentMinY; - m_extentMaxX = dm.m_extentMaxX; - m_extentMaxY = dm.m_extentMaxY; - - // Deep copy every tile. XXX: Make this copy-on-write! - for(int i = 0; i < 1024; i++) - { - const KisTile *tile = dm.m_hashTable[i]; - - m_hashTable[i] = 0; - - while(tile) - { - KisTile *newtile = new KisTile(*tile, tile->getCol(), tile->getRow()); - Q_CHECK_PTR(newtile); - - newtile->setNext(m_hashTable[i]); - m_hashTable[i] = newtile; - tile = tile->getNext(); - - m_numTiles++; - } - } - -} - -KisTiledDataManager::~KisTiledDataManager() -{ - // Deep delete every tile - for(int i = 0; i < 1024; i++) - { - const KisTile *tile = m_hashTable[i]; - - while(tile) - { - const KisTile *deltile = tile; - tile = tile->getNext(); - delete deltile; - } - } - delete [] m_hashTable; - delete m_defaultTile; - delete [] m_defPixel; -} - -void KisTiledDataManager::setDefaultPixel(const TQ_UINT8 *defPixel) -{ - if (defPixel == 0) return; - - memcpy(m_defPixel, defPixel, m_pixelSize); - - m_defaultTile->setData(m_defPixel); -} - -bool KisTiledDataManager::write(KoStore *store) -{ - - if (store == 0) return false; - //Q_ASSERT(store != 0); - - char str[80]; - - sprintf(str, "%d\n", m_numTiles); - store->write(str,strlen(str)); - - for(int i = 0; i < 1024; i++) - { - const KisTile *tile = m_hashTable[i]; - - while(tile) - { - sprintf(str, "%d,%d,%d,%d\n", tile->getCol() * KisTile::WIDTH, - tile->getRow() * KisTile::HEIGHT, - KisTile::WIDTH, KisTile::HEIGHT); - store->write(str,strlen(str)); - - tile->addReader(); - store->write((char *)tile->m_data, KisTile::HEIGHT * KisTile::WIDTH * m_pixelSize); - tile->removeReader(); - - tile = tile->getNext(); - } - } - - return true; -} -bool KisTiledDataManager::read(KoStore *store) -{ - if (store == 0) return false; - //Q_ASSERT(store != 0); - - char str[80]; - TQ_INT32 x,y,w,h; - - TQIODevice *stream = store->device(); - if (stream == 0) return false; - //Q_ASSERT(stream != 0); - - stream->readLine(str, 79); - - sscanf(str,"%u",&m_numTiles); - - for(TQ_UINT32 i = 0; i < m_numTiles; i++) - { - stream->readLine(str, 79); - sscanf(str,"%d,%d,%d,%d",&x,&y,&w,&h); - - // the following is only correct as long as tile size is not changed - // The first time we change tilesize the dimensions just read needs to be respected - // but for now we just assume that tiles are the same size as ever. - TQ_INT32 row = yToRow(y); - TQ_INT32 col = xToCol(x); - TQ_UINT32 tileHash = calcTileHash(col, row); - - KisTile *tile = new KisTile(m_pixelSize, col, row, m_defPixel); - Q_CHECK_PTR(tile); - - updateExtent(col,row); - - tile->addReader(); - store->read((char *)tile->m_data, KisTile::HEIGHT * KisTile::WIDTH * m_pixelSize); - tile->removeReader(); - - tile->setNext(m_hashTable[tileHash]); - m_hashTable[tileHash] = tile; - } - return true; -} - -void KisTiledDataManager::extent(TQ_INT32 &x, TQ_INT32 &y, TQ_INT32 &w, TQ_INT32 &h) const -{ - x = m_extentMinX; - y = m_extentMinY; - - if (m_extentMaxX >= m_extentMinX) { - w = m_extentMaxX - m_extentMinX + 1; - } else { - w = 0; - } - - if (m_extentMaxY >= m_extentMinY) { - h = m_extentMaxY - m_extentMinY + 1; - } else { - h = 0; - } -} - -TQRect KisTiledDataManager::extent() const -{ - TQ_INT32 x; - TQ_INT32 y; - TQ_INT32 w; - TQ_INT32 h; - - extent(x, y, w, h); - - return TQRect(x, y, w, h); -} - -void KisTiledDataManager::setExtent(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) -{ - TQRect newRect = TQRect(x, y, w, h).normalize(); - //printRect("newRect", newRect); - TQRect oldRect = TQRect(m_extentMinX, m_extentMinY, m_extentMaxX - m_extentMinX + 1, m_extentMaxY - m_extentMinY + 1).normalize(); - //printRect("oldRect", oldRect); - - // Do nothing if the desired size is bigger than we currently are: that is handled by the autoextending automatically - if (newRect.tqcontains(oldRect)) return; - - // Loop through all tiles, if a tile is wholly outside the extent, add to the memento, then delete it, - // if the tile is partially outside the extent, clear the outside pixels to the default pixel. - for(int tileHash = 0; tileHash < 1024; tileHash++) - { - KisTile *tile = m_hashTable[tileHash]; - KisTile *previousTile = 0; - - while(tile) - { - TQRect tileRect = TQRect(tile->getCol() * KisTile::WIDTH, tile->getRow() * KisTile::HEIGHT, KisTile::WIDTH, KisTile::HEIGHT); - //printRect("tileRect", tileRect); - - if (newRect.tqcontains(tileRect)) { - // Completely inside, do nothing - previousTile = tile; - tile = tile->getNext(); - } - else { - ensureTileMementoed(tile->getCol(), tile->getRow(), tileHash, tile); - - if (newRect.intersects(tileRect)) { - - // Create the intersection of the tile and new rect - TQRect intersection = newRect.intersect(tileRect); - //printRect("intersection", intersection); - intersection.setRect(intersection.x() - tileRect.x(), intersection.y() - tileRect.y(), intersection.width(), intersection.height()); - - // This can be done a lot more efficiently, no doubt, by clearing runs of pixels to the left and the right of - // the intersecting line. - tile->addReader(); - for (int y = 0; y < KisTile::HEIGHT; ++y) { - for (int x = 0; x < KisTile::WIDTH; ++x) { - if (!intersection.tqcontains(x,y)) { - TQ_UINT8 * ptr = tile->data(x, y); - memcpy(ptr, m_defPixel, m_pixelSize); - } - } - } - tile->removeReader(); - previousTile = tile; - tile = tile->getNext(); - } - else { - KisTile *deltile = tile; - tile = tile->getNext(); - - m_numTiles--; - - if (previousTile) - previousTile->setNext(tile); - else - m_hashTable[tileHash] = tile; - delete deltile; - } - } - } - } - - // Set the extent correctly - m_extentMinX = x; - m_extentMinY = y; - m_extentMaxX = x + w - 1; - m_extentMaxY = y + h - 1; -} - -void KisTiledDataManager::recalculateExtent() -{ - m_extentMinX = TQ_INT32_MAX; - m_extentMinY = TQ_INT32_MAX; - m_extentMaxX = TQ_INT32_MIN; - m_extentMaxY = TQ_INT32_MIN; - - // Loop through all tiles. - for (int tileHash = 0; tileHash < 1024; tileHash++) - { - const KisTile *tile = m_hashTable[tileHash]; - - while (tile) - { - updateExtent(tile->getCol(), tile->getRow()); - tile = tile->getNext(); - } - } -} - -void KisTiledDataManager::clear(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h, TQ_UINT8 clearValue) -{ - if (w < 1 || h < 1) { - return; - } - - TQ_INT32 firstColumn = xToCol(x); - TQ_INT32 lastColumn = xToCol(x + w - 1); - - TQ_INT32 firstRow = yToRow(y); - TQ_INT32 lastRow = yToRow(y + h - 1); - - TQRect clearRect(x, y, w, h); - - const TQ_UINT32 rowStride = KisTile::WIDTH * m_pixelSize; - - for (TQ_INT32 row = firstRow; row <= lastRow; ++row) { - for (TQ_INT32 column = firstColumn; column <= lastColumn; ++column) { - - KisTile *tile = getTile(column, row, true); - TQRect tileRect = tile->extent(); - - TQRect clearTileRect = clearRect & tileRect; - - tile->addReader(); - if (clearTileRect == tileRect) { - // Clear whole tile - memset(tile->data(), clearValue, KisTile::WIDTH * KisTile::HEIGHT * m_pixelSize); - } else { - - TQ_UINT32 rowsRemaining = clearTileRect.height(); - TQ_UINT8 *dst = tile->data(clearTileRect.x() - tileRect.x(), clearTileRect.y() - tileRect.y()); - - while (rowsRemaining > 0) { - memset(dst, clearValue, clearTileRect.width() * m_pixelSize); - dst += rowStride; - --rowsRemaining; - } - } - tile->removeReader(); - } - } -} - -void KisTiledDataManager::clear(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h, const TQ_UINT8 *clearPixel) -{ - Q_ASSERT(clearPixel != 0); - - if (clearPixel == 0 || w < 1 || h < 1) { - return; - } - - bool pixelBytesAreTheSame = true; - - for (TQ_UINT32 i = 0; i < m_pixelSize; ++i) { - if (clearPixel[i] != clearPixel[0]) { - pixelBytesAreTheSame = false; - break; - } - } - - if (pixelBytesAreTheSame) { - clear(x, y, w, h, clearPixel[0]); - } else { - - TQ_INT32 firstColumn = xToCol(x); - TQ_INT32 lastColumn = xToCol(x + w - 1); - - TQ_INT32 firstRow = yToRow(y); - TQ_INT32 lastRow = yToRow(y + h - 1); - - TQRect clearRect(x, y, w, h); - - const TQ_UINT32 rowStride = KisTile::WIDTH * m_pixelSize; - - TQ_UINT8 *clearPixelData = 0; - - if (w >= KisTile::WIDTH && h >= KisTile::HEIGHT) { - - // There might be a whole tile to be cleared so generate a cleared tile. - clearPixelData = new TQ_UINT8[KisTile::WIDTH * KisTile::HEIGHT * m_pixelSize]; - - TQ_UINT8 *dst = clearPixelData; - TQ_UINT32 pixelsRemaining = KisTile::WIDTH; - - // Generate one row - while (pixelsRemaining > 0) { - memcpy(dst, clearPixel, m_pixelSize); - dst += m_pixelSize; - --pixelsRemaining; - } - - TQ_UINT32 rowsRemaining = KisTile::HEIGHT - 1; - - // Copy to the rest of the rows. - while (rowsRemaining > 0) { - memcpy(dst, clearPixelData, rowStride); - dst += rowStride; - --rowsRemaining; - } - - } else { - - // Generate one row - TQ_UINT32 maxRunLength = TQMIN(w, KisTile::WIDTH); - - clearPixelData = new TQ_UINT8[maxRunLength * m_pixelSize]; - - TQ_UINT8 *dst = clearPixelData; - TQ_UINT32 pixelsRemaining = maxRunLength; - - while (pixelsRemaining > 0) { - memcpy(dst, clearPixel, m_pixelSize); - dst += m_pixelSize; - --pixelsRemaining; - } - } - - for (TQ_INT32 row = firstRow; row <= lastRow; ++row) { - for (TQ_INT32 column = firstColumn; column <= lastColumn; ++column) { - - KisTile *tile = getTile(column, row, true); - TQRect tileRect = tile->extent(); - - TQRect clearTileRect = clearRect & tileRect; - - if (clearTileRect == tileRect) { - - // Clear whole tile - tile->addReader(); - memcpy(tile->data(), clearPixelData, KisTile::WIDTH * KisTile::HEIGHT * m_pixelSize); - tile->removeReader(); - } else { - - TQ_UINT32 rowsRemaining = clearTileRect.height(); - tile->addReader(); - TQ_UINT8 *dst = tile->data(clearTileRect.x() - tileRect.x(), clearTileRect.y() - tileRect.y()); - - while (rowsRemaining > 0) { - memcpy(dst, clearPixelData, clearTileRect.width() * m_pixelSize); - dst += rowStride; - --rowsRemaining; - } - tile->removeReader(); - } - } - } - - delete [] clearPixelData; - } -} - -void KisTiledDataManager::clear() -{ - // Loop through all tiles, add to the memento, then delete it, - for(int tileHash = 0; tileHash < 1024; tileHash++) - { - const KisTile *tile = m_hashTable[tileHash]; - - while(tile) - { - ensureTileMementoed(tile->getCol(), tile->getRow(), tileHash, tile); - - const KisTile *deltile = tile; - tile = tile->getNext(); - - delete deltile; - } - m_hashTable[tileHash] = 0; - } - - m_numTiles = 0; - - // Set the extent correctly - m_extentMinX = TQ_INT32_MAX; - m_extentMinY = TQ_INT32_MAX; - m_extentMaxX = TQ_INT32_MIN; - m_extentMaxY = TQ_INT32_MIN; -} - -void KisTiledDataManager::paste(KisDataManagerSP data, TQ_INT32 sx, TQ_INT32 sy, TQ_INT32 dx, TQ_INT32 dy, - TQ_INT32 w, TQ_INT32 h) -{ - //CBR_MISSING - sx=sy=dx=dy=w=h;data=0; -} - - -TQ_UINT32 KisTiledDataManager::calcTileHash(TQ_INT32 col, TQ_INT32 row) -{ - return ((row << 5) + (col & 0x1F)) & 0x3FF; -} - -KisMementoSP KisTiledDataManager::getMemento() -{ - m_currentMemento = new KisMemento(m_pixelSize); - Q_CHECK_PTR(m_currentMemento); - - memcpy(m_currentMemento->m_defPixel, m_defPixel, m_pixelSize); - - return m_currentMemento; -} - -void KisTiledDataManager::rollback(KisMementoSP memento) -{ - if (memento == 0) return; - //Q_ASSERT(memento != 0); - - if (m_currentMemento != 0) { - // Undo means our current memento is no longer valid so remove it. - m_currentMemento = 0; - } - - // Rollback means restoring all of the tiles in the memento to our hashtable. - - // But first clear the memento redo hashtable. - // This is nessesary as new changes might have been done since last rollback (automatic filters) - for(int i = 0; i < 1024; i++) - { - memento->deleteAll(memento->m_redoHashTable[i]); - memento->m_redoHashTable[i]=0; - } - - // Also clear the table of deleted tiles - memento->clearTilesToDeleteOnRedo(); - - // Now on to the real rollback - - memcpy(memento->m_redoDefPixel, m_defPixel, m_pixelSize); - setDefaultPixel(memento->m_defPixel); - - for(int i = 0; i < 1024; i++) - { - KisTile *tile = memento->m_hashTable[i]; - - while(tile) - { - // The memento has a tile stored that we need to roll back - // Now find the corresponding one in our hashtable - KisTile *curTile = m_hashTable[i]; - KisTile *preTile = 0; - while(curTile) - { - if(curTile->getRow() == tile->getRow() && curTile->getCol() == tile->getCol()) - { - break; - } - preTile = curTile; - curTile = curTile->getNext(); - } - - if(curTile) - { - // Remove it from our hashtable - if(preTile) - preTile->setNext(curTile->getNext()); - else - m_hashTable[i]= curTile->getNext(); - - m_numTiles--; - - // And put it in the redo hashtable of the memento - curTile->setNext(memento->m_redoHashTable[i]); - memento->m_redoHashTable[i] = curTile; - } - else - { - memento->addTileToDeleteOnRedo(tile->getCol(), tile->getRow()); - // As we are pratically adding a new tile we need to update the extent - updateExtent(tile->getCol(), tile->getRow()); - } - - // Put a copy of the memento tile into our hashtable - curTile = new KisTile(*tile); - Q_CHECK_PTR(curTile); - m_numTiles++; - - curTile->setNext(m_hashTable[i]); - m_hashTable[i] = curTile; - - tile = tile->getNext(); - } - } - - if (memento->tileListToDeleteOnUndo() != 0) { - // XXX: We currently add these tiles above, only to delete them again here. - deleteTiles(memento->tileListToDeleteOnUndo()); - } -} - -void KisTiledDataManager::rollforward(KisMementoSP memento) -{ - if (memento == 0) return; - //Q_ASSERT(memento != 0); - - if (m_currentMemento != 0) { - // Redo means our current memento is no longer valid so remove it. - m_currentMemento = 0; - } - - // Rollforward means restoring all of the tiles in the memento's redo to our hashtable. - - setDefaultPixel(memento->m_redoDefPixel); - - for(int i = 0; i < 1024; i++) - { - KisTile *tile = memento->m_redoHashTable[i]; - - while(tile) - { - // The memento has a tile stored that we need to roll forward - // Now find the corresponding one in our hashtable - KisTile *curTile = m_hashTable[i]; - KisTile *preTile = 0; - while(curTile) - { - if(curTile->getRow() == tile->getRow() && curTile->getCol() == tile->getCol()) - { - break; - } - preTile = curTile; - curTile = curTile->getNext(); - } - - if (curTile) - { - // Remove it from our hashtable - if(preTile) - preTile->setNext(curTile->getNext()); - else - m_hashTable[i]= curTile->getNext(); - - // And delete it (it's equal to the one stored in the memento's undo) - m_numTiles--; - delete curTile; - } - - // Put a copy of the memento tile into our hashtable - curTile = new KisTile(*tile); - Q_CHECK_PTR(curTile); - - curTile->setNext(m_hashTable[i]); - m_hashTable[i] = curTile; - m_numTiles++; - updateExtent(curTile->getCol(), curTile->getRow()); - - tile = tile->getNext(); - } - } - - // Roll forward also means re-deleting the tiles that was deleted but restored by the undo - if (memento->tileListToDeleteOnRedo() != 0) { - deleteTiles(memento->tileListToDeleteOnRedo()); - } -} - -void KisTiledDataManager::deleteTiles(const KisMemento::DeletedTile *d) -{ - while (d) - { - TQ_UINT32 tileHash = calcTileHash(d->col(), d->row()); - KisTile *curTile = m_hashTable[tileHash]; - KisTile *preTile = 0; - while(curTile) - { - if(curTile->getRow() == d->row() && curTile->getCol() == d->col()) - { - break; - } - preTile = curTile; - curTile = curTile->getNext(); - } - if (curTile) { - // Remove it from our hashtable - if(preTile) - preTile->setNext(curTile->getNext()); - else - m_hashTable[tileHash] = curTile->getNext(); - - // And delete it (it's equal to the one stored in the memento's undo) - m_numTiles--; - delete curTile; - } - d = d->next(); - } - - recalculateExtent(); -} - -void KisTiledDataManager::ensureTileMementoed(TQ_INT32 col, TQ_INT32 row, TQ_UINT32 tileHash, const KisTile *refTile) -{ - if (refTile == 0) return; - //Q_ASSERT(refTile != 0); - - // Basically we search for the tile in the current memento, and if it's already there we do nothing, otherwise - // we make a copy of the tile and put it in the current memento - - if(!m_currentMemento) - return; - - KisTile *tile = m_currentMemento->m_hashTable[tileHash]; - while(tile != 0) - { - if(tile->getRow() == row && tile->getCol() == col) - break; - - tile = tile->getNext(); - } - if(tile) - return; // it has allready been stored - - tile = new KisTile(*refTile); - Q_CHECK_PTR(tile); - - tile->setNext(m_currentMemento->m_hashTable[tileHash]); - m_currentMemento->m_hashTable[tileHash] = tile; - m_currentMemento->m_numTiles++; -} - -void KisTiledDataManager::updateExtent(TQ_INT32 col, TQ_INT32 row) -{ - if(m_extentMinX > col * KisTile::WIDTH) - m_extentMinX = col * KisTile::WIDTH; - if(m_extentMaxX < (col+1) * KisTile::WIDTH - 1) - m_extentMaxX = (col+1) * KisTile::WIDTH - 1; - if(m_extentMinY > row * KisTile::HEIGHT) - m_extentMinY = row * KisTile::HEIGHT; - if(m_extentMaxY < (row+1) * KisTile::HEIGHT - 1) - m_extentMaxY = (row+1) * KisTile::HEIGHT - 1; -} - -KisTile *KisTiledDataManager::getTile(TQ_INT32 col, TQ_INT32 row, bool writeAccess) -{ - TQ_UINT32 tileHash = calcTileHash(col, row); - - // Lookup tile in hash table - KisTile *tile = m_hashTable[tileHash]; - while(tile != 0) - { - if(tile->getRow() == row && tile->getCol() == col) - break; - - tile = tile->getNext(); - } - - // Might not have been created yet - if(!tile) - { - if(writeAccess) - { - // Create a new tile - tile = new KisTile(*m_defaultTile, col, row); - Q_CHECK_PTR(tile); - - tile->setNext(m_hashTable[tileHash]); - m_hashTable[tileHash] = tile; - m_numTiles++; - updateExtent(col, row); - - if (m_currentMemento && !m_currentMemento->containsTile(col, row, tileHash)) { - m_currentMemento->addTileToDeleteOnUndo(col, row); - } - } - else - // If only read access then it's enough to share a default tile - tile = m_defaultTile; - } - - if(writeAccess) - ensureTileMementoed(col, row, tileHash, tile); - - return tile; -} - -KisTile *KisTiledDataManager::getOldTile(TQ_INT32 col, TQ_INT32 row, KisTile *def) -{ - KisTile *tile = 0; - - // Lookup tile in hash table of current memento - if (m_currentMemento) - { - if (!m_currentMemento->valid()) return def; - //Q_ASSERT(m_currentMemento->valid()); - - TQ_UINT32 tileHash = calcTileHash(col, row); - tile = m_currentMemento->m_hashTable[tileHash]; - while (tile != 0) - { - if (tile->getRow() == row && tile->getCol() == col) - break; - - tile = tile->getNext(); - } - } - - if (!tile) - tile = def; - - return tile; -} - -TQ_UINT8* KisTiledDataManager::pixelPtr(TQ_INT32 x, TQ_INT32 y, bool writable) -{ - // Ahem, this is a bit not as good. The point is, this function needs the tile data, - // but it might be swapped out. This code swaps it in, but at function exit it might - // be swapped out again! THIS MAKES THE RETURNED POINTER TQUITE VOLATILE - return pixelPtrSafe(x, y, writable) -> data(); -} - -KisTileDataWrapperSP KisTiledDataManager::pixelPtrSafe(TQ_INT32 x, TQ_INT32 y, bool writable) { - TQ_INT32 row = yToRow(y); - TQ_INT32 col = xToCol(x); - - // calc limits within the tile - TQ_INT32 yInTile = y - row * KisTile::HEIGHT; - TQ_INT32 xInTile = x - col * KisTile::WIDTH; - TQ_INT32 offset = m_pixelSize * (yInTile * KisTile::WIDTH + xInTile); - - KisTile *tile = getTile(col, row, writable); - - return new KisTileDataWrapper(tile, offset); -} - -const TQ_UINT8* KisTiledDataManager::pixel(TQ_INT32 x, TQ_INT32 y) -{ - return pixelPtr(x, y, false); -} - -TQ_UINT8* KisTiledDataManager::writablePixel(TQ_INT32 x, TQ_INT32 y) -{ - return pixelPtr(x, y, true); -} - -void KisTiledDataManager::setPixel(TQ_INT32 x, TQ_INT32 y, const TQ_UINT8 * data) -{ - TQ_UINT8 *pixel = pixelPtr(x, y, true); - memcpy(pixel, data, m_pixelSize); -} - - -void KisTiledDataManager::readBytes(TQ_UINT8 * data, - TQ_INT32 x, TQ_INT32 y, - TQ_INT32 w, TQ_INT32 h) -{ - if (data == 0) return; - //Q_ASSERT(data != 0); - if (w < 0) - w = 0; - - if (h < 0) - h = 0; - - TQ_INT32 dstY = 0; - TQ_INT32 srcY = y; - TQ_INT32 rowsRemaining = h; - - while (rowsRemaining > 0) { - - TQ_INT32 dstX = 0; - TQ_INT32 srcX = x; - TQ_INT32 columnsRemaining = w; - TQ_INT32 numContiguousSrcRows = numContiguousRows(srcY, srcX, srcX + w - 1); - - TQ_INT32 rows = TQMIN(numContiguousSrcRows, rowsRemaining); - - while (columnsRemaining > 0) { - - TQ_INT32 numContiguousSrcColumns = numContiguousColumns(srcX, srcY, srcY + rows - 1); - - TQ_INT32 columns = TQMIN(numContiguousSrcColumns, columnsRemaining); - - KisTileDataWrapperSP tileData = pixelPtrSafe(srcX, srcY, false); - const TQ_UINT8 *srcData = tileData -> data(); - TQ_INT32 srcRowStride = rowStride(srcX, srcY); - - TQ_UINT8 *dstData = data + ((dstX + (dstY * w)) * m_pixelSize); - TQ_INT32 dstRowStride = w * m_pixelSize; - - for (TQ_INT32 row = 0; row < rows; row++) { - memcpy(dstData, srcData, columns * m_pixelSize); - dstData += dstRowStride; - srcData += srcRowStride; - } - - srcX += columns; - dstX += columns; - columnsRemaining -= columns; - } - - srcY += rows; - dstY += rows; - rowsRemaining -= rows; - } - -} - - -void KisTiledDataManager::writeBytes(const TQ_UINT8 * bytes, - TQ_INT32 x, TQ_INT32 y, - TQ_INT32 w, TQ_INT32 h) -{ - if (bytes == 0) return; - //Q_ASSERT(bytes != 0); - - // XXX: Is this correct? - if (w < 0) - w = 0; - - if (h < 0) - h = 0; - - TQ_INT32 srcY = 0; - TQ_INT32 dstY = y; - TQ_INT32 rowsRemaining = h; - - while (rowsRemaining > 0) { - - TQ_INT32 srcX = 0; - TQ_INT32 dstX = x; - TQ_INT32 columnsRemaining = w; - TQ_INT32 numContiguousdstRows = numContiguousRows(dstY, dstX, dstX + w - 1); - - TQ_INT32 rows = TQMIN(numContiguousdstRows, rowsRemaining); - - while (columnsRemaining > 0) { - - TQ_INT32 numContiguousdstColumns = numContiguousColumns(dstX, dstY, dstY + rows - 1); - - TQ_INT32 columns = TQMIN(numContiguousdstColumns, columnsRemaining); - - //TQ_UINT8 *dstData = writablePixel(dstX, dstY); - KisTileDataWrapperSP tileData = pixelPtrSafe(dstX, dstY, true); - TQ_UINT8 *dstData = tileData->data(); - TQ_INT32 dstRowStride = rowStride(dstX, dstY); - - const TQ_UINT8 *srcData = bytes + ((srcX + (srcY * w)) * m_pixelSize); - TQ_INT32 srcRowStride = w * m_pixelSize; - - for (TQ_INT32 row = 0; row < rows; row++) { - memcpy(dstData, srcData, columns * m_pixelSize); - srcData += srcRowStride; - dstData += dstRowStride; - } - - dstX += columns; - srcX += columns; - columnsRemaining -= columns; - } - - dstY += rows; - srcY += rows; - rowsRemaining -= rows; - } -} - -TQ_INT32 KisTiledDataManager::numContiguousColumns(TQ_INT32 x, TQ_INT32 minY, TQ_INT32 maxY) -{ - TQ_INT32 numColumns; - - Q_UNUSED(minY); - Q_UNUSED(maxY); - - if (x >= 0) { - numColumns = KisTile::WIDTH - (x % KisTile::WIDTH); - } else { - numColumns = ((-x - 1) % KisTile::WIDTH) + 1; - } - - return numColumns; -} - -TQ_INT32 KisTiledDataManager::numContiguousRows(TQ_INT32 y, TQ_INT32 minX, TQ_INT32 maxX) -{ - TQ_INT32 numRows; - - Q_UNUSED(minX); - Q_UNUSED(maxX); - - if (y >= 0) { - numRows = KisTile::HEIGHT - (y % KisTile::HEIGHT); - } else { - numRows = ((-y - 1) % KisTile::HEIGHT) + 1; - } - - return numRows; -} - -TQ_INT32 KisTiledDataManager::rowStride(TQ_INT32 x, TQ_INT32 y) -{ - Q_UNUSED(x); - Q_UNUSED(y); - - return KisTile::WIDTH * m_pixelSize; -} - -TQ_INT32 KisTiledDataManager::numTiles(void) const -{ - return m_numTiles; -} - -KisTileDataWrapper::KisTileDataWrapper(KisTile* tile, TQ_INT32 offset) - : m_tile(tile), m_offset(offset) -{ - m_tile->addReader(); -} - -KisTileDataWrapper::~KisTileDataWrapper() -{ - m_tile->removeReader(); -} |