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(KisPaintDevice* to)
00079 {
00080 if (to)
00081 m_projection = new KisPaintDevice(*to);
00082 else
00083 m_projection = new KisPaintDevice(this, image()->colorSpace(), name().latin1());
00084 }
00085
00086 bool KisGroupLayer::paintLayerInducesProjectionOptimization(KisPaintLayer* l) {
00087 return l && l->paintDevice()->colorSpace() == m_image->colorSpace() && l->visible()
00088 && l->opacity() == OPACITY_OPAQUE && !l->temporaryTarget() && !l->hasMask();
00089 }
00090
00091 KisPaintDeviceSP KisGroupLayer::projection(const QRect & rect)
00092 {
00093
00094
00095 if (parent() == 0 && childCount() == 1) {
00096 KisPaintLayerSP l = dynamic_cast<KisPaintLayer*>(firstChild().data());
00097 if (paintLayerInducesProjectionOptimization(l)) {
00098 l->setClean(rect);
00099 setClean(rect);
00100 return l->paintDevice();
00101 }
00102 }
00103
00104 if (!dirty()) {
00105 return m_projection;
00106 }
00107
00108 if (!rect.intersects(m_dirtyRect)) {
00109 return m_projection;
00110 }
00111
00112
00113
00114
00115
00116
00117 const QRect rc = m_dirtyRect;
00118
00119 updateProjection(rc);
00120 setClean(rect);
00121
00122 return m_projection;
00123 }
00124
00125 uint KisGroupLayer::childCount() const
00126 {
00127 return m_layers.count();
00128 }
00129
00130 KisLayerSP KisGroupLayer::firstChild() const
00131 {
00132 return at(0);
00133 }
00134
00135 KisLayerSP KisGroupLayer::lastChild() const
00136 {
00137 return at(childCount() - 1);
00138 }
00139
00140 KisLayerSP KisGroupLayer::at(int index) const
00141 {
00142 if (childCount() && index >= 0 && kClamp(uint(index), uint(0), childCount() - 1) == uint(index))
00143 return m_layers.at(reverseIndex(index));
00144 return 0;
00145 }
00146
00147 int KisGroupLayer::index(KisLayerSP layer) const
00148 {
00149 if (layer->parent().data() == this)
00150 return layer->index();
00151 return -1;
00152 }
00153
00154 void KisGroupLayer::setIndex(KisLayerSP layer, int index)
00155 {
00156 if (layer->parent().data() != this)
00157 return;
00158
00159 removeLayer(layer);
00160 addLayer(layer, index);
00161 }
00162
00163 bool KisGroupLayer::addLayer(KisLayerSP newLayer, int x)
00164 {
00165 if (x < 0 || kClamp(uint(x), uint(0), childCount()) != uint(x) ||
00166 newLayer->parent() || m_layers.contains(newLayer))
00167 {
00168 kdWarning() << "invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, int x)!" << endl;
00169 return false;
00170 }
00171 uint index(x);
00172 if (index == 0)
00173 m_layers.append(newLayer);
00174 else
00175 m_layers.insert(m_layers.begin() + reverseIndex(index) + 1, newLayer);
00176 for (uint i = childCount() - 1; i > index; i--)
00177 at(i)->m_index++;
00178 newLayer->m_parent = this;
00179 newLayer->m_index = index;
00180 newLayer->setImage(image());
00181 newLayer->setDirty(newLayer->extent());
00182 setDirty();
00183 return true;
00184 }
00185
00186 bool KisGroupLayer::addLayer(KisLayerSP newLayer, KisLayerSP aboveThis)
00187 {
00188 if (aboveThis && aboveThis->parent().data() != this)
00189 {
00190 kdWarning() << "invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, KisLayerSP aboveThis)!" << endl;
00191 return false;
00192 }
00193 return addLayer(newLayer, aboveThis ? aboveThis->index() : childCount());
00194 }
00195
00196 bool KisGroupLayer::removeLayer(int x)
00197 {
00198 if (x >= 0 && kClamp(uint(x), uint(0), childCount() - 1) == uint(x))
00199 {
00200 uint index(x);
00201 for (uint i = childCount() - 1; i > index; i--)
00202 at(i)->m_index--;
00203 KisLayerSP removedLayer = at(index);
00204
00205 removedLayer->m_parent = 0;
00206 removedLayer->m_index = -1;
00207 m_layers.erase(m_layers.begin() + reverseIndex(index));
00208 setDirty(removedLayer->extent());
00209 if (childCount() < 1) {
00210
00211 m_projection->clear();
00212 setDirty();
00213 }
00214 return true;
00215 }
00216 kdWarning() << "invalid input to KisGroupLayer::removeLayer()!" << endl;
00217 return false;
00218 }
00219
00220 bool KisGroupLayer::removeLayer(KisLayerSP layer)
00221 {
00222 if (layer->parent().data() != this)
00223 {
00224 kdWarning() << "invalid input to KisGroupLayer::removeLayer()!" << endl;
00225 return false;
00226 }
00227
00228 return removeLayer(layer->index());
00229 }
00230
00231 void KisGroupLayer::setImage(KisImage *image)
00232 {
00233 super::setImage(image);
00234 for (vKisLayerSP_it it = m_layers.begin(); it != m_layers.end(); ++it)
00235 {
00236 (*it)->setImage(image);
00237 }
00238 }
00239
00240 QRect KisGroupLayer::extent() const
00241 {
00242 QRect groupExtent;
00243
00244 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00245 {
00246 groupExtent |= (*it)->extent();
00247 }
00248
00249 return groupExtent;
00250 }
00251
00252 QRect KisGroupLayer::exactBounds() const
00253 {
00254 QRect groupExactBounds;
00255
00256 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00257 {
00258 groupExactBounds |= (*it)->exactBounds();
00259 }
00260
00261 return groupExactBounds;
00262 }
00263
00264 Q_INT32 KisGroupLayer::x() const
00265 {
00266 return m_x;
00267 }
00268
00269 void KisGroupLayer::setX(Q_INT32 x)
00270 {
00271 Q_INT32 delta = x - m_x;
00272
00273 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00274 {
00275 KisLayerSP layer = *it;
00276 layer->setX(layer->x() + delta);
00277 }
00278 m_x = x;
00279 }
00280
00281 Q_INT32 KisGroupLayer::y() const
00282 {
00283 return m_y;
00284 }
00285
00286 void KisGroupLayer::setY(Q_INT32 y)
00287 {
00288 Q_INT32 delta = y - m_y;
00289
00290 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
00291 {
00292 KisLayerSP layer = *it;
00293 layer->setY(layer->y() + delta);
00294 }
00295
00296 m_y = y;
00297 }
00298
00299 QImage KisGroupLayer::createThumbnail(Q_INT32 w, Q_INT32 h)
00300 {
00301 return m_projection->createThumbnail(w, h);
00302 }
00303
00304 void KisGroupLayer::updateProjection(const QRect & rc)
00305 {
00306 if (!m_dirtyRect.isValid()) return;
00307
00308
00309 KisLayerSP child = lastChild();
00310
00311
00312 if (!child) m_projection->clear();
00313
00314 KisLayerSP startWith = 0;
00315 KisAdjustmentLayerSP adjLayer = 0;
00316 KisLayerSP tmpPaintLayer = 0;
00317
00318
00319
00320 bool gotPaintLayer = (parent() != 0);
00321
00322
00323
00324
00325 while (child) {
00326 KisAdjustmentLayerSP tmpAdjLayer = dynamic_cast<KisAdjustmentLayer*>(child.data());
00327 if (tmpAdjLayer) {
00328 if (gotPaintLayer) {
00329
00330
00331 if (tmpAdjLayer->dirty(rc) && adjLayer != 0 && adjLayer->visible()) {
00332 startWith = adjLayer->prevSibling();
00333 break;
00334 }
00335 else if (tmpAdjLayer->visible() && !tmpAdjLayer->dirty(rc)) {
00336
00337 adjLayer = tmpAdjLayer;
00338 }
00339 else {
00340 startWith = tmpPaintLayer;
00341 }
00342 }
00343 }
00344 else {
00345 tmpPaintLayer = child;
00346 gotPaintLayer = true;
00347
00348
00349 if (child->dirty(rc)) {
00350 if (adjLayer != 0 && adjLayer->visible()) {
00351
00352 startWith = adjLayer->prevSibling();
00353 }
00354 else {
00355 startWith = child;
00356 }
00357
00358 break;
00359 }
00360 }
00361 child = child->prevSibling();
00362 }
00363
00364 if (adjLayer != 0 && startWith == 0 && gotPaintLayer && adjLayer->prevSibling()) {
00365 startWith = adjLayer->prevSibling();
00366 }
00367
00368
00369 if (adjLayer == 0) {
00370 startWith = lastChild();
00371 }
00372
00373 if (startWith == 0) {
00374 return;
00375 }
00376
00377 bool first = true;
00378
00379
00380 KisFillPainter gc(m_projection);
00381 if (adjLayer != 0) {
00382 gc.bitBlt(rc.left(), rc.top(),
00383 COMPOSITE_COPY, adjLayer->cachedPaintDevice(), OPACITY_OPAQUE,
00384 rc.left(), rc.top(), rc.width(), rc.height());
00385 first = false;
00386 }
00387 else {
00388 gc.eraseRect(rc);
00389 first = true;
00390 }
00391 gc.end();
00392
00393 KisMergeVisitor visitor(m_projection, rc);
00394
00395 child = startWith;
00396
00397 while(child)
00398 {
00399 if(first)
00400 {
00401
00402
00403
00404 const KisCompositeOp cop = child->compositeOp();
00405 const bool block = child->signalsBlocked();
00406 child->blockSignals(true);
00407
00408
00409 KisPaintLayer* l = dynamic_cast<KisPaintLayer*>(child.data());
00410 if (l && l->hasMask())
00411 child->m_compositeOp = COMPOSITE_OVER;
00412 else
00413 child->m_compositeOp = COMPOSITE_COPY;
00414 child->blockSignals(block);
00415 child->accept(visitor);
00416 child->blockSignals(true);
00417 child->m_compositeOp = cop;
00418 child->blockSignals(block);
00419 first = false;
00420 }
00421 else
00422 child->accept(visitor);
00423
00424 child = child->prevSibling();
00425 }
00426 }
00427
00428 #include "kis_group_layer.moc"