00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qevent.h>
00022 #include <qlabel.h>
00023 #include <qlayout.h>
00024 #include <qwidget.h>
00025 #include <qrect.h>
00026
00027 #include <kdebug.h>
00028 #include <kaction.h>
00029 #include <kcommand.h>
00030 #include <klocale.h>
00031
00032 #include "kis_canvas_subject.h"
00033 #include "kis_undo_adapter.h"
00034 #include "kis_selection.h"
00035 #include "kis_painter.h"
00036 #include "kis_fill_painter.h"
00037 #include "kis_tool_freehand.h"
00038 #include "kis_cursor.h"
00039 #include "kis_button_press_event.h"
00040 #include "kis_button_release_event.h"
00041 #include "kis_move_event.h"
00042 #include "kis_layer.h"
00043 #include "kis_group_layer.h"
00044 #include "kis_paint_layer.h"
00045 #include "kis_canvas.h"
00046 #include "kis_canvas_painter.h"
00047 #include "kis_boundary_painter.h"
00048 #include "kis_brush.h"
00049
00050 KisToolFreehand::KisToolFreehand(QString transactionText)
00051 : super(transactionText),
00052 m_dragDist ( 0 ),
00053 m_transactionText(transactionText),
00054 m_mode( HOVER )
00055 {
00056 m_painter = 0;
00057 m_currentImage = 0;
00058 m_tempLayer = 0;
00059 m_paintIncremental = true;
00060 m_paintOnSelection = false;
00061 m_paintedOutline = false;
00062 }
00063
00064 KisToolFreehand::~KisToolFreehand()
00065 {
00066 }
00067
00068 void KisToolFreehand::update(KisCanvasSubject *subject)
00069 {
00070 super::update(subject);
00071 m_currentImage = m_subject->currentImg();
00072 }
00073
00074 void KisToolFreehand::buttonPress(KisButtonPressEvent *e)
00075 {
00076 if (!m_subject) return;
00077
00078 if (!m_subject->currentBrush()) return;
00079
00080 if (!m_currentImage || !m_currentImage->activeDevice()) return;
00081
00082 if (e->button() == QMouseEvent::LeftButton) {
00083
00084 m_currentImage->activeDevice()->lock( true );
00085 kdDebug() << ">>>>>>>>>>>>>>>>>>>Locking paint device\n";
00086
00087
00088
00089
00090
00091
00092 initPaint(e);
00093 paintAt(e->pos(), e->pressure(), e->xTilt(), e->yTilt());
00094
00095 m_prevPos = e->pos();
00096 m_prevPressure = e->pressure();
00097 m_prevXTilt = e->xTilt();
00098 m_prevYTilt = e->yTilt();
00099
00100 QRect r = m_painter->dirtyRect();
00101 if ( r.isValid() ) {
00102 m_dirtyRect = r;
00103
00104 r = QRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2);
00105 if (!m_paintOnSelection) {
00106 m_currentImage->activeLayer()->setDirty(r);
00107 }
00108 else {
00109 m_target->setDirty(r);
00110
00111 m_subject->canvasController()->updateCanvas( r );
00112 }
00113 }
00114 }
00115 }
00116
00117 void KisToolFreehand::buttonRelease(KisButtonReleaseEvent* e)
00118 {
00119 if (e->button() == QMouseEvent::LeftButton && m_mode == PAINT) {
00120 endPaint();
00121 m_currentImage->activeDevice()->lock( false );
00122 kdDebug() << ">>>>>>>>>>>>>>>>>>>UNLocking paint device\n";
00123
00124 }
00125 KisToolPaint::buttonRelease(e);
00126 }
00127
00128 void KisToolFreehand::move(KisMoveEvent *e)
00129 {
00130 if (m_mode == PAINT) {
00131
00132 paintLine(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt, e->pos(), e->pressure(), e->xTilt(), e->yTilt());
00133
00134 m_prevPos = e->pos();
00135 m_prevPressure = e->pressure();
00136 m_prevXTilt = e->xTilt();
00137 m_prevYTilt = e->yTilt();
00138
00139 QRect r = m_painter->dirtyRect();
00140
00141 if (r.isValid()) {
00142 m_dirtyRect |= r;
00143
00144 if (!m_paintOnSelection) {
00145 m_currentImage->activeLayer()->setDirty(r);
00146 }
00147 else {
00148
00149 r = QRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2);
00150 m_target->setDirty(r);
00151 m_subject->canvasController()->updateCanvas( r );
00152 }
00153 }
00154 }
00155 }
00156
00157 void KisToolFreehand::initPaint(KisEvent *)
00158 {
00159 if (!m_currentImage || !m_currentImage->activeDevice()) return;
00160
00161 m_mode = PAINT;
00162 m_dragDist = 0;
00163
00164
00165 KisPaintDeviceSP device;
00166 if (m_currentImage && (device = m_currentImage->activeDevice())) {
00167
00168 if (m_painter)
00169 delete m_painter;
00170
00171 if (!m_paintIncremental) {
00172 if (m_currentImage->undo())
00173 m_currentImage->undoAdapter()->beginMacro(m_transactionText);
00174
00175 KisLayerSupportsIndirectPainting* layer;
00176 if ((layer = dynamic_cast<KisLayerSupportsIndirectPainting*>(
00177 m_currentImage->activeLayer().data()))) {
00178
00179
00180
00181
00182
00183 KisLayer* l = layer->layer();
00184 KisPaintLayer* pl = dynamic_cast<KisPaintLayer*>(l);
00185 if (l->parent() && (l->parent()->parent() == 0)
00186 && (l->parent()->childCount() == 1)
00187 && l->parent()->paintLayerInducesProjectionOptimization(pl)) {
00188
00189
00190 l->parent()->resetProjection(pl->paintDevice());
00191 }
00192
00193 m_target = new KisPaintDevice(m_currentImage->activeLayer(),
00194 device->colorSpace());
00195 layer->setTemporaryTarget(m_target);
00196 layer->setTemporaryCompositeOp(m_compositeOp);
00197 layer->setTemporaryOpacity(m_opacity);
00198
00199 if (device->hasSelection())
00200 m_target->setSelection(device->selection());
00201 }
00202 } else {
00203 m_target = device;
00204 }
00205 if(m_target->hasSelection()) m_target->selection()->startCachingExactRect();
00206 m_painter = new KisPainter( m_target );
00207 Q_CHECK_PTR(m_painter);
00208 m_source = device;
00209 if (currentImage()->undo()) m_painter->beginTransaction(m_transactionText);
00210 }
00211
00212 m_painter->setPaintColor(m_subject->fgColor());
00213 m_painter->setBackgroundColor(m_subject->bgColor());
00214 m_painter->setBrush(m_subject->currentBrush());
00215
00216
00217
00218 if (m_paintIncremental) {
00219 m_painter->setCompositeOp(m_compositeOp);
00220 m_painter->setOpacity(m_opacity);
00221 } else {
00222 m_painter->setCompositeOp(COMPOSITE_ALPHA_DARKEN);
00223 m_painter->setOpacity( OPACITY_OPAQUE );
00224
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 }
00236
00237 void KisToolFreehand::endPaint()
00238 {
00239 m_mode = HOVER;
00240 if (m_currentImage) {
00241
00242 if (m_painter) {
00243
00244
00245 if (!m_paintIncremental) {
00246 if (m_currentImage->undo())
00247 m_painter->endTransaction();
00248 KisPainter painter( m_source );
00249 painter.setCompositeOp(m_compositeOp);
00250 if (m_currentImage->undo())
00251 painter.beginTransaction(m_transactionText);
00252 painter.bitBlt(m_dirtyRect.x(), m_dirtyRect.y(), m_compositeOp, m_target,
00253 m_opacity,
00254 m_dirtyRect.x(), m_dirtyRect.y(),
00255 m_dirtyRect.width(), m_dirtyRect.height());
00256
00257 KisLayerSupportsIndirectPainting* layer =
00258 dynamic_cast<KisLayerSupportsIndirectPainting*>(m_source->parentLayer());
00259 layer->setTemporaryTarget(0);
00260 m_source->parentLayer()->setDirty(m_dirtyRect);
00261
00262 if (m_currentImage->undo()) {
00263 m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
00264 m_currentImage->undoAdapter()->endMacro();
00265 }
00266 } else {
00267 if (m_currentImage->undo())
00268 m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction());
00269 }
00270 }
00271 delete m_painter;
00272 m_painter = 0;
00273 notifyModified();
00274 if(m_target->hasSelection()) m_target->selection()->stopCachingExactRect();
00275 }
00276 }
00277
00278 void KisToolFreehand::paintAt(const KisPoint &pos,
00279 const double pressure,
00280 const double xTilt,
00281 const double yTilt)
00282 {
00283 painter()->paintAt(pos, pressure, xTilt, yTilt);
00284 }
00285
00286 void KisToolFreehand::paintLine(const KisPoint & pos1,
00287 const double pressure1,
00288 const double xtilt1,
00289 const double ytilt1,
00290 const KisPoint & pos2,
00291 const double pressure2,
00292 const double xtilt2,
00293 const double ytilt2)
00294 {
00295 m_dragDist = painter()->paintLine(pos1, pressure1, xtilt1, ytilt1, pos2, pressure2, xtilt2, ytilt2, m_dragDist);
00296 }
00297
00298
00299 KisImageSP KisToolFreehand::currentImage()
00300 {
00301 return m_currentImage;
00302 }
00303
00304
00305 void KisToolFreehand::paintOutline(const KisPoint& point) {
00306 if (!m_subject) {
00307 return;
00308 }
00309
00310 KisCanvasController *controller = m_subject->canvasController();
00311
00312 if (currentImage() && !currentImage()->bounds().contains(point.floorQPoint())) {
00313 if (m_paintedOutline) {
00314 controller->kiscanvas()->update();
00315 m_paintedOutline = false;
00316 }
00317 return;
00318 }
00319
00320 KisCanvas *canvas = controller->kiscanvas();
00321 canvas->repaint();
00322
00323 KisBrush *brush = m_subject->currentBrush();
00324
00325 if (brush) {
00326 KisCanvasPainter gc(canvas);
00327 QPen pen(Qt::SolidLine);
00328
00329 KisPoint hotSpot = brush->hotSpot();
00330
00331 gc.setRasterOp(Qt::NotROP);
00332 gc.setPen(pen);
00333 gc.setViewport(0, 0, static_cast<Q_INT32>(canvas->width() * m_subject->zoomFactor()),
00334 static_cast<Q_INT32>(canvas->height() * m_subject->zoomFactor()));
00335 gc.translate((- controller->horzValue()) / m_subject->zoomFactor(),
00336 (- controller->vertValue()) / m_subject->zoomFactor());
00337
00338 KisPoint topLeft = point - hotSpot;
00339
00340 if (m_subject->currentPaintop().id() == "pen") {
00341
00342 topLeft = topLeft.roundQPoint();
00343 }
00344
00345 gc.translate(topLeft.x(), topLeft.y());
00346
00347 KisBoundaryPainter::paint(brush->boundary(), gc);
00348 m_paintedOutline = true;
00349 }
00350 }
00351
00352
00353 #include "kis_tool_freehand.moc"
00354