Cropping paint devices

Boudewijn Rempt boud at valdyas.org
Sat Mar 26 14:07:56 CET 2005


With the current system, paint devices can only grow, never shrink. When 
scaling down, resizing or cropping that's a big problem -- made nicely 
visible through the resize image to layer command. I've tried to add a 
setExtent method to the data manager, but I must be doing something quite 
wrong because it leads to never ending crashes. Here's the snippet, maybe 
someone else (Casper?) can help me out:



void KisTiledDataManager::setExtent(Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
{
	QRect newRect = QRect(x, y, w, h).normalize();
	QRect oldRect = QRect(m_extentMinX, m_extentMinY, m_extentMaxX - m_extentMinX + 1, m_extentMaxY - m_extentMinY + 1).normalize();

	// Do nothing if the desired size is bigger than we currently are: that is handled by the autoextending automatically
	if (newRect.contains(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 black transparent (XXX: use the
	// default pixel for this when avaiable).
	for(int i = 0; i < 1024; i++)
	{
		KisTile *tile = m_hashTable[i];

		while(tile)
		{
			QRect tileRect = QRect(tile -> getCol(), tile -> getRow(), KisTile::WIDTH, KisTile::HEIGHT);

			
			if (newRect.contains(tileRect)) {
				// Completely inside, do nothing
				tile->getNext();
			}
			else {
				Q_UINT32 tileHash = calcTileHash(tileRect.x(), tileRect.y());
				ensureTileMementoed(tileRect.x(), tileRect.y(), tileHash, tile);
			
				if (newRect.intersects(tileRect)) {
					// Partially inside, clear the non-intersecting bits

					// Create the intersection of the tile and new rect
					QRect intersection = newRect.intersect(tileRect);
					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.
					for (int y = 0; y < KisTile::HEIGHT; ++y) {
						for (int x = 0; x < KisTile::WIDTH; ++x) {
							if (!intersection.contains(x,y)) {
								Q_UINT8 * ptr = tile -> data(x, y);
								memset(ptr, 0, m_pixelSize);
							}
						}
					}
					
					tile->getNext();
				}
				else {
					// Completely outside, delete this tile. It had already been mementoed
					KisTile *deltile = tile;
					tile = tile->getNext();
					delete deltile;
				}
			}
			

		}
	}
	
	// Set the extent correctly
	m_extentMinX = x;
	m_extentMinY = y;
	m_extentMaxX = x + w + 1;
	m_extentMaxY = y + h + 1;
}

-- 
Boudewijn Rempt 
http://www.valdyas.org/fading/index.cgi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/kimageshop/attachments/20050326/e41c2f14/attachment.pgp


More information about the kimageshop mailing list