00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <kdebug.h>
00021 #include <qimage.h>
00022
00023 #include "kis_debug_areas.h"
00024 #include "kis_image.h"
00025 #include "kis_paint_layer.h"
00026 #include "kis_selection.h"
00027 #include "kis_painter.h"
00028 #include "kis_undo_adapter.h"
00029 #include "kis_iterators_pixel.h"
00030 #include "kis_paint_device.h"
00031 #include "kis_meta_registry.h"
00032 #include "kis_colorspace_factory_registry.h"
00033 #include "kis_datamanager.h"
00034 #include "kis_undo_adapter.h"
00035
00036 KisPaintLayer::KisPaintLayer(KisImage *img, const QString& name, Q_UINT8 opacity, KisPaintDeviceSP dev)
00037 : super(img, name, opacity)
00038 {
00039 Q_ASSERT(img);
00040 Q_ASSERT(dev);
00041 m_paintdev = dev;
00042 m_mask = 0;
00043 m_maskAsSelection = 0;
00044 m_paintdev->setParentLayer(this);
00045 m_renderMask = false;
00046 m_editMask = true;
00047 }
00048
00049
00050 KisPaintLayer::KisPaintLayer(KisImage *img, const QString& name, Q_UINT8 opacity)
00051 : super(img, name, opacity)
00052 {
00053 Q_ASSERT(img);
00054 m_paintdev = new KisPaintDevice(this, img->colorSpace(), name.latin1());
00055 m_mask = 0;
00056 m_maskAsSelection = 0;
00057 m_renderMask = false;
00058 m_editMask = true;
00059 }
00060
00061 KisPaintLayer::KisPaintLayer(KisImage *img, const QString& name, Q_UINT8 opacity, KisColorSpace * colorSpace)
00062 : super(img, name, opacity)
00063 {
00064 Q_ASSERT(img);
00065 Q_ASSERT(colorSpace);
00066 m_paintdev = new KisPaintDevice(this, colorSpace, name.latin1());
00067 m_mask = 0;
00068 m_maskAsSelection = 0;
00069 m_renderMask = false;
00070 m_editMask = true;
00071 }
00072
00073 KisPaintLayer::KisPaintLayer(const KisPaintLayer& rhs) :
00074 KisLayer(rhs), KisLayerSupportsIndirectPainting(rhs)
00075 {
00076 m_paintdev = new KisPaintDevice( *rhs.m_paintdev.data() );
00077 m_paintdev->setParentLayer(this);
00078 if (rhs.hasMask()) {
00079 m_mask = new KisPaintDevice(*rhs.m_mask.data());
00080 m_mask->setParentLayer(this);
00081 }
00082 m_renderMask = rhs.m_renderMask;
00083 m_editMask = rhs.m_editMask;
00084 }
00085
00086 KisLayerSP KisPaintLayer::clone() const
00087 {
00088 return new KisPaintLayer(*this);
00089 }
00090
00091 KisPaintLayer::~KisPaintLayer()
00092 {
00093 if (m_paintdev != 0) {
00094 m_paintdev->setParentLayer(0);
00095 }
00096 if (m_mask != 0) {
00097 m_mask->setParentLayer(0);
00098 }
00099 }
00100
00101 void KisPaintLayer::paintSelection(QImage &img, Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
00102 {
00103 if (m_paintdev && m_paintdev->hasSelection()) {
00104 m_paintdev->selection()->paintSelection(img, x, y, w, h);
00105 } else if (m_mask && m_editMask && m_mask->hasSelection()) {
00106 m_mask->selection()->paintSelection(img, x, y, w, h);
00107 }
00108 }
00109
00110 void KisPaintLayer::paintSelection(QImage &img, const QRect& scaledImageRect, const QSize& scaledImageSize, const QSize& imageSize)
00111 {
00112 if (m_paintdev && m_paintdev->hasSelection()) {
00113 m_paintdev->selection()->paintSelection(img, scaledImageRect, scaledImageSize, imageSize);
00114 } else if (m_mask && m_editMask && m_mask->hasSelection()) {
00115 m_mask->selection()->paintSelection(img, scaledImageRect, scaledImageSize, imageSize);
00116 }
00117 }
00118
00119 void KisPaintLayer::paintMaskInactiveLayers(QImage &img, Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
00120 {
00121 uchar *j = img.bits();
00122
00123 KisColorSpace *cs = m_paintdev->colorSpace();
00124
00125 for (Q_INT32 y2 = y; y2 < h + y; ++y2) {
00126 KisHLineIteratorPixel it = m_paintdev->createHLineIterator(x, y2, w, false);
00127 while ( ! it.isDone()) {
00128 Q_UINT8 s = cs->getAlpha(it.rawData());
00129 if(s==0)
00130 {
00131 Q_UINT8 g = (*(j + 0) + *(j + 1 ) + *(j + 2 )) / 9;
00132
00133 *(j+0) = 128+g ;
00134 *(j+1) = 165+g;
00135 *(j+2) = 128+g;
00136 }
00137 j+=4;
00138 ++it;
00139 }
00140 }
00141 }
00142
00143 QImage KisPaintLayer::createThumbnail(Q_INT32 w, Q_INT32 h)
00144 {
00145 if (m_paintdev)
00146 return m_paintdev->createThumbnail(w, h);
00147 else
00148 return QImage();
00149 }
00150
00151
00152 Q_INT32 KisPaintLayer::x() const {
00153 if (m_paintdev)
00154 return m_paintdev->getX();
00155 else return 0;
00156 }
00157
00158 void KisPaintLayer::setX(Q_INT32 x)
00159 {
00160 if (m_paintdev)
00161 m_paintdev->setX(x);
00162 }
00163
00164 Q_INT32 KisPaintLayer::y() const {
00165 if (m_paintdev)
00166 return m_paintdev->getY();
00167 else
00168 return 0;
00169 }
00170
00171 void KisPaintLayer::setY(Q_INT32 y) {
00172 if (m_paintdev)
00173 m_paintdev->setY(y);
00174 }
00175
00176 QRect KisPaintLayer::extent() const {
00177 if (m_paintdev)
00178 return m_paintdev->extent();
00179 else
00180 return QRect();
00181 }
00182
00183 QRect KisPaintLayer::exactBounds() const {
00184 if (m_paintdev)
00185 return m_paintdev->exactBounds();
00186 else
00187 return QRect();
00188 }
00189
00190 void KisPaintLayer::removeMask() {
00191 if (!hasMask())
00192 return;
00193
00194 m_mask->setParentLayer(0);
00195 m_mask = 0;
00196 m_maskAsSelection = 0;
00197 setDirty();
00198
00199 emit sigMaskInfoChanged();
00200 }
00201
00202
00203 void KisPaintLayer::applyMask() {
00204 if (!hasMask())
00205 return;
00206
00207 int x, y, w, h;
00208 m_paintdev->extent(x, y, w, h);
00209
00210
00211 KisPaintDeviceSP temp = new KisPaintDevice(m_paintdev->colorSpace());
00212 KisPainter gc(temp);
00213 gc.bltSelection(x, y, COMPOSITE_OVER, m_paintdev, m_maskAsSelection, OPACITY_OPAQUE, x, y, w, h);
00214 gc.end();
00215 gc.begin(m_paintdev);
00216 gc.bitBlt(x, y, COMPOSITE_COPY, temp, OPACITY_OPAQUE, x, y, w, h);
00217 gc.end();
00218
00219 removeMask();
00220 }
00221
00222 KisPaintDeviceSP KisPaintLayer::createMask() {
00223 if (hasMask())
00224 return m_mask;
00225
00226 kdDebug() << k_funcinfo << endl;
00227
00228
00229
00230 m_mask = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()
00231 ->getColorSpace(KisID("GRAYA"), 0));
00232
00233 genericMaskCreationHelper();
00234
00235 return m_mask;
00236 }
00237
00238
00239 void KisPaintLayer::createMaskFromPaintDevice(KisPaintDeviceSP from) {
00240 if (hasMask())
00241 return;
00242
00243 kdDebug() << k_funcinfo << endl;
00244 m_mask = from;
00245
00246 genericMaskCreationHelper();
00247 }
00248
00249 void KisPaintLayer::createMaskFromSelection(KisSelectionSP from) {
00250 kdDebug() << k_funcinfo << endl;
00251 m_mask = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()
00252 ->getColorSpace(KisID("GRAYA"), 0));
00253 m_mask->setParentLayer(this);
00254
00255 m_maskAsSelection = new KisSelection();
00256
00257
00258 Q_UINT8 const defPixel[] = { 255, 255 };
00259 m_mask->dataManager()->setDefaultPixel(defPixel);
00260
00261 if (from) {
00262 QRect r(extent());
00263
00264 int w = r.width();
00265 int h = r.height();
00266 for (int y = r.y(); y < h; y++) {
00267 KisHLineIteratorPixel srcIt = from->createHLineIterator(r.x(), y, w, false);
00268 KisHLineIteratorPixel dstIt = m_mask->createHLineIterator(r.x(), y, w, true);
00269
00270 while(!dstIt.isDone()) {
00271
00272 *dstIt.rawData() = *srcIt.rawData();
00273 ++srcIt;
00274 ++dstIt;
00275 }
00276 }
00277 }
00278
00279 convertMaskToSelection(extent());
00280 m_paintdev->deselect();
00281
00282 setDirty();
00283 emit sigMaskInfoChanged();
00284 }
00285
00286 KisPaintDeviceSP KisPaintLayer::getMask() {
00287 createMask();
00288 kdDebug() << k_funcinfo << endl;
00289 return m_mask;
00290 }
00291
00292 KisSelectionSP KisPaintLayer::getMaskAsSelection() {
00293 createMask();
00294 kdDebug() << k_funcinfo << endl;
00295 return m_maskAsSelection;
00296 }
00297
00298 void KisPaintLayer::setEditMask(bool b) {
00299 m_editMask = b;
00300 emit sigMaskInfoChanged();
00301 }
00302
00303 void KisPaintLayer::setRenderMask(bool b) {
00304 m_renderMask = b;
00305
00306 if (hasMask())
00307 setDirty();
00308
00309 emit sigMaskInfoChanged();
00310 }
00311
00312 void KisPaintLayer::convertMaskToSelection(const QRect& r) {
00313 KisRectIteratorPixel srcIt = m_mask->createRectIterator(r.x(), r.y(),
00314 r.width(), r.height(), false);
00315 KisRectIteratorPixel dstIt = m_maskAsSelection->createRectIterator(r.x(), r.y(),
00316 r.width(), r.height(), true);
00317
00318 while(!dstIt.isDone()) {
00319
00320
00321
00322 *dstIt.rawData() = *srcIt.rawData();
00323 ++srcIt;
00324 ++dstIt;
00325 }
00326 }
00327
00328 void KisPaintLayer::genericMaskCreationHelper() {
00329 m_mask->setParentLayer(this);
00330
00331 m_maskAsSelection = new KisSelection();
00332
00333
00334 Q_UINT8 const defPixel[] = { 255, 255 };
00335 m_mask->dataManager()->setDefaultPixel(defPixel);
00336
00337 setDirty();
00338 emit sigMaskInfoChanged();
00339 }
00340
00341 void KisPaintLayer::setDirty(bool propagate) {
00342 if (hasMask())
00343 convertMaskToSelection(extent());
00344 super::setDirty(propagate);
00345 }
00346
00347 void KisPaintLayer::setDirty(const QRect & rect, bool propagate) {
00348 if (hasMask())
00349 convertMaskToSelection(rect);
00350 super::setDirty(rect, propagate);
00351 }
00352
00353
00354 namespace {
00355 class KisCreateMaskCommand : public KNamedCommand {
00356 typedef KNamedCommand super;
00357 KisPaintLayerSP m_layer;
00358 KisPaintDeviceSP m_mask;
00359 public:
00360 KisCreateMaskCommand(const QString& name, KisPaintLayer* layer)
00361 : super(name), m_layer(layer) {}
00362 virtual void execute() {
00363 kdDebug() << k_funcinfo << endl;
00364 if (!m_mask)
00365 m_mask = m_layer->createMask();
00366 else
00367 m_layer->createMaskFromPaintDevice(m_mask);
00368 }
00369 virtual void unexecute() {
00370 m_layer->removeMask();
00371 }
00372 };
00373
00374 class KisMaskFromSelectionCommand : public KNamedCommand {
00375 typedef KNamedCommand super;
00376 KisPaintLayerSP m_layer;
00377 KisPaintDeviceSP m_maskBefore;
00378 KisPaintDeviceSP m_maskAfter;
00379 KisSelectionSP m_selection;
00380 public:
00381 KisMaskFromSelectionCommand(const QString& name, KisPaintLayer* layer)
00382 : super(name), m_layer(layer) {
00383 if (m_layer->hasMask())
00384 m_maskBefore = m_layer->getMask();
00385 else
00386 m_maskBefore = 0;
00387 m_maskAfter = 0;
00388 if (m_layer->paintDevice()->hasSelection())
00389 m_selection = m_layer->paintDevice()->selection();
00390 else
00391 m_selection = 0;
00392 }
00393 virtual void execute() {
00394 if (!m_maskAfter) {
00395 m_layer->createMaskFromSelection(m_selection);
00396 m_maskAfter = m_layer->getMask();
00397 } else {
00398 m_layer->paintDevice()->deselect();
00399 m_layer->createMaskFromPaintDevice(m_maskAfter);
00400 }
00401 }
00402 virtual void unexecute() {
00403 m_layer->paintDevice()->setSelection(m_selection);
00404 if (m_maskBefore)
00405 m_layer->createMaskFromPaintDevice(m_maskBefore);
00406 else
00407 m_layer->removeMask();
00408 }
00409 };
00410
00411 class KisMaskToSelectionCommand : public KNamedCommand {
00412 typedef KNamedCommand super;
00413 KisPaintLayerSP m_layer;
00414 KisPaintDeviceSP m_mask;
00415 KisSelectionSP m_selection;
00416 public:
00417 KisMaskToSelectionCommand(const QString& name, KisPaintLayer* layer)
00418 : super(name), m_layer(layer) {
00419 m_mask = m_layer->getMask();
00420 if (m_layer->paintDevice()->hasSelection())
00421 m_selection = m_layer->paintDevice()->selection();
00422 else
00423 m_selection = 0;
00424 }
00425 virtual void execute() {
00426 m_layer->paintDevice()->setSelection(m_layer->getMaskAsSelection());
00427 m_layer->removeMask();
00428 }
00429 virtual void unexecute() {
00430 if (m_selection)
00431 m_layer->paintDevice()->setSelection(m_selection);
00432 else
00433 m_layer->paintDevice()->deselect();
00434 m_layer->createMaskFromPaintDevice(m_mask);
00435 }
00436 };
00437
00438 class KisRemoveMaskCommand : public KNamedCommand {
00439 typedef KNamedCommand super;
00440 KisPaintLayerSP m_layer;
00441 KisPaintDeviceSP m_mask;
00442 public:
00443 KisRemoveMaskCommand(const QString& name, KisPaintLayer* layer)
00444 : super(name), m_layer(layer) {
00445 m_mask = m_layer->getMask();
00446 }
00447 virtual void execute() {
00448 kdDebug() << k_funcinfo << endl;
00449 m_layer->removeMask();
00450 }
00451 virtual void unexecute() {
00452
00453
00454 m_layer->createMaskFromPaintDevice(m_mask);
00455 }
00456 };
00457
00458 class KisApplyMaskCommand : public KNamedCommand {
00459 typedef KNamedCommand super;
00460 KisPaintLayerSP m_layer;
00461 KisPaintDeviceSP m_mask;
00462 KisPaintDeviceSP m_original;
00463 public:
00464 KisApplyMaskCommand(const QString& name, KisPaintLayer* layer)
00465 : super(name), m_layer(layer) {
00466 m_mask = m_layer->getMask();
00467 m_original = new KisPaintDevice(*m_layer->paintDevice());
00468 }
00469 virtual void execute() {
00470 m_layer->applyMask();
00471 }
00472 virtual void unexecute() {
00473
00474
00475 KisPainter gc(m_layer->paintDevice());
00476 int x, y, w, h;
00477 m_layer->paintDevice()->extent(x, y, w, h);
00478
00479 gc.bitBlt(x, y, COMPOSITE_COPY, m_original, OPACITY_OPAQUE, x, y, w, h);
00480 gc.end();
00481
00482 m_layer->createMaskFromPaintDevice(m_mask);
00483 }
00484 };
00485 }
00486
00487 KNamedCommand* KisPaintLayer::createMaskCommand() {
00488 return new KisCreateMaskCommand(i18n("Create Layer Mask"), this);
00489 }
00490
00491 KNamedCommand* KisPaintLayer::maskFromSelectionCommand() {
00492 return new KisMaskFromSelectionCommand(i18n("Mask From Selection"), this);
00493 }
00494
00495 KNamedCommand* KisPaintLayer::maskToSelectionCommand() {
00496 return new KisMaskToSelectionCommand(i18n("Mask to Selection"), this);
00497 }
00498
00499
00500 KNamedCommand* KisPaintLayer::removeMaskCommand() {
00501 return new KisRemoveMaskCommand(i18n("Remove Layer Mask"), this);
00502 }
00503
00504 KNamedCommand* KisPaintLayer::applyMaskCommand() {
00505 return new KisApplyMaskCommand(i18n("Apply Layer Mask"), this);
00506 }
00507
00508
00509 #include "kis_paint_layer.moc"