00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <kdebug.h>
00020 #include <kglobal.h>
00021 #include <qimage.h>
00022 #include <qdatetime.h>
00023
00024 #include "kis_types.h"
00025 #include "kis_layer.h"
00026 #include "kis_group_layer.h"
00027 #include "kis_layer_visitor.h"
00028 #include "kis_debug_areas.h"
00029 #include "kis_image.h"
00030 #include "kis_paint_device.h"
00031 #include "kis_merge_visitor.h"
00032 #include "kis_fill_painter.h"
00033
00034 KisGroupLayer::KisGroupLayer(KisImage *img, const QString &name, Q_UINT8 opacity) :
00035 super(img, name, opacity),
00036 m_x(0),
00037 m_y(0)
00038 {
00039 m_projection = new KisPaintDevice(this, img->colorSpace(), name.latin1());
00040 }
00041
00042 KisGroupLayer::KisGroupLayer(const KisGroupLayer &rhs) :
00043 super(rhs),
00044 m_x(rhs.m_x),
00045 m_y(rhs.m_y)
00046 {
00047 for(vKisLayerSP_cit it = rhs.m_layers.begin(); it != rhs.m_layers.end(); ++it)
00048 {
00049 m_layers.push_back( it->data()->clone() );
00050 }
00051 m_projection = new KisPaintDevice(*rhs.m_projection.data());
00052 m_projection->setParentLayer(this);
00053 }
00054
00055 KisLayerSP KisGroupLayer::clone() const
00056 {
00057 return new KisGroupLayer(*this);
00058 }
00059
00060 KisGroupLayer::~KisGroupLayer()
00061 {
00062 m_layers.clear();
00063 }
00064
00065
00066 void KisGroupLayer::setDirty(bool propagate)
00067 {
00068 KisLayer::setDirty(propagate);
00069 if (propagate) emit (sigDirty(m_dirtyRect));
00070 }
00071
00072 void KisGroupLayer::setDirty(const QRect & rc, bool propagate)
00073 {
00074 KisLayer::setDirty(rc, propagate);
00075 if (propagate) emit sigDirty(rc);
00076 }
00077
00078 void KisGroupLayer::resetProjection()
00079 {
00080 m_projection = new KisPaintDevice(this, image()->colorSpace(), name().latin1());
00081 }
00082
00083 KisPaintDeviceSP KisGroupLayer::projection(const QRect & rect)
00084 {
00085
00086
00087 if (parent() == 0 && childCount() == 1) {
00088 KisPaintLayerSP l = dynamic_cast<KisPaintLayer*>(firstChild().data());
00089 if (l && l->paintDevice()->colorSpace() == m_image->colorSpace() && l->visible() && l->opacity() == OPACITY_OPAQUE) {
00090 l->setClean(rect);
00091 setClean(rect);
00092 return l->paintDevice();
00093 }
00094 }
00095
00096 if (!dirty()) {
00097 return m_projection;
00098 }
00099
00100 if (!rect.intersects(m_dirtyRect)) {
00101 return m_projection;
00102 }
00103
00104
00105
00106
00107
00108
00109 const QRect rc = m_dirtyRect;
00110
00111 QTime t;
00112 t.start();
00113 updateProjection(rc);
00114 setClean(rect);
00115
00116 return m_projection;
00117 }
00118
00119 uint KisGroupLayer::childCount() const
00120 {
00121 return m_layers.count();
00122 }
00123
00124 KisLayerSP KisGroupLayer::firstChild() const
00125 {
00126 return at(0);
00127 }
00128
00129 KisLayerSP KisGroupLayer::lastChild() const
00130 {
00131 return at(childCount() - 1);
00132 }
00133
00134 KisLayerSP KisGroupLayer::at(int index) const
00135 {
00136 if (childCount() && index >= 0 && kClamp(uint(index), uint(0), childCount() - 1) == uint(index))
00137 return m_layers.at(reverseIndex(index));
00138 return 0;
00139 }
00140
00141 int KisGroupLayer::index(KisLayerSP layer) const
00142 {
00143 if (layer->parent().data() == this)
00144 return layer->index();
00145 return -1;
00146 }
00147
00148 void KisGroupLayer::setIndex(KisLayerSP layer, int index)
00149 {
00150 if (layer->parent().data() != this)
00151 return;
00152
00153 removeLayer(layer);
00154 addLayer(layer, index);
00155 }
00156
00157 bool KisGroupLayer::addLayer(KisLayerSP newLayer, int x)
00158 {
00159 if (x < 0 || kClamp(uint(x), uint(0), childCount()) != uint(x) ||
00160 newLayer->parent() || m_layers.contains(newLayer))
00161 {
00162 kdWarning() << "invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, int x)!" << endl;
00163 return false;
00164 }
00165 uint index(x);
00166 if (index == 0)
00167 m_layers.append(newLayer);
00168 else
00169 m_layers.insert(m_layers.begin() + reverseIndex(index) + 1, newLayer);
00170 for (uint i = childCount() - 1; i > index; i--)
00171 at(i)->m_index++;
00172 newLayer->m_parent = this;
00173 newLayer->m_index = index;
00174 newLayer->setImage(image());
00175 newLayer->setDirty(newLayer->extent());
00176 setDirty();
00177 return true;
00178 }
00179
00180 bool KisGroupLayer::addLayer(KisLayerSP newLayer, KisLayerSP aboveThis)
00181 {
00182 if (aboveThis && aboveThis->parent().data() != this)
00183 {
00184 kdWarning() << "invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, KisLayerSP aboveThis)!" << endl;
00185 return false;
00186 }
00187 return addLayer(newLayer, aboveThis ? aboveThis->index() : childCount());
00188 }
00189
00190 bool KisGroupLayer::removeLayer(int x)
00191 {
00192 if (x >= 0 && kClamp(uint(x), uint(0), childCount() - 1) == uint(x))
00193 {
00194 uint index(x);
00195 for (uint i = childCount() - 1; i > index; i--)
00196 at(i)->m_index--;
00197 KisLayerSP removedLayer = at(index);
00198
00199 removedLayer->m_parent = 0;
00200 removedLayer->m_index = -1;
00201 m_layers.erase(m_layers.begin() + reverseIndex(index));
00202 setDirty(removedLayer->extent());
00203 if (childCount() < 1) {
00204
00205 m_projection->clear();
00206 setDirty();
00207 }
00208 return true;
00209 }
00210 kdWarning() << "invalid input to KisGroupLayer::removeLayer()!" << endl;
00211 return false;
00212 }
00213
00214 bool KisGroupLayer::removeLayer(KisLayerSP layer)
00215 {
00216 if (layer->parent().data() != this)
00217 {
00218 kdWarning() << "invalid input to KisGroupLayer::removeLayer()!" << endl;
00219 return false;
00220 }
00221
00222 return removeLayer(layer->index());
00223 }
00224
00225 void KisGroupLayer::setImage(KisImage *image)
00226 {
00227 super::setImage(image);
00228 for (vKisLayerSP_it it = m_layers.begin(); it != m_layers.end(); ++it)
00229 {
00230 (*it)->setImage(image);
00231 }
00232 }
00233
00234 QRect KisGroupLayer::extent() const
00235 {
00236 QRect groupExtent;
00237
00238 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00239 {
00240 groupExtent |= (*it)->extent();
00241 }
00242
00243 return groupExtent;
00244 }
00245
00246 QRect KisGroupLayer::exactBounds() const
00247 {
00248 QRect groupExactBounds;
00249
00250 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00251 {
00252 groupExactBounds |= (*it)->exactBounds();
00253 }
00254
00255 return groupExactBounds;
00256 }
00257
00258 Q_INT32 KisGroupLayer::x() const
00259 {
00260 return m_x;
00261 }
00262
00263 void KisGroupLayer::setX(Q_INT32 x)
00264 {
00265 Q_INT32 delta = x - m_x;
00266
00267 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00268 {
00269 KisLayerSP layer = *it;
00270 layer->setX(layer->x() + delta);
00271 }
00272 m_x = x;
00273 }
00274
00275 Q_INT32 KisGroupLayer::y() const
00276 {
00277 return m_y;
00278 }
00279
00280 void KisGroupLayer::setY(Q_INT32 y)
00281 {
00282 Q_INT32 delta = y - m_y;
00283
00284 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00285 {
00286 KisLayerSP layer = *it;
00287 layer->setY(layer->y() + delta);
00288 }
00289
00290 m_y = y;
00291 }
00292
00293 QImage KisGroupLayer::createThumbnail(Q_INT32 w, Q_INT32 h)
00294 {
00295 return m_projection->createThumbnail(w, h);
00296 }
00297
00298 void KisGroupLayer::updateProjection(const QRect & rc)
00299 {
00300 if (!m_dirtyRect.isValid()) return;
00301
00302
00303 KisLayerSP child = lastChild();
00304
00305
00306 if (!child) m_projection->clear();
00307
00308 KisLayerSP startWith = 0;
00309 KisAdjustmentLayerSP adjLayer = 0;
00310 KisLayerSP tmpPaintLayer = 0;
00311
00312
00313
00314 bool gotPaintLayer = (parent() != 0);
00315
00316
00317
00318
00319 while (child) {
00320 KisAdjustmentLayerSP tmpAdjLayer = dynamic_cast<KisAdjustmentLayer*>(child.data());
00321 if (tmpAdjLayer) {
00322 if (gotPaintLayer) {
00323
00324
00325 if (tmpAdjLayer->dirty(rc) && adjLayer != 0 && adjLayer->visible()) {
00326 startWith = adjLayer->prevSibling();
00327 break;
00328 }
00329 else if (tmpAdjLayer->visible() && !tmpAdjLayer->dirty(rc)) {
00330
00331 adjLayer = tmpAdjLayer;
00332 }
00333 else {
00334 startWith = tmpPaintLayer;
00335 }
00336 }
00337 }
00338 else {
00339 tmpPaintLayer = child;
00340 gotPaintLayer = true;
00341
00342
00343 if (child->dirty(rc)) {
00344 if (adjLayer != 0 && adjLayer->visible()) {
00345
00346 startWith = adjLayer->prevSibling();
00347 }
00348 else {
00349 startWith = child;
00350 }
00351
00352 break;
00353 }
00354 }
00355 child = child->prevSibling();
00356 }
00357
00358 if (adjLayer != 0 && startWith == 0 && gotPaintLayer && adjLayer->prevSibling()) {
00359 startWith = adjLayer->prevSibling();
00360 }
00361
00362
00363 if (adjLayer == 0) {
00364 startWith = lastChild();
00365 }
00366
00367 if (startWith == 0) {
00368 return;
00369 }
00370
00371 bool first = true;
00372
00373
00374 KisFillPainter gc(m_projection);
00375 if (adjLayer != 0) {
00376 gc.bitBlt(rc.left(), rc.top(),
00377 COMPOSITE_COPY, adjLayer->cachedPaintDevice(), OPACITY_OPAQUE,
00378 rc.left(), rc.top(), rc.width(), rc.height());
00379 first = false;
00380 }
00381 else {
00382 gc.eraseRect(rc);
00383 first = true;
00384 }
00385 gc.end();
00386
00387 KisMergeVisitor visitor(m_projection, rc);
00388
00389 child = startWith;
00390
00391 while(child)
00392 {
00393 if(first)
00394 {
00395
00396
00397
00398 const KisCompositeOp cop = child->compositeOp();
00399 const bool block = child->signalsBlocked();
00400 child->blockSignals(true);
00401 child->m_compositeOp = COMPOSITE_COPY;
00402 child->blockSignals(block);
00403 child->accept(visitor);
00404 child->blockSignals(true);
00405 child->m_compositeOp = cop;
00406 child->blockSignals(block);
00407 first = false;
00408 }
00409 else
00410 child->accept(visitor);
00411
00412 child = child->prevSibling();
00413 }
00414 }
00415
00416 #include "kis_group_layer.moc"