22#include <tqdatetime.h>
26#include "kis_group_layer.h"
27#include "kis_layer_visitor.h"
28#include "kis_debug_areas.h"
30#include "kis_paint_device.h"
31#include "kis_merge_visitor.h"
32#include "kis_fill_painter.h"
34KisGroupLayer::KisGroupLayer(KisImage *img,
const TQString &name, TQ_UINT8 opacity) :
35 super(img, name, opacity),
39 m_projection =
new KisPaintDevice(
this, img->colorSpace(), name.latin1());
47 for(vKisLayerSP_cit it = rhs.m_layers.begin(); it != rhs.m_layers.end(); ++it)
49 this->addLayer(it->data()->clone(), 0);
52 m_projection->setParentLayer(
this);
60KisGroupLayer::~KisGroupLayer()
69 if (propagate) emit (sigDirty(m_dirtyRect));
75 if (propagate) emit sigDirty(rc);
83 m_projection =
new KisPaintDevice(
this, image()->colorSpace(), name().latin1());
87 return l && l->paintDevice()->colorSpace() == m_image->colorSpace() && l->visible()
88 && l->opacity() == OPACITY_OPAQUE && !l->temporaryTarget() && !l->
hasMask();
100 return l->paintDevice();
108 if (!rect.intersects(m_dirtyRect)) {
117 const TQRect rc = m_dirtyRect;
119 updateProjection(rc);
127 return m_layers.count();
142 if (
childCount() && index >= 0 && kClamp(uint(index), uint(0),
childCount() - 1) == uint(index))
143 return m_layers.at(reverseIndex(index));
149 if (layer->parent().data() ==
this)
150 return layer->index();
156 if (layer->parent().data() !=
this)
165 if (x < 0 || kClamp(uint(x), uint(0),
childCount()) != uint(x) ||
166 newLayer->parent() || m_layers.contains(newLayer))
168 kdWarning() <<
"invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, int x)!" << endl;
173 m_layers.append(newLayer);
175 m_layers.insert(m_layers.begin() + reverseIndex(index) + 1, newLayer);
176 for (uint i =
childCount() - 1; i > index; i--)
178 newLayer->m_parent =
this;
179 newLayer->m_index = index;
180 newLayer->setImage(image());
181 newLayer->setDirty(newLayer->extent());
188 if (aboveThis && aboveThis->parent().data() !=
this)
190 kdWarning() <<
"invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, KisLayerSP aboveThis)!" << endl;
198 if (x >= 0 && kClamp(uint(x), uint(0),
childCount() - 1) == uint(x))
201 for (uint i =
childCount() - 1; i > index; i--)
203 KisLayerSP removedLayer =
at(index);
205 removedLayer->m_parent = 0;
206 removedLayer->m_index = -1;
207 m_layers.erase(m_layers.begin() + reverseIndex(index));
211 m_projection->clear();
216 kdWarning() <<
"invalid input to KisGroupLayer::removeLayer()!" << endl;
222 if (layer->parent().data() !=
this)
224 kdWarning() <<
"invalid input to KisGroupLayer::removeLayer()!" << endl;
231void KisGroupLayer::setImage(KisImage *image)
233 super::setImage(image);
234 for (vKisLayerSP_it it = m_layers.begin(); it != m_layers.end(); ++it)
236 (*it)->setImage(image);
244 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
246 groupExtent |= (*it)->extent();
254 TQRect groupExactBounds;
256 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
258 groupExactBounds |= (*it)->exactBounds();
261 return groupExactBounds;
264TQ_INT32 KisGroupLayer::x()
const
269void KisGroupLayer::setX(TQ_INT32 x)
271 TQ_INT32 delta = x - m_x;
273 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
275 KisLayerSP layer = *it;
276 layer->setX(layer->x() + delta);
281TQ_INT32 KisGroupLayer::y()
const
286void KisGroupLayer::setY(TQ_INT32 y)
288 TQ_INT32 delta = y - m_y;
290 for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
292 KisLayerSP layer = *it;
293 layer->setY(layer->y() + delta);
301 return m_projection->createThumbnail(w, h);
304void KisGroupLayer::updateProjection(
const TQRect & rc)
306 if (!m_dirtyRect.isValid())
return;
312 if (!child) m_projection->clear();
314 KisLayerSP startWith = 0;
315 KisAdjustmentLayerSP adjLayer = 0;
316 KisLayerSP tmpPaintLayer = 0;
320 bool gotPaintLayer = (
parent() != 0);
331 if (tmpAdjLayer->dirty(rc) && adjLayer != 0 && adjLayer->visible()) {
335 else if (tmpAdjLayer->visible() && !tmpAdjLayer->dirty(rc)) {
337 adjLayer = tmpAdjLayer;
340 startWith = tmpPaintLayer;
345 tmpPaintLayer = child;
346 gotPaintLayer =
true;
349 if (child->dirty(rc)) {
350 if (adjLayer != 0 && adjLayer->visible()) {
352 startWith = adjLayer->prevSibling();
361 child = child->prevSibling();
364 if (adjLayer != 0 && startWith == 0 && gotPaintLayer && adjLayer->prevSibling()) {
365 startWith = adjLayer->prevSibling();
373 if (startWith == 0) {
382 gc.bitBlt(rc.left(), rc.top(),
383 COMPOSITE_COPY, adjLayer->cachedPaintDevice(), OPACITY_OPAQUE,
384 rc.left(), rc.top(), rc.width(), rc.height());
393 KisMergeVisitor visitor(m_projection, rc);
404 const KisCompositeOp cop = child->compositeOp();
405 const bool block = child->signalsBlocked();
406 child->blockSignals(
true);
411 child->m_compositeOp = COMPOSITE_OVER;
413 child->m_compositeOp = COMPOSITE_COPY;
414 child->blockSignals(block);
415 child->accept(visitor);
416 child->blockSignals(
true);
417 child->m_compositeOp = cop;
418 child->blockSignals(block);
422 child->accept(visitor);
424 child = child->prevSibling();
428#include "kis_group_layer.moc"
Class that contains a KisFilter and optionally a KisSelection.
This painter can be used to fill paint devices in different ways.
A KisLayer that bundles child layers into a single layer.
virtual KisLayerSP firstChild() const
Returns the first child layer of this layer (if it supports that).
virtual KisPaintDeviceSP projection(const TQRect &rect)
will copy from to, if !0, CoW!!
virtual uint childCount() const
Returns how many direct child layers this layer has (not recursive).
virtual void resetProjection(KisPaintDevice *to=0)
virtual TQRect exactBounds() const
Returns the exact bounds of where the actual data resides in this layer.
virtual KisLayerSP clone() const
Return a copy of this layer.
virtual bool addLayer(KisLayerSP newLayer, int index)
Adds the layer to this group at the specified index.
virtual void setDirty(bool propagate=true)
Set the entire layer extent dirty; this percolates up to parent layers all the way to the root layer.
virtual KisLayerSP at(int index) const
Returns the layer at the specified index.
virtual KisLayerSP lastChild() const
Returns the last child layer of this layer (if it supports that).
virtual void setIndex(KisLayerSP layer, int index)
Moves the specified layer to the specified index in the group, if it's already a member of this group...
virtual TQRect extent() const
Returns an approximation of where the bounds on actual data are in this layer.
virtual bool removeLayer(int index)
Removes the layer at the specified index from the group.
virtual bool paintLayerInducesProjectionOptimization(KisPaintLayer *l)
Returns if the layer will induce the projection hack (if the only layer in this group)
virtual int index(KisLayerSP layer) const
Returns the index of the layer if it's in this group, or -1 otherwise.
virtual TQImage createThumbnail(TQ_INT32 w, TQ_INT32 h)
Returns a thumbnail in requested size.
virtual void setClean(const TQRect &rect)
Set the specified rect to clean.
virtual bool dirty()
If the layer has been changed and not been composited yet, this returns true.
virtual KisGroupLayerSP parent() const
Returns the parent layer of a layer.
virtual void setDirty(bool propagate=true)
Set the entire layer extent dirty; this percolates up to parent layers all the way to the root layer.
virtual KisLayerSP prevSibling() const
Returns the previous sibling of this layer in the parent's list.
A paint device contains the actual pixel data and offers methods to read and write pixels.
This layer is of a type that can be painted on.
bool hasMask() const
Does this layer have a layer mask?