00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef KIS_MERGE_H_
00020 #define KIS_MERGE_H_
00021
00022 #include <qrect.h>
00023
00024 #include "kis_types.h"
00025 #include "kis_paint_device.h"
00026 #include "kis_layer_visitor.h"
00027 #include "kis_painter.h"
00028 #include "kis_image.h"
00029 #include "kis_layer.h"
00030 #include "kis_group_layer.h"
00031 #include "kis_adjustment_layer.h"
00032 #include "kis_paint_layer.h"
00033 #include "kis_part_layer_iface.h"
00034 #include "kis_filter.h"
00035 #include "kis_filter_configuration.h"
00036 #include "kis_filter_registry.h"
00037 #include "kis_selection.h"
00038
00039 class KisMergeVisitor : public KisLayerVisitor {
00040 public:
00045 KisMergeVisitor(KisPaintDeviceSP projection, const QRect& rc) :
00046 KisLayerVisitor()
00047 {
00048 Q_ASSERT(projection);
00049
00050 m_projection = projection;
00051 m_rc = rc;
00052 }
00053
00054 public:
00055 virtual bool visit(KisPaintLayer *layer)
00056 {
00057
00058 if (m_projection == 0) {
00059 return false;
00060 }
00061
00062 kdDebug(41010) << "Visiting on paint layer " << layer->name() << ", visible: " << layer->visible()
00063 << ", temporary: " << layer->temporary() << ", extent: "
00064 << layer->extent() << ", dirty: " << layer->dirtyRect() << ", paint rect: " << m_rc << endl;
00065 if (!layer->visible())
00066 return true;
00067
00068 Q_INT32 sx, sy, dx, dy, w, h;
00069
00070 QRect rc = layer->paintDevice()->extent() & m_rc;
00071
00072 sx = rc.left();
00073 sy = rc.top();
00074 w = rc.width();
00075 h = rc.height();
00076 dx = sx;
00077 dy = sy;
00078
00079 KisPainter gc(m_projection);
00080 gc.bitBlt(dx, dy, layer->compositeOp(), layer->paintDevice(), layer->opacity(), sx, sy, w, h);
00081
00082 layer->setClean( rc );
00083 return true;
00084 }
00085
00086 virtual bool visit(KisGroupLayer *layer)
00087 {
00088
00089 if (m_projection == 0) {
00090 return false;
00091 }
00092
00093 kdDebug(41010) << "Visiting on group layer " << layer->name() << ", visible: " << layer->visible() << ", extent: "
00094 << layer->extent() << ", dirty: " << layer->dirtyRect() << ", paint rect: " << m_rc << endl;
00095
00096 if (!layer->visible())
00097 return true;
00098
00099 Q_INT32 sx, sy, dx, dy, w, h;
00100
00101
00102 KisPaintDeviceSP dev = layer->projection(m_rc);
00103 QRect rc = dev->extent() & m_rc;
00104
00105 sx = rc.left();
00106 sy = rc.top();
00107 w = rc.width();
00108 h = rc.height();
00109 dx = sx;
00110 dy = sy;
00111
00112 KisPainter gc(m_projection);
00113 gc.bitBlt(dx, dy, layer->compositeOp(), dev, layer->opacity(), sx, sy, w, h);
00114
00115 return true;
00116 }
00117
00118 virtual bool visit(KisPartLayer* layer)
00119 {
00120
00121 kdDebug(41010) << "Visiting on part layer " << layer->name() << ", visible: " << layer->visible() << ", extent: "
00122 << layer->extent() << ", dirty: " << layer->dirtyRect() << ", paint rect: " << m_rc << endl;
00123
00124 if (m_projection == 0) {
00125 return false;
00126 }
00127 if (!layer->visible())
00128 return true;
00129
00130 KisPaintDeviceSP dev(layer->prepareProjection(m_projection, m_rc));
00131 if (!dev)
00132 return true;
00133
00134 Q_INT32 sx, sy, dx, dy, w, h;
00135
00136 QRect rc = dev->extent() & m_rc;
00137
00138 sx= rc.left();
00139 sy = rc.top();
00140 w = rc.width();
00141 h = rc.height();
00142 dx = sx;
00143 dy = sy;
00144
00145 KisPainter gc(m_projection);
00146 gc.bitBlt(dx, dy, layer->compositeOp() , dev, layer->opacity(), sx, sy, w, h);
00147
00148 layer->setClean(rc);
00149 return true;
00150 }
00151
00152 virtual bool visit(KisAdjustmentLayer* layer)
00153 {
00154 kdDebug(41010) << "Visiting on adjustment layer " << layer->name() << ", visible: " << layer->visible() << ", extent: "
00155 << layer->extent() << ", dirty: " << layer->dirtyRect() << ", paint rect: " << m_rc << endl;
00156
00157 if (m_projection == 0) {
00158 return true;
00159 }
00160
00161 if (!layer->visible())
00162 return true;
00163
00164 KisFilterConfiguration * cfg = layer->filter();
00165 if (!cfg) return false;
00166
00167
00168 KisFilter * f = KisFilterRegistry::instance()->get( cfg->name() );
00169 if (!f) return false;
00170
00171 KisSelectionSP selection = layer->selection();
00172
00173
00174 KisPaintDeviceSP tmp = new KisPaintDevice(*m_projection);
00175
00176
00177 if (selection != 0) {
00178 tmp->setSelection(selection);
00179 }
00180
00181
00182
00183 f->process(tmp, tmp, cfg, m_rc);
00184
00185
00186 KisPainter gc(m_projection);
00187 if (selection)
00188 gc.bltSelection(m_rc.left(), m_rc.top(),
00189 COMPOSITE_OVER, tmp, selection, layer->opacity(),
00190 m_rc.left(), m_rc.top(), m_rc.width(), m_rc.height());
00191 else
00192 gc.bitBlt(m_rc.left(), m_rc.top(),
00193 COMPOSITE_OVER, tmp, layer->opacity(),
00194 m_rc.left(), m_rc.top(), m_rc.width(), m_rc.height());
00195 gc.end();
00196
00197
00198 gc.begin(layer->cachedPaintDevice());
00199 gc.bitBlt(m_rc.left(), m_rc.top(),
00200 COMPOSITE_COPY, m_projection, OPACITY_OPAQUE,
00201 m_rc.left(), m_rc.top(), m_rc.width(), m_rc.height());
00202
00203 layer->setClean(m_rc);
00204
00205 return true;
00206 }
00207
00208 private:
00209 KisPaintDeviceSP m_projection;
00210 QRect m_rc;
00211 };
00212
00213 #endif // KIS_MERGE_H_
00214