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) {
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);
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;
106 KisPaintDeviceSP source = layer->paintDevice();
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);
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);
163 while(!dstIt.isDone()) {
165 *dstIt.rawData() = *srcIt.rawData();
169 }
else if (tempTarget) {
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);
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;
214 gc.bitBlt(dx, dy, layer->compositeOp(), dev, layer->opacity(), sx, sy, w, h);
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;
247 gc.bitBlt(dx, dy, layer->compositeOp() , dev, layer->opacity(), sx, sy, w, h);
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)
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) {
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());
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());
323 KisTransaction* cmd =
new KisTransaction(
"", tmp);
327 f->process(tmp, tmp, cfg, m_rc);
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;
Class that contains a KisFilter and optionally a KisSelection.
virtual TQRect extent() const
Returns an approximation of where the bounds on actual data are in this layer.
A KisFilterConfiguration is the serializable representation of the filter parameters.
const TQString & name() const
Get the unique, language independent name of the filter.
Basic interface of a Chalk filter.
A KisLayer that bundles child layers into a single layer.
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.
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.
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?
KisPainter contains the graphics primitives necessary to draw on a KisPaintDevice.
An interface for the Part Layer so that we can use it in core/, but can implement it in ui/.
KisSelection contains a byte-map representation of a layer, where the value of a byte signifies wheth...