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
00085 if (!m_currentImage->bounds().contains(e->pos().floorQPoint())) return;
00086
00087 initPaint(e);
00088 paintAt(e->pos(), e->pressure(), e->xTilt(), e->yTilt());
00089
00090 m_prevPos = e->pos();
00091 m_prevPressure = e->pressure();
00092 m_prevXTilt = e->xTilt();
00093 m_prevYTilt = e->yTilt();
00094
00095 QRect r = m_painter->dirtyRect();
00096 if ( r.isValid() ) {
00097 m_dirtyRect = r;
00098
00099 r = QRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2);
00100 if (!m_paintOnSelection) {
00101 if (!m_paintIncremental) {
00102 m_tempLayer->setDirty(r);
00103 }
00104 else {
00105 m_currentImage->activeLayer()->setDirty(r);
00106 }
00107 }
00108 else {
00109
00110 m_subject->canvasController()->updateCanvas( r );
00111 }
00112 }
00113 }
00114 }
00115
00116 void KisToolFreehand::buttonRelease(KisButtonReleaseEvent* e)
00117 {
00118 if (e->button() == QMouseEvent::LeftButton && m_mode == PAINT) {
00119 endPaint();
00120 }
00121 }
00122
00123 void KisToolFreehand::move(KisMoveEvent *e)
00124 {
00125 if (m_mode == PAINT) {
00126
00127 paintLine(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt, e->pos(), e->pressure(), e->xTilt(), e->yTilt());
00128
00129 m_prevPos = e->pos();
00130 m_prevPressure = e->pressure();
00131 m_prevXTilt = e->xTilt();
00132 m_prevYTilt = e->yTilt();
00133
00134 QRect r = m_painter->dirtyRect();
00135
00136 if (r.isValid()) {
00137 m_dirtyRect |= r;
00138
00139 if (!m_paintOnSelection) {
00140 if (!m_paintIncremental) {
00141 m_tempLayer->setDirty(r);
00142 }
00143 else {
00144 m_currentImage->activeLayer()->setDirty(r);
00145 }
00146 }
00147 else {
00148
00149 r = QRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2);
00150 m_subject->canvasController()->updateCanvas( r );
00151 }
00152 }
00153 }
00154 }
00155
00156 void KisToolFreehand::initPaint(KisEvent *)
00157 {
00158 if (!m_currentImage || !m_currentImage->activeDevice()) return;
00159
00160 m_mode = PAINT;
00161 m_dragDist = 0;
00162
00163
00164 KisPaintDeviceSP device;
00165 if (m_currentImage && (device = m_currentImage->activeDevice())) {
00166
00167 if (m_painter)
00168 delete m_painter;
00169
00170 if (!m_paintIncremental) {
00171 if (m_currentImage->undo())
00172 m_currentImage->undoAdapter()->beginMacro(m_transactionText);
00173
00174
00175
00176
00177 m_tempLayer = new KisPaintLayer(m_currentImage, "temp", OPACITY_OPAQUE);
00178 m_tempLayer->setTemporary(true);
00179
00180 m_target = (dynamic_cast<KisPaintLayer*>(m_tempLayer.data()))->paintDevice();
00181
00182
00183 m_tempLayer->setCompositeOp( m_compositeOp );
00184 m_tempLayer->setOpacity( m_opacity );
00185
00186 m_tempLayer->setVisible(true);
00187
00188 currentImage()->addLayer(m_tempLayer, m_currentImage->activeLayer()->parent().data(), m_currentImage->activeLayer());
00189
00190 } else {
00191 m_target = device;
00192 }
00193 m_painter = new KisPainter( m_target );
00194 Q_CHECK_PTR(m_painter);
00195 m_source = device;
00196 if (currentImage()->undo()) m_painter->beginTransaction(m_transactionText);
00197 }
00198
00199 m_painter->setPaintColor(m_subject->fgColor());
00200 m_painter->setBackgroundColor(m_subject->bgColor());
00201 m_painter->setBrush(m_subject->currentBrush());
00202
00203
00204
00205 if (m_paintIncremental) {
00206 m_painter->setCompositeOp(m_compositeOp);
00207 m_painter->setOpacity(m_opacity);
00208 } else {
00209 m_painter->setCompositeOp(COMPOSITE_OVER);
00210 m_painter->setOpacity( OPACITY_OPAQUE );
00211
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 }
00223
00224 void KisToolFreehand::endPaint()
00225 {
00226 m_mode = HOVER;
00227 if (m_currentImage) {
00228
00229 if (m_painter) {
00230
00231
00232 if (!m_paintIncremental) {
00233 if (m_currentImage->undo()) m_painter->endTransaction();
00234 KisPainter painter( m_source );
00235 painter.setCompositeOp(m_compositeOp);
00236 if (m_currentImage->undo()) painter.beginTransaction(m_transactionText);
00237 painter.bitBlt(m_dirtyRect.x(), m_dirtyRect.y(), m_compositeOp, m_target, m_opacity,
00238 m_dirtyRect.x(), m_dirtyRect.y(), m_dirtyRect.width(), m_dirtyRect.height());
00239
00240 if (m_currentImage->undo()) m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
00241 m_currentImage->removeLayer(m_tempLayer);
00242
00243
00244
00245
00246
00247
00248 if (m_currentImage->undo()) m_currentImage->undoAdapter()->endMacro();
00249 } else {
00250 if (m_currentImage->undo()) m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction());
00251 }
00252 }
00253 delete m_painter;
00254 m_painter = 0;
00255 notifyModified();
00256 }
00257 }
00258
00259 void KisToolFreehand::paintAt(const KisPoint &pos,
00260 const double pressure,
00261 const double xTilt,
00262 const double yTilt)
00263 {
00264 painter()->paintAt(pos, pressure, xTilt, yTilt);
00265 }
00266
00267 void KisToolFreehand::paintLine(const KisPoint & pos1,
00268 const double pressure1,
00269 const double xtilt1,
00270 const double ytilt1,
00271 const KisPoint & pos2,
00272 const double pressure2,
00273 const double xtilt2,
00274 const double ytilt2)
00275 {
00276 m_dragDist = painter()->paintLine(pos1, pressure1, xtilt1, ytilt1, pos2, pressure2, xtilt2, ytilt2, m_dragDist);
00277 }
00278
00279
00280 KisImageSP KisToolFreehand::currentImage()
00281 {
00282 return m_currentImage;
00283 }
00284
00285
00286 void KisToolFreehand::paintOutline(const KisPoint& point) {
00287 if (!m_subject) {
00288 return;
00289 }
00290
00291 KisCanvasController *controller = m_subject->canvasController();
00292
00293 if (currentImage() && !currentImage()->bounds().contains(point.floorQPoint())) {
00294 if (m_paintedOutline) {
00295 controller->kiscanvas()->update();
00296 m_paintedOutline = false;
00297 }
00298 return;
00299 }
00300
00301 KisCanvas *canvas = controller->kiscanvas();
00302 canvas->repaint();
00303
00304 KisBrush *brush = m_subject->currentBrush();
00305
00306 if (brush) {
00307 KisCanvasPainter gc(canvas);
00308 QPen pen(Qt::SolidLine);
00309
00310 KisPoint hotSpot = brush->hotSpot();
00311
00312 gc.setRasterOp(Qt::NotROP);
00313 gc.setPen(pen);
00314 gc.setViewport(0, 0, static_cast<Q_INT32>(canvas->width() * m_subject->zoomFactor()),
00315 static_cast<Q_INT32>(canvas->height() * m_subject->zoomFactor()));
00316 gc.translate((- controller->horzValue()) / m_subject->zoomFactor(),
00317 (- controller->vertValue()) / m_subject->zoomFactor());
00318
00319 KisPoint topLeft = point - hotSpot;
00320
00321 if (m_subject->currentPaintop().id() == "pen") {
00322
00323 topLeft = topLeft.roundQPoint();
00324 }
00325
00326 gc.translate(topLeft.x(), topLeft.y());
00327
00328 KisBoundaryPainter::paint(brush->boundary(), gc);
00329 m_paintedOutline = true;
00330 }
00331 }
00332
00333
00334 #include "kis_tool_freehand.moc"
00335