diff options
Diffstat (limited to 'krita/core/kis_paint_device.cc')
-rw-r--r-- | krita/core/kis_paint_device.cc | 1285 |
1 files changed, 0 insertions, 1285 deletions
diff --git a/krita/core/kis_paint_device.cc b/krita/core/kis_paint_device.cc deleted file mode 100644 index a6942626..00000000 --- a/krita/core/kis_paint_device.cc +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien <[email protected]> - * Copyright (c) 2004 Boudewijn Rempt <[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 <tqrect.h> -#include <tqwmatrix.h> -#include <tqimage.h> -#include <tqdatetime.h> -#include <tqapplication.h> -#include <tqvaluelist.h> -#include <tqtimer.h> - -#include <kcommand.h> -#include <klocale.h> -#include <kdebug.h> - -#include <KoStore.h> - -#include "kis_global.h" -#include "kis_types.h" -#include "kis_painter.h" -#include "kis_fill_painter.h" -#include "kis_undo_adapter.h" -#include "kis_iterator.h" -#include "kis_iterators_pixel.h" -#include "kis_iteratorpixeltrait.h" -#include "kis_random_accessor.h" -#include "kis_random_sub_accessor.h" -#include "kis_transaction.h" -#include "kis_profile.h" -#include "kis_color.h" -#include "kis_integer_maths.h" -#include "kis_colorspace_factory_registry.h" -#include "kis_selection.h" -#include "kis_layer.h" -#include "kis_paint_device_iface.h" -#include "kis_paint_device.h" -#include "kis_datamanager.h" -#include "kis_memento.h" -#include "kis_selection.h" - -#include "kis_exif_info.h" - -namespace { - - class KisPaintDeviceCommand : public KNamedCommand { - typedef KNamedCommand super; - - public: - KisPaintDeviceCommand(const TQString& name, KisPaintDeviceSP paintDevice); - virtual ~KisPaintDeviceCommand() {} - - virtual void execute() = 0; - virtual void unexecute() = 0; - - protected: - void setUndo(bool undo); - - KisPaintDeviceSP m_paintDevice; - }; - - KisPaintDeviceCommand::KisPaintDeviceCommand(const TQString& name, KisPaintDeviceSP paintDevice) : - super(name), m_paintDevice(paintDevice) - { - } - - void KisPaintDeviceCommand::setUndo(bool undo) - { - if (m_paintDevice->undoAdapter()) { - m_paintDevice->undoAdapter()->setUndo(undo); - } - } - - class MoveCommand : public KNamedCommand { - typedef KNamedCommand super; - - public: - MoveCommand(KisPaintDeviceSP device, const TQPoint& oldpos, const TQPoint& newpos); - virtual ~MoveCommand(); - - virtual void execute(); - virtual void unexecute(); - - private: - void moveTo(const TQPoint& pos); - void undoOff(); - void undoOn(); - - private: - KisPaintDeviceSP m_device; - TQPoint m_oldPos; - TQPoint m_newPos; - }; - - MoveCommand::MoveCommand(KisPaintDeviceSP device, const TQPoint& oldpos, const TQPoint& newpos) : - super(i18n("Move Layer")) - { - m_device = device; - m_oldPos = oldpos; - m_newPos = newpos; - } - - MoveCommand::~MoveCommand() - { - } - - void MoveCommand::undoOff() - { - if (m_device->undoAdapter()) { - m_device->undoAdapter()->setUndo(false); - } - } - - void MoveCommand::undoOn() - { - if (m_device->undoAdapter()) { - m_device->undoAdapter()->setUndo(true); - } - } - - void MoveCommand::execute() - { - undoOff(); - moveTo(m_newPos); - undoOn(); - } - - void MoveCommand::unexecute() - { - undoOff(); - moveTo(m_oldPos); - undoOn(); - } - - void MoveCommand::moveTo(const TQPoint& pos) - { - m_device->move(pos.x(), pos.y()); - } - - class KisConvertLayerTypeCmd : public KNamedCommand { - typedef KNamedCommand super; - - public: - KisConvertLayerTypeCmd(KisUndoAdapter *adapter, KisPaintDeviceSP paintDevice, - KisDataManagerSP beforeData, KisColorSpace * beforeColorSpace, - KisDataManagerSP afterData, KisColorSpace * afterColorSpace - ) : super(i18n("Convert Layer Type")) - { - m_adapter = adapter; - m_paintDevice = paintDevice; - m_beforeData = beforeData; - m_beforeColorSpace = beforeColorSpace; - m_afterData = afterData; - m_afterColorSpace = afterColorSpace; - } - - virtual ~KisConvertLayerTypeCmd() - { - } - - public: - virtual void execute() - { - m_adapter->setUndo(false); - m_paintDevice->setData(m_afterData, m_afterColorSpace); - m_adapter->setUndo(true); - } - - virtual void unexecute() - { - m_adapter->setUndo(false); - m_paintDevice->setData(m_beforeData, m_beforeColorSpace); - m_adapter->setUndo(true); - } - - private: - KisUndoAdapter *m_adapter; - - KisPaintDeviceSP m_paintDevice; - - KisDataManagerSP m_beforeData; - KisColorSpace * m_beforeColorSpace; - - KisDataManagerSP m_afterData; - KisColorSpace * m_afterColorSpace; - }; - -} - -KisPaintDevice::KisPaintDevice(KisColorSpace * colorSpace, const char * name) : - TQObject(0, name), KShared(), m_exifInfo(0), m_lock( false ) -{ - if (colorSpace == 0) { - kdWarning(41001) << "Cannot create paint device without colorstrategy!\n"; - return; - } - m_longRunningFilterTimer = 0; - m_dcop = 0; - - m_x = 0; - m_y = 0; - - m_pixelSize = colorSpace->pixelSize(); - m_nChannels = colorSpace->nChannels(); - - TQ_UINT8* defPixel = new TQ_UINT8 [ m_pixelSize ]; - colorSpace->fromTQColor(TQt::black, OPACITY_TRANSPARENT, defPixel); - - m_datamanager = new KisDataManager(m_pixelSize, defPixel); - delete [] defPixel; - - Q_CHECK_PTR(m_datamanager); - m_extentIsValid = true; - - m_parentLayer = 0; - - m_colorSpace = colorSpace; - - m_hasSelection = false; - m_selectionDeselected = false; - m_selection = 0; - -} - -KisPaintDevice::KisPaintDevice(KisLayer *tqparent, KisColorSpace * colorSpace, const char * name) : - TQObject(0, name), KShared(), m_exifInfo(0), m_lock( false ) -{ - - m_longRunningFilterTimer = 0; - m_dcop = 0; - - m_x = 0; - m_y = 0; - - m_hasSelection = false; - m_selectionDeselected = false; - m_selection = 0; - - m_parentLayer = tqparent; - - if (colorSpace == 0 && tqparent != 0 && tqparent->image() != 0) { - m_colorSpace = tqparent->image()->colorSpace(); - } - else { - m_colorSpace = colorSpace; - } - - Q_ASSERT( m_colorSpace ); - - m_pixelSize = m_colorSpace->pixelSize(); - m_nChannels = m_colorSpace->nChannels(); - - TQ_UINT8* defPixel = new TQ_UINT8[ m_pixelSize ]; - m_colorSpace->fromTQColor(TQt::black, OPACITY_TRANSPARENT, defPixel); - - m_datamanager = new KisDataManager(m_pixelSize, defPixel); - delete [] defPixel; - Q_CHECK_PTR(m_datamanager); - m_extentIsValid = true; - - if ( TQString ( name ) == TQString( "Layer 1" ) ) { - m_longRunningFilters = m_colorSpace->createBackgroundFilters(); - - if (!m_longRunningFilters.isEmpty()) { - m_longRunningFilterTimer = new TQTimer(this); - connect(m_longRunningFilterTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(runBackgroundFilters())); - m_longRunningFilterTimer->start(2000); - } - } -} - - -KisPaintDevice::KisPaintDevice(const KisPaintDevice& rhs) : TQObject(), KShared(rhs) -{ - if (this != &rhs) { - m_longRunningFilterTimer = 0; - m_parentLayer = 0; - m_dcop = rhs.m_dcop; - if (rhs.m_datamanager) { - m_datamanager = new KisDataManager(*rhs.m_datamanager); - Q_CHECK_PTR(m_datamanager); - } - else { - kdWarning() << "rhs " << rhs.name() << " has no datamanager\n"; - } - m_extentIsValid = rhs.m_extentIsValid; - m_x = rhs.m_x; - m_y = rhs.m_y; - m_colorSpace = rhs.m_colorSpace; - m_hasSelection = rhs.m_hasSelection; - - if ( m_hasSelection ) - m_selection = new KisSelection(*rhs.m_selection); - else - m_selection = 0; - - m_pixelSize = rhs.m_pixelSize; - m_nChannels = rhs.m_nChannels; - if(rhs.m_exifInfo) - { - m_exifInfo = new KisExifInfo(*rhs.m_exifInfo); - } - else { - m_exifInfo = 0; - } - } -} - -KisPaintDevice::~KisPaintDevice() -{ - delete m_dcop; - delete m_longRunningFilterTimer; - TQValueList<KisFilter*>::iterator it; - TQValueList<KisFilter*>::iterator end = m_longRunningFilters.end(); - for (it = m_longRunningFilters.begin(); it != end; ++it) { - KisFilter * f = (*it); - delete f; - } - m_longRunningFilters.clear(); - //delete m_exifInfo; -} - -DCOPObject *KisPaintDevice::dcopObject() -{ - if (!m_dcop) { - m_dcop = new KisPaintDeviceIface(this); - Q_CHECK_PTR(m_dcop); - } - return m_dcop; -} - -KisLayer *KisPaintDevice::tqparentLayer() const -{ - return m_parentLayer; -} - -void KisPaintDevice::setParentLayer(KisLayer *tqparentLayer) -{ - m_parentLayer = tqparentLayer; -} - -void KisPaintDevice::setDirty(const TQRect & rc) -{ - if (m_parentLayer) m_parentLayer->setDirty(rc); -} - -void KisPaintDevice::setDirty() -{ - if (m_parentLayer) m_parentLayer->setDirty(); -} - -KisImage *KisPaintDevice::image() const -{ - if (m_parentLayer) { - return m_parentLayer->image(); - } else { - return 0; - } -} - - -void KisPaintDevice::move(TQ_INT32 x, TQ_INT32 y) -{ - TQRect dirtyRect = extent(); - - m_x = x; - m_y = y; - - dirtyRect |= extent(); - - if(m_selection) - { - m_selection->setX(x); - m_selection->setY(y); - } - - setDirty(dirtyRect); - - emit positionChanged(this); -} - -void KisPaintDevice::move(const TQPoint& pt) -{ - move(pt.x(), pt.y()); -} - -KNamedCommand * KisPaintDevice::moveCommand(TQ_INT32 x, TQ_INT32 y) -{ - KNamedCommand * cmd = new MoveCommand(this, TQPoint(m_x, m_y), TQPoint(x, y)); - Q_CHECK_PTR(cmd); - cmd->execute(); - return cmd; -} - -void KisPaintDevice::extent(TQ_INT32 &x, TQ_INT32 &y, TQ_INT32 &w, TQ_INT32 &h) const -{ - m_datamanager->extent(x, y, w, h); - x += m_x; - y += m_y; -} - -TQRect KisPaintDevice::extent() const -{ - TQ_INT32 x, y, w, h; - extent(x, y, w, h); - return TQRect(x, y, w, h); -} - -bool KisPaintDevice::extentIsValid() const -{ - return m_extentIsValid; -} - -void KisPaintDevice::setExtentIsValid(bool isValid) -{ - m_extentIsValid = isValid; -} - -void KisPaintDevice::exactBounds(TQ_INT32 &x, TQ_INT32 &y, TQ_INT32 &w, TQ_INT32 &h) const -{ - TQRect r = exactBounds(); - x = r.x(); - y = r.y(); - w = r.width(); - h = r.height(); -} - -TQRect KisPaintDevice::exactBoundsOldMethod() const -{ - TQ_INT32 x, y, w, h, boundX, boundY, boundW, boundH; - extent(x, y, w, h); - - extent(boundX, boundY, boundW, boundH); - - const TQ_UINT8* defaultPixel = m_datamanager->defaultPixel(); - - bool found = false; - - for (TQ_INT32 y2 = y; y2 < y + h ; ++y2) { - KisHLineIterator it = const_cast<KisPaintDevice *>(this)->createHLineIterator(x, y2, w, false); - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundY = y2; - found = true; - break; - } - ++it; - } - if (found) break; - } - - found = false; - - for (TQ_INT32 y2 = y + h; y2 > y ; --y2) { - KisHLineIterator it = const_cast<KisPaintDevice *>(this)->createHLineIterator(x, y2, w, false); - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundH = y2 - boundY + 1; - found = true; - break; - } - ++it; - } - if (found) break; - } - found = false; - - for (TQ_INT32 x2 = x; x2 < x + w ; ++x2) { - KisVLineIterator it = const_cast<KisPaintDevice *>(this)->createVLineIterator(x2, y, h, false); - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundX = x2; - found = true; - break; - } - ++it; - } - if (found) break; - } - - found = false; - - // Look for right edge ) - for (TQ_INT32 x2 = x + w; x2 > x ; --x2) { - KisVLineIterator it = const_cast<KisPaintDevice *>(this)->createVLineIterator(x2, y, h, false); - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundW = x2 - boundX + 1; // XXX: I commented this - // +1 out, but why? It - // should be correct, since - // we've found the first - // pixel that should be - // included, and it should - // be added to the width. - found = true; - break; - } - ++it; - } - if (found) break; - } - - return TQRect(boundX, boundY, boundW, boundH); -} - -TQRect KisPaintDevice::exactBoundsImprovedOldMethod() const -{ - // Solution n°2 - TQ_INT32 x, y, w, h, boundX2, boundY2, boundW2, boundH2; - extent(x, y, w, h); - extent(boundX2, boundY2, boundW2, boundH2); - - const TQ_UINT8* defaultPixel = m_datamanager->defaultPixel(); - bool found = false; - { - KisHLineIterator it = const_cast<KisPaintDevice *>(this)->createHLineIterator(x, y, w, false); - for (TQ_INT32 y2 = y; y2 < y + h ; ++y2) { - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundY2 = y2; - found = true; - break; - } - ++it; - } - if (found) break; - it.nextRow(); - } - } - - found = false; - - for (TQ_INT32 y2 = y + h; y2 > y ; --y2) { - KisHLineIterator it = const_cast<KisPaintDevice *>(this)->createHLineIterator(x, y2, w, false); - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundH2 = y2 - boundY2 + 1; - found = true; - break; - } - ++it; - } - if (found) break; - } - found = false; - - { - KisVLineIterator it = const_cast<KisPaintDevice *>(this)->createVLineIterator(x, boundY2, boundH2, false); - for (TQ_INT32 x2 = x; x2 < x + w ; ++x2) { - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundX2 = x2; - found = true; - break; - } - ++it; - } - if (found) break; - it.nextCol(); - } - } - - found = false; - - // Look for right edge ) - { - for (TQ_INT32 x2 = x + w; x2 > x ; --x2) { - KisVLineIterator it = const_cast<KisPaintDevice *>(this)->createVLineIterator(/*x + w*/ x2, boundY2, boundH2, false); - while (!it.isDone() && found == false) { - if (memcmp(it.rawData(), defaultPixel, m_pixelSize) != 0) { - boundW2 = x2 - boundX2 + 1; // XXX: I commented this - // +1 out, but why? It - // should be correct, since - // we've found the first - // pixel that should be - // included, and it should - // be added to the width. - found = true; - break; - } - ++it; - } - if (found) break; - } - } - return TQRect(boundX2, boundY2, boundW2, boundH2); -} - - -TQRect KisPaintDevice::exactBounds() const -{ - TQRect r2 = exactBoundsImprovedOldMethod(); - return r2; -} - -void KisPaintDevice::crop(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) -{ - m_datamanager->setExtent(x - m_x, y - m_y, w, h); -} - - -void KisPaintDevice::crop(TQRect r) -{ - r.moveBy(-m_x, -m_y); m_datamanager->setExtent(r); -} - -void KisPaintDevice::clear() -{ - m_datamanager->clear(); -} - -void KisPaintDevice::fill(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h, const TQ_UINT8 *fillPixel) -{ - m_datamanager->clear(x, y, w, h, fillPixel); -} - -void KisPaintDevice::mirrorX() -{ - TQRect r; - if (hasSelection()) { - r = selection()->selectedRect(); - } - else { - r = exactBounds(); - } - - for (TQ_INT32 y = r.top(); y <= r.bottom(); ++y) { - KisHLineIteratorPixel srcIt = createHLineIterator(r.x(), y, r.width(), false); - KisHLineIteratorPixel dstIt = createHLineIterator(r.x(), y, r.width(), true); - - dstIt += r.width() - 1; - - while (!srcIt.isDone()) { - if (srcIt.isSelected()) { - memcpy(dstIt.rawData(), srcIt.oldRawData(), m_pixelSize); - } - ++srcIt; - --dstIt; - - } - } - if (m_parentLayer) { - m_parentLayer->setDirty(r); - } -} - -void KisPaintDevice::mirrorY() -{ - /* Read a line from bottom to top and and from top to bottom and write their values to each other */ - TQRect r; - if (hasSelection()) { - r = selection()->selectedRect(); - } - else { - r = exactBounds(); - } - - - TQ_INT32 y1, y2; - for (y1 = r.top(), y2 = r.bottom(); y1 <= r.bottom(); ++y1, --y2) { - KisHLineIteratorPixel itTop = createHLineIterator(r.x(), y1, r.width(), true); - KisHLineIteratorPixel itBottom = createHLineIterator(r.x(), y2, r.width(), false); - while (!itTop.isDone() && !itBottom.isDone()) { - if (itBottom.isSelected()) { - memcpy(itTop.rawData(), itBottom.oldRawData(), m_pixelSize); - } - ++itBottom; - ++itTop; - } - } - - if (m_parentLayer) { - m_parentLayer->setDirty(r); - } -} - -KisMementoSP KisPaintDevice::getMemento() -{ - return m_datamanager->getMemento(); -} - -void KisPaintDevice::rollback(KisMementoSP memento) { m_datamanager->rollback(memento); } - -void KisPaintDevice::rollforward(KisMementoSP memento) { m_datamanager->rollforward(memento); } - -bool KisPaintDevice::write(KoStore *store) -{ - bool retval = m_datamanager->write(store); - emit ioProgress(100); - - return retval; -} - -bool KisPaintDevice::read(KoStore *store) -{ - bool retval = m_datamanager->read(store); - emit ioProgress(100); - - return retval; -} - -void KisPaintDevice::convertTo(KisColorSpace * dstColorSpace, TQ_INT32 renderingIntent) -{ - kdDebug(41004) << "Converting " << name() << " to " << dstColorSpace->id().id() << " from " - << m_colorSpace->id().id() << "\n"; - if ( colorSpace() == dstColorSpace ) - { - return; - } - - KisPaintDevice dst(dstColorSpace); - dst.setX(getX()); - dst.setY(getY()); - - TQ_INT32 x, y, w, h; - extent(x, y, w, h); - - for (TQ_INT32 row = y; row < y + h; ++row) { - - TQ_INT32 column = x; - TQ_INT32 columnsRemaining = w; - - while (columnsRemaining > 0) { - - TQ_INT32 numContiguousDstColumns = dst.numContiguousColumns(column, row, row); - TQ_INT32 numContiguousSrcColumns = numContiguousColumns(column, row, row); - - TQ_INT32 columns = TQMIN(numContiguousDstColumns, numContiguousSrcColumns); - columns = TQMIN(columns, columnsRemaining); - - //const TQ_UINT8 *srcData = pixel(column, row); - //TQ_UINT8 *dstData = dst.writablePixel(column, row); - KisHLineIteratorPixel srcIt = createHLineIterator(column, row, columns, false); - KisHLineIteratorPixel dstIt = dst.createHLineIterator(column, row, columns, true); - - const TQ_UINT8 *srcData = srcIt.rawData(); - TQ_UINT8 *dstData = dstIt.rawData(); - - - m_colorSpace->convertPixelsTo(srcData, dstData, dstColorSpace, columns, renderingIntent); - - column += columns; - columnsRemaining -= columns; - } - } - - KisDataManagerSP oldData = m_datamanager; - KisColorSpace *oldColorSpace = m_colorSpace; - - setData(dst.m_datamanager, dstColorSpace); - - if (undoAdapter() && undoAdapter()->undo()) { - undoAdapter()->addCommand(new KisConvertLayerTypeCmd(undoAdapter(), this, oldData, oldColorSpace, m_datamanager, m_colorSpace)); - } -} - -void KisPaintDevice::setProfile(KisProfile * profile) -{ - if (profile == 0) return; - - KisColorSpace * dstSpace = - KisMetaRegistry::instance()->csRegistry()->getColorSpace( colorSpace()->id(), - profile); - if (dstSpace) - m_colorSpace = dstSpace; - -} - -void KisPaintDevice::setData(KisDataManagerSP data, KisColorSpace * colorSpace) -{ - m_datamanager = data; - m_colorSpace = colorSpace; - m_pixelSize = m_colorSpace->pixelSize(); - m_nChannels = m_colorSpace->nChannels(); - - if (m_parentLayer) { - m_parentLayer->setDirty(extent()); - m_parentLayer->notifyPropertyChanged(); - } -} - -KisUndoAdapter *KisPaintDevice::undoAdapter() const -{ - if (m_parentLayer && m_parentLayer->image()) { - return m_parentLayer->image()->undoAdapter(); - } - return 0; -} - -void KisPaintDevice::convertFromTQImage(const TQImage& image, const TQString &srcProfileName, - TQ_INT32 offsetX, TQ_INT32 offsetY) -{ - TQImage img = image; - - // Krita is little-endian inside. - if (img.bitOrder() == TQImage::LittleEndian) { - img = img.convertBitOrder(TQImage::BigEndian); - } - kdDebug() << k_funcinfo << img.bitOrder()<< endl; - // Krita likes bgra (convertDepth returns *this is the img is alread 32 bits) - img = img.convertDepth( 32 ); -#if 0 - // XXX: Apply import profile - if (colorSpace() == KisMetaRegistry::instance()->csRegistry() ->getColorSpace(KisID("RGBA",""),"")) { - writeBytes(img.bits(), 0, 0, img.width(), img.height()); - } - else { -#endif - TQ_UINT8 * dstData = new TQ_UINT8[img.width() * img.height() * pixelSize()]; - KisMetaRegistry::instance()->csRegistry() - ->getColorSpace(KisID("RGBA",""),srcProfileName)-> - convertPixelsTo(img.bits(), dstData, colorSpace(), img.width() * img.height()); - writeBytes(dstData, offsetX, offsetY, img.width(), img.height()); -// } -} - -TQImage KisPaintDevice::convertToTQImage(KisProfile * dstProfile, float exposure) -{ - TQ_INT32 x1; - TQ_INT32 y1; - TQ_INT32 w; - TQ_INT32 h; - - x1 = - getX(); - y1 = - getY(); - - if (image()) { - w = image()->width(); - h = image()->height(); - } - else { - extent(x1, y1, w, h); - } - - return convertToTQImage(dstProfile, x1, y1, w, h, exposure); -} - -// XXX: is this faster than building the TQImage ourselves? It makes -TQImage KisPaintDevice::convertToTQImage(KisProfile * dstProfile, TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 w, TQ_INT32 h, float exposure) -{ - if (w < 0) - return TQImage(); - - if (h < 0) - return TQImage(); - - TQ_UINT8 * data = new TQ_UINT8 [w * h * m_pixelSize]; - Q_CHECK_PTR(data); - - // XXX: Is this really faster than converting line by line and building the TQImage directly? - // This copies potentially a lot of data. - readBytes(data, x1, y1, w, h); - TQImage image = colorSpace()->convertToTQImage(data, w, h, dstProfile, INTENT_PERCEPTUAL, exposure); - delete[] data; - - return image; -} - -KisPaintDeviceSP KisPaintDevice::createThumbnailDevice(TQ_INT32 w, TQ_INT32 h) -{ - KisPaintDeviceSP thumbnail = new KisPaintDevice(colorSpace(), "thumbnail"); - - thumbnail->clear(); - - int srcw, srch; - if( image() ) - { - srcw = image()->width(); - srch = image()->height(); - } - else - { - const TQRect e = exactBounds(); - srcw = e.width(); - srch = e.height(); - } - - if (w > srcw) - { - w = srcw; - h = TQ_INT32(double(srcw) / w * h); - } - if (h > srch) - { - h = srch; - w = TQ_INT32(double(srch) / h * w); - } - - if (srcw > srch) - h = TQ_INT32(double(srch) / srcw * w); - else if (srch > srcw) - w = TQ_INT32(double(srcw) / srch * h); - - for (TQ_INT32 y=0; y < h; ++y) { - TQ_INT32 iY = (y * srch ) / h; - for (TQ_INT32 x=0; x < w; ++x) { - TQ_INT32 iX = (x * srcw ) / w; - thumbnail->setPixel(x, y, colorAt(iX, iY)); - } - } - - return thumbnail; - -} - - -TQImage KisPaintDevice::createThumbnail(TQ_INT32 w, TQ_INT32 h) -{ - int srcw, srch; - if( image() ) - { - srcw = image()->width(); - srch = image()->height(); - } - else - { - const TQRect e = extent(); - srcw = e.width(); - srch = e.height(); - } - - if (w > srcw) - { - w = srcw; - h = TQ_INT32(double(srcw) / w * h); - } - if (h > srch) - { - h = srch; - w = TQ_INT32(double(srch) / h * w); - } - - if (srcw > srch) - h = TQ_INT32(double(srch) / srcw * w); - else if (srch > srcw) - w = TQ_INT32(double(srcw) / srch * h); - - TQColor c; - TQ_UINT8 opacity; - TQImage img(w,h,32); - - for (TQ_INT32 y=0; y < h; ++y) { - TQ_INT32 iY = (y * srch ) / h; - for (TQ_INT32 x=0; x < w; ++x) { - TQ_INT32 iX = (x * srcw ) / w; - pixel(iX, iY, &c, &opacity); - const TQRgb rgb = c.rgb(); - img.setPixel(x, y, tqRgba(tqRed(rgb), tqGreen(rgb), tqBlue(rgb), opacity)); - } - } - - return img; -} - -KisRectIteratorPixel KisPaintDevice::createRectIterator(TQ_INT32 left, TQ_INT32 top, TQ_INT32 w, TQ_INT32 h, bool writable) -{ - if(hasSelection()) - return KisRectIteratorPixel(this, m_datamanager, m_selection->m_datamanager, left, top, w, h, m_x, m_y, writable); - else - return KisRectIteratorPixel(this, m_datamanager, NULL, left, top, w, h, m_x, m_y, writable); -} - -KisHLineIteratorPixel KisPaintDevice::createHLineIterator(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, bool writable) -{ - if(hasSelection()) - return KisHLineIteratorPixel(this, m_datamanager, m_selection->m_datamanager, x, y, w, m_x, m_y, writable); - else - return KisHLineIteratorPixel(this, m_datamanager, NULL, x, y, w, m_x, m_y, writable); -} - -KisVLineIteratorPixel KisPaintDevice::createVLineIterator(TQ_INT32 x, TQ_INT32 y, TQ_INT32 h, bool writable) -{ - if(hasSelection()) - return KisVLineIteratorPixel(this, m_datamanager, m_selection->m_datamanager, x, y, h, m_x, m_y, writable); - else - return KisVLineIteratorPixel(this, m_datamanager, NULL, x, y, h, m_x, m_y, writable); - -} - -KisRandomAccessorPixel KisPaintDevice::createRandomAccessor(TQ_INT32 x, TQ_INT32 y, bool writable) { - if(hasSelection()) - return KisRandomAccessorPixel(m_datamanager, m_selection->m_datamanager, x, y, m_x, m_y, writable); - else - return KisRandomAccessorPixel(m_datamanager, NULL, x, y, m_x, m_y, writable); -} - -KisRandomSubAccessorPixel KisPaintDevice::createRandomSubAccessor() -{ - return KisRandomSubAccessorPixel(this); -} - -void KisPaintDevice::emitSelectionChanged() -{ - if (m_parentLayer && m_parentLayer->image()) { - m_parentLayer->image()->slotSelectionChanged(); - } -} - -void KisPaintDevice::emitSelectionChanged(const TQRect& r) -{ - if (m_parentLayer && m_parentLayer->image()) { - m_parentLayer->image()->slotSelectionChanged(r); - } -} - -KisSelectionSP KisPaintDevice::selection() -{ - if ( m_selectionDeselected && m_selection ) { - m_selectionDeselected = false; - } - else if (!m_selection) { - m_selection = new KisSelection(this); - Q_CHECK_PTR(m_selection); - m_selection->setX(m_x); - m_selection->setY(m_y); - } - m_hasSelection = true; - - return m_selection; -} - - -bool KisPaintDevice::hasSelection() -{ - return m_hasSelection; -} - -bool KisPaintDevice::selectionDeselected() -{ - return m_selectionDeselected; -} - - -void KisPaintDevice::deselect() -{ - if (m_selection && m_hasSelection) { - m_hasSelection = false; - m_selectionDeselected = true; - } -} - -void KisPaintDevice::reselect() -{ - m_hasSelection = true; - m_selectionDeselected = false; -} - -void KisPaintDevice::addSelection(KisSelectionSP selection) { - - KisPainter painter(this->selection().data()); - TQRect r = selection->selectedExactRect(); - painter.bitBlt(r.x(), r.y(), COMPOSITE_OVER, selection.data(), r.x(), r.y(), r.width(), r.height()); - painter.end(); -} - -void KisPaintDevice::subtractSelection(KisSelectionSP selection) { - KisPainter painter(this->selection().data()); - selection->invert(); - - TQRect r = selection->selectedExactRect(); - painter.bitBlt(r.x(), r.y(), COMPOSITE_ERASE, selection.data(), r.x(), r.y(), r.width(), r.height()); - - selection->invert(); - painter.end(); -} - -void KisPaintDevice::clearSelection() -{ - if (!hasSelection()) return; - - TQRect r = m_selection->selectedExactRect(); - - if (r.isValid()) { - - for (TQ_INT32 y = 0; y < r.height(); y++) { - - KisHLineIterator devIt = createHLineIterator(r.x(), r.y() + y, r.width(), true); - KisHLineIterator selectionIt = m_selection->createHLineIterator(r.x(), r.y() + y, r.width(), false); - - while (!devIt.isDone()) { - // XXX: Optimize by using stretches - - m_colorSpace->applyInverseAlphaU8Mask( devIt.rawData(), selectionIt.rawData(), 1); - - ++devIt; - ++selectionIt; - } - } - - if (m_parentLayer) { - m_parentLayer->setDirty(r); - } - } -} - -void KisPaintDevice::applySelectionMask(KisSelectionSP tqmask) -{ - TQRect r = tqmask->selectedRect(); - crop(r); - - for (TQ_INT32 y = r.top(); y <= r.bottom(); ++y) { - - KisHLineIterator pixelIt = createHLineIterator(r.x(), y, r.width(), true); - KisHLineIterator tqmaskIt = tqmask->createHLineIterator(r.x(), y, r.width(), false); - - while (!pixelIt.isDone()) { - // XXX: Optimize by using stretches - - m_colorSpace->applyAlphaU8Mask( pixelIt.rawData(), tqmaskIt.rawData(), 1); - - ++pixelIt; - ++tqmaskIt; - } - } -} - -KisSelectionSP KisPaintDevice::setSelection( KisSelectionSP selection) -{ - if (selection) { - KisSelectionSP oldSelection = m_selection; - m_selection = selection; - m_hasSelection = true; - return oldSelection; - } - else return 0; -} - -bool KisPaintDevice::pixel(TQ_INT32 x, TQ_INT32 y, TQColor *c, TQ_UINT8 *opacity) -{ - KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, false); - - TQ_UINT8 *pix = iter.rawData(); - - if (!pix) return false; - - colorSpace()->toTQColor(pix, c, opacity); - - return true; -} - - -bool KisPaintDevice::pixel(TQ_INT32 x, TQ_INT32 y, KisColor * kc) -{ - KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, false); - - TQ_UINT8 *pix = iter.rawData(); - - if (!pix) return false; - - kc->setColor(pix, m_colorSpace); - - return true; -} - -KisColor KisPaintDevice::colorAt(TQ_INT32 x, TQ_INT32 y) -{ - //return KisColor(m_datamanager->pixel(x - m_x, y - m_y), m_colorSpace); - KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, true); - return KisColor(iter.rawData(), m_colorSpace); -} - -bool KisPaintDevice::setPixel(TQ_INT32 x, TQ_INT32 y, const TQColor& c, TQ_UINT8 opacity) -{ - KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, true); - - colorSpace()->fromTQColor(c, opacity, iter.rawData()); - - return true; -} - -bool KisPaintDevice::setPixel(TQ_INT32 x, TQ_INT32 y, const KisColor& kc) -{ - TQ_UINT8 * pix; - if (kc.colorSpace() != m_colorSpace) { - KisColor kc2 (kc, m_colorSpace); - pix = kc2.data(); - } - else { - pix = kc.data(); - } - - KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, true); - memcpy(iter.rawData(), pix, m_colorSpace->pixelSize()); - - return true; -} - - -TQ_INT32 KisPaintDevice::numContiguousColumns(TQ_INT32 x, TQ_INT32 minY, TQ_INT32 maxY) -{ - return m_datamanager->numContiguousColumns(x - m_x, minY - m_y, maxY - m_y); -} - -TQ_INT32 KisPaintDevice::numContiguousRows(TQ_INT32 y, TQ_INT32 minX, TQ_INT32 maxX) -{ - return m_datamanager->numContiguousRows(y - m_y, minX - m_x, maxX - m_x); -} - -TQ_INT32 KisPaintDevice::rowStride(TQ_INT32 x, TQ_INT32 y) -{ - return m_datamanager->rowStride(x - m_x, y - m_y); -} - -const TQ_UINT8* KisPaintDevice::pixel(TQ_INT32 x, TQ_INT32 y) -{ - return m_datamanager->pixel(x - m_x, y - m_y); -} - -TQ_UINT8* KisPaintDevice::writablePixel(TQ_INT32 x, TQ_INT32 y) -{ - return m_datamanager->writablePixel(x - m_x, y - m_y); -} - -void KisPaintDevice::setX(TQ_INT32 x) -{ - m_x = x; - if(m_selection && m_selection != this) - m_selection->setX(x); -} - -void KisPaintDevice::setY(TQ_INT32 y) -{ - m_y = y; - if(m_selection && m_selection != this) - m_selection->setY(y); -} - - -void KisPaintDevice::readBytes(TQ_UINT8 * data, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) -{ - m_datamanager->readBytes(data, x - m_x, y - m_y, w, h); -} - -void KisPaintDevice::writeBytes(const TQ_UINT8 * data, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) -{ - m_datamanager->writeBytes( data, x - m_x, y - m_y, w, h); -} - - -KisDataManagerSP KisPaintDevice::dataManager() const -{ - return m_datamanager; -} - -KisExifInfo* KisPaintDevice::exifInfo() -{ - if(!m_exifInfo) - m_exifInfo = new KisExifInfo(); - return m_exifInfo; -} - -void KisPaintDevice::runBackgroundFilters() -{ - if ( m_lock ) return; - - KisTransaction * cmd = new KisTransaction("Running autofilters", this); - - TQRect rc = extent(); - if (!m_longRunningFilters.isEmpty()) { - TQValueList<KisFilter*>::iterator it; - TQValueList<KisFilter*>::iterator end = m_longRunningFilters.end(); - for (it = m_longRunningFilters.begin(); it != end; ++it) { - (*it)->process(this, this, 0, rc); - } - } - if (cmd && undoAdapter()) undoAdapter()->addCommand(cmd); - - if (m_parentLayer) m_parentLayer->setDirty(rc); -} - -#include "kis_paint_device.moc" |