26#include "kis_paint_device.h"
27#include "kis_layer_visitor.h"
28#include "kis_painter.h"
31#include "kis_group_layer.h"
32#include "kis_adjustment_layer.h"
33#include "kis_paint_layer.h"
34#include "kis_part_layer_iface.h"
35#include "kis_filter.h"
36#include "kis_filter_configuration.h"
37#include "kis_filter_registry.h"
38#include "kis_selection.h"
39#include "kis_transaction.h"
40#include "kis_iterators_pixel.h"
42class KisMergeVisitor :
public KisLayerVisitor {
48 KisMergeVisitor(KisPaintDeviceSP projection,
const TQRect& rc) :
53 m_projection = projection;
59 template<
class Target>
60 TDESharedPtr<Target> paintIndirect(KisPaintDeviceSP source,
61 TDESharedPtr<Target> target,
62 KisLayerSupportsIndirectPainting* layer,
63 TQ_INT32 sx, TQ_INT32 sy, TQ_INT32 dx, TQ_INT32 dy,
64 TQ_INT32 w, TQ_INT32 h) {
65 KisPainter gc2(target.data());
66 gc2.bitBlt(dx, dy, COMPOSITE_COPY, source,
67 OPACITY_OPAQUE, sx, sy, w, h);
68 gc2.bitBlt(dx, dy, layer->temporaryCompositeOp(), layer->temporaryTarget(),
69 layer->temporaryOpacity(), sx, sy, w, h);
75 virtual bool visit(KisPaintLayer *layer)
78 if (m_projection == 0) {
82 kdDebug(41010) <<
"Visiting on paint layer " << layer->name() <<
", visible: " << layer->visible()
83 <<
", temporary: " << layer->temporary() <<
", extent: "
84 << layer->
extent() <<
", dirty: " << layer->dirtyRect() <<
", paint rect: " << m_rc << endl;
85 if (!layer->visible())
88 TQ_INT32 sx, sy, dx, dy, w, h;
90 TQRect rc = layer->paintDevice()->extent() & m_rc;
93 KisPaintDeviceSP tempTarget = layer->temporaryTarget();
95 rc = (layer->paintDevice()->extent() | tempTarget->extent()) & m_rc;
105 KisPainter gc(m_projection);
106 KisPaintDeviceSP source = layer->paintDevice();
110 KisPaintDeviceSP temp =
new KisPaintDevice(source->colorSpace());
111 source = paintIndirect(source, temp, layer, sx, sy, dx, dy, w, h);
114 gc.bitBlt(dx, dy, layer->compositeOp(), source, layer->opacity(), sx, sy, w, h);
134 KisPaintDeviceSP mask = layer->
getMask();
135 TQRect mextent = mask->extent();
136 if ((mextent & m_rc) != m_rc) {
142 KisRectIteratorPixel it = mask->createRectIterator(sx, sy, w, h,
true);
147 KisPaintDeviceSP temp =
new KisPaintDevice(source->colorSpace());
148 mask = paintIndirect(mask, temp, layer, sx, sy, dx, dy, w, h);
151 gc.bitBlt(dx, dy, COMPOSITE_OVER, mask, OPACITY_OPAQUE, sx, sy, w, h);
155 if (tempTarget && layer->
editMask()) {
156 KisPaintDeviceSP maskSrc = layer->
getMask();
157 KisPaintDeviceSP temp =
new KisPaintDevice(maskSrc->colorSpace());
158 temp = paintIndirect(maskSrc, temp, layer, sx, sy, dx, dy, w, h);
160 KisRectIteratorPixel srcIt = temp->createRectIterator(sx, sy, w, h,
false);
161 KisRectIteratorPixel dstIt = mask->createRectIterator(sx, sy, w, h,
true);
169 }
else if (tempTarget) {
171 KisPaintDeviceSP temp =
new KisPaintDevice(source->colorSpace());
172 source = paintIndirect(source, temp, layer, sx, sy, dx, dy, w, h);
175 gc.bltSelection(dx, dy,
176 layer->compositeOp(),
179 layer->opacity(), sx, sy, w, h);
187 virtual bool visit(KisGroupLayer *layer)
190 if (m_projection == 0) {
194 kdDebug(41010) <<
"Visiting on group layer " << layer->name() <<
", visible: " << layer->visible() <<
", extent: "
195 << layer->
extent() <<
", dirty: " << layer->dirtyRect() <<
", paint rect: " << m_rc << endl;
197 if (!layer->visible())
200 TQ_INT32 sx, sy, dx, dy, w, h;
203 KisPaintDeviceSP dev = layer->
projection(m_rc);
204 TQRect rc = dev->extent() & m_rc;
213 KisPainter gc(m_projection);
214 gc.bitBlt(dx, dy, layer->compositeOp(), dev, layer->opacity(), sx, sy, w, h);
219 virtual bool visit(KisPartLayer* layer)
222 kdDebug(41010) <<
"Visiting on part layer " << layer->name() <<
", visible: " << layer->visible() <<
", extent: "
223 << layer->
extent() <<
", dirty: " << layer->dirtyRect() <<
", paint rect: " << m_rc << endl;
225 if (m_projection == 0) {
228 if (!layer->visible())
231 KisPaintDeviceSP dev(layer->prepareProjection(m_projection, m_rc));
235 TQ_INT32 sx, sy, dx, dy, w, h;
237 TQRect rc = dev->extent() & m_rc;
246 KisPainter gc(m_projection);
247 gc.bitBlt(dx, dy, layer->compositeOp() , dev, layer->opacity(), sx, sy, w, h);
253 virtual bool visit(KisAdjustmentLayer* layer)
255 kdDebug(41010) <<
"Visiting on adjustment layer " << layer->name() <<
", visible: " << layer->visible() <<
", extent: "
256 << layer->
extent() <<
", dirty: " << layer->dirtyRect() <<
", paint rect: " << m_rc << endl;
258 if (m_projection == 0) {
262 if (!layer->visible())
265 KisPaintDeviceSP tempTarget = layer->temporaryTarget();
267 m_rc = (layer->
extent() | tempTarget->extent()) & m_rc;
270 if (m_rc.width() == 0 || m_rc.height() == 0)
273 KisFilterConfiguration * cfg = layer->filter();
274 if (!cfg)
return false;
277 KisFilter * f = KisFilterRegistry::instance()->
get( cfg->
name() );
278 if (!f)
return false;
282 KisSelectionSP selection = layer->selection();
286 KisPaintDeviceSP tmp = 0;
287 KisSelectionSP sel = selection;
289 if (selection != 0) {
290 tmp =
new KisPaintDevice(m_projection->colorSpace());
293 TQRect selectedRect = selection->selectedRect();
294 selectedRect &= m_rc;
296 if (selectedRect.width() == 0 || selectedRect.height() == 0)
303 tmp->setX(selection->getX());
304 tmp->setY(selection->getY());
308 sel =
new KisSelection();
309 sel = paintIndirect(selection.data(), sel, layer, m_rc.left(), m_rc.top(),
310 m_rc.left(), m_rc.top(), m_rc.width(), m_rc.height());
313 gc.bitBlt(selectedRect.x(), selectedRect.y(), COMPOSITE_COPY, m_projection,
314 selectedRect.x(), selectedRect.y(),
315 selectedRect.width(), selectedRect.height());
318 tmp =
new KisPaintDevice(*m_projection);
323 KisTransaction* cmd =
new KisTransaction(
"", tmp);
327 f->process(tmp, tmp, cfg, m_rc);
332 KisPainter gc(m_projection);
334 gc.bltSelection(m_rc.left(), m_rc.top(),
335 COMPOSITE_OVER, tmp, sel, layer->opacity(),
336 m_rc.left(), m_rc.top(), m_rc.width(), m_rc.height());
338 gc.bitBlt(m_rc.left(), m_rc.top(),
339 COMPOSITE_OVER, tmp, layer->opacity(),
340 m_rc.left(), m_rc.top(), m_rc.width(), m_rc.height());
344 gc.begin(layer->cachedPaintDevice());
345 gc.bitBlt(m_rc.left(), m_rc.top(),
346 COMPOSITE_COPY, m_projection, OPACITY_OPAQUE,
347 m_rc.left(), m_rc.top(), m_rc.width(), m_rc.height());
353 KisPaintDeviceSP m_projection;
virtual TQRect extent() const
Returns an approximation of where the bounds on actual data are in this layer.
const TQString & name() const
Get the unique, language independent name of the filter.
_T get(const KisID &name) const
This function allow to get an object from its KisID.
virtual KisPaintDeviceSP projection(const TQRect &rect)
will copy from to, if !0, CoW!!
virtual TQRect extent() const
Returns an approximation of where the bounds on actual data are in this layer.
virtual void setClean(const TQRect &rect)
Set the specified rect to clean.
virtual TQRect extent() const =0
Returns an approximation of where the bounds on actual data are in this layer.
virtual TQRect extent() const
Returns an approximation of where the bounds on actual data are in this layer.
KisPaintDeviceSP getMask()
Returns the layer mask's device. Creates one if there is currently none.
bool editMask() const
When this returns true, the KisPaintDevice returned in paintDevice will actually be the layer mask (i...
KisSelectionSP getMaskAsSelection()
Returns the layer mask's device, converted to a selection. Creates one if there is currently none.
bool renderMask() const
Returns true if the masked part of the mask will be rendered instead of being transparent.
bool hasMask() const
Does this layer have a layer mask?
TQ_UINT8 * rawData() const
returns a pointer to the pixel data. Do NOT interpret the data - leave that to a colorstrategy
bool isDone() const
returns true when iterators has reached the end