18 #include "brushtool.h"
25 #include "layervector.h"
28 #include "pencilsettings.h"
29 #include "colormanager.h"
30 #include "strokemanager.h"
31 #include "layermanager.h"
32 #include "scribblearea.h"
37 BrushTool::BrushTool( QObject *parent ) :
42 ToolType BrushTool::type()
47 void BrushTool::loadSettings()
49 m_enabledProperties[WIDTH] =
true;
50 m_enabledProperties[FEATHER] =
true;
51 m_enabledProperties[USEFEATHER] =
true;
52 m_enabledProperties[PRESSURE] =
true;
53 m_enabledProperties[INVISIBILITY] =
true;
54 m_enabledProperties[INTERPOLATION] =
true;
55 m_enabledProperties[ANTI_ALIASING] =
true;
57 QSettings settings( PENCIL2D, PENCIL2D );
59 properties.width = settings.value(
"brushWidth" ).toDouble();
60 properties.feather = settings.value(
"brushFeather", 15.0 ).toDouble();
61 properties.useFeather = settings.value(
"brushUseFeather",
true ).toBool();
62 properties.pressure = settings.value(
"brushPressure",
false ).toBool();
63 properties.invisibility = settings.value(
"brushInvisibility",
true).toBool();
64 properties.preserveAlpha = OFF;
65 properties.inpolLevel = 0;
68 if (properties.useFeather ==
true) {
69 properties.useAA = -1;
74 if ( properties.width <= 0 )
79 if ( std::isnan( properties.feather ) )
85 void BrushTool::setWidth(
const qreal width)
88 properties.width = width;
91 QSettings settings( PENCIL2D, PENCIL2D );
92 settings.setValue(
"brushWidth", width);
96 void BrushTool::setUseFeather(
const bool usingFeather )
99 properties.useFeather = usingFeather;
102 QSettings settings( PENCIL2D, PENCIL2D );
103 settings.setValue(
"brushUseFeather", usingFeather);
107 void BrushTool::setFeather(
const qreal feather )
110 properties.feather = feather;
113 QSettings settings( PENCIL2D, PENCIL2D );
114 settings.setValue(
"brushFeather", feather);
118 void BrushTool::setInvisibility(
const bool invisibility )
121 properties.invisibility = invisibility;
123 QSettings settings ( PENCIL2D, PENCIL2D );
124 settings.setValue(
"brushInvisibility",invisibility);
128 void BrushTool::setPressure(
const bool pressure )
131 properties.pressure = pressure;
134 QSettings settings( PENCIL2D, PENCIL2D );
135 settings.setValue(
"brushPressure", pressure);
139 void BrushTool::setInpolLevel(
const int level)
141 properties.inpolLevel = level;
143 QSettings settings( PENCIL2D, PENCIL2D);
144 settings.setValue(
"lineInpol", level);
148 void BrushTool::setAA(
const int AA )
151 properties.useAA = AA;
154 QSettings settings( PENCIL2D, PENCIL2D );
155 settings.setValue(
"brushAA", AA);
159 QCursor BrushTool::cursor()
161 if ( mEditor->preference()->isOn( SETTING::TOOL_CURSOR ) )
163 return QCursor( QPixmap(
":icons/brush.png" ), 0, 13 );
165 return Qt::CrossCursor;
168 void BrushTool::adjustPressureSensitiveProperties( qreal pressure,
bool mouseDevice )
185 if ( properties.pressure && !mouseDevice )
187 mCurrentPressure = pressure;
191 mCurrentPressure = 1.0;
195 void BrushTool::mousePressEvent( QMouseEvent *event )
197 if ( event->button() == Qt::LeftButton )
199 mEditor->backup( typeName() );
200 mScribbleArea->setAllDirty();
203 mMouseDownPoint = getCurrentPoint();
205 mLastBrushPoint = getCurrentPoint();
208 if ( !mEditor->preference()->isOn(SETTING::INVISIBLE_LINES) )
210 mScribbleArea->toggleThinLines();
215 void BrushTool::mouseReleaseEvent( QMouseEvent *event )
217 if ( event->button() == Qt::LeftButton )
219 Layer* layer = mEditor->layers()->currentLayer();
220 if ( mScribbleArea->isLayerPaintable() )
222 qreal distance = QLineF( getCurrentPoint(), mMouseDownPoint ).length();
225 paintAt(mMouseDownPoint);
233 if ( layer->type() == Layer::BITMAP ) {
236 else if (layer->type() == Layer::VECTOR )
244 void BrushTool::mouseMoveEvent( QMouseEvent *event )
246 if ( mScribbleArea->isLayerPaintable() )
248 if ( event->buttons() & Qt::LeftButton )
251 if (properties.inpolLevel != m_pStrokeManager->getInpolLevel()) {
252 m_pStrokeManager->setInpolLevel(properties.inpolLevel);
259 void BrushTool::paintAt( QPointF point )
261 qDebug() <<
"Made a single dab at " << point;
262 Layer* layer = mEditor->layers()->currentLayer();
263 if ( layer->type() == Layer::BITMAP )
266 mCurrentWidth = properties.width;
267 qreal brushWidth = mCurrentWidth;
271 rect.extend( point.toPoint() );
272 mScribbleArea->drawBrush( QPoint( qRound(point.x() ), qRound(point.y() )),
275 mEditor->color()->frontColor(),
277 properties.useFeather,
280 int rad = qRound( brushWidth ) / 2 + 2;
281 mScribbleArea->refreshBitmap( rect, rad );
285 void BrushTool::drawStroke()
287 StrokeTool::drawStroke();
290 Layer* layer = mEditor->layers()->currentLayer();
292 if ( layer->type() == Layer::BITMAP )
294 for (
int i = 0; i < p.size(); i++ )
296 p[ i ] = mEditor->view()->mapScreenToCanvas( p[ i ] );
300 if (properties.pressure ==
true) {
301 opacity = mCurrentPressure / 2;
304 mCurrentWidth = properties.width;
305 qreal brushWidth = mCurrentWidth;
307 qreal brushStep = (0.5 * brushWidth);
308 brushStep = qMax( 1.0, brushStep );
312 QPointF a = mLastBrushPoint;
313 QPointF b = getCurrentPoint();
315 qreal distance = 4 * QLineF( b, a ).length();
316 int steps = qRound( distance / brushStep);
318 for (
int i = 0; i < steps; i++ )
320 QPointF point = mLastBrushPoint + ( i + 1 ) * brushStep * ( getCurrentPoint() - mLastBrushPoint ) / distance;
322 rect.extend( point.toPoint() );
323 mScribbleArea->drawBrush( QPoint( qRound(point.x() ),qRound(point.y() )),
326 mEditor->color()->frontColor(),
328 properties.useFeather,
330 if ( i == ( steps - 1 ) )
332 mLastBrushPoint = getCurrentPoint();
336 int rad = qRound( brushWidth / 2 + 2);
338 mScribbleArea->paintBitmapBufferRect( rect );
339 mScribbleArea->refreshBitmap( rect, rad );
357 else if ( layer->type() == Layer::VECTOR )
359 qreal brushWidth = 0;
360 if (properties.pressure ) {
361 brushWidth = properties.width * mCurrentPressure;
364 brushWidth = properties.width;
367 int rad = qRound( ( brushWidth / 2 + 2 ) * mEditor->view()->scaling() );
369 QPen pen( mEditor->color()->frontColor(),
370 brushWidth * mEditor->view()->scaling(),
377 QPainterPath path( p[ 0 ] );
378 path.cubicTo( p[ 1 ],
382 mScribbleArea->drawPath( path, pen, Qt::NoBrush, QPainter::CompositionMode_Source );
383 mScribbleArea->refreshVector( path.boundingRect().toRect(), rad );
388 void BrushTool::paintBitmapStroke()
390 mScribbleArea->paintBitmapBuffer();
391 mScribbleArea->setAllDirty();
392 mScribbleArea->clearBitmapBuffer();
397 void BrushTool::paintVectorStroke()
399 Layer* layer = mEditor->layers()->currentLayer();
401 if ( layer->type() == Layer::VECTOR && mStrokePoints.size() > -1 )
405 mScribbleArea->clearBitmapBuffer();
406 qreal tol = mScribbleArea->getCurveSmoothing() / mEditor->view()->scaling();
408 BezierCurve curve( mStrokePoints, mStrokePressures, tol );
409 curve.setWidth( properties.width );
410 curve.setFeather( properties.feather );
411 curve.setInvisibility( properties.invisibility );
412 curve.setVariableWidth( properties.pressure );
413 curve.setColourNumber( mEditor->color()->frontColorNumber() );
415 auto pLayerVector =
static_cast< LayerVector*
>( layer );
416 VectorImage* vectorImage = pLayerVector->getLastVectorImageAtFrame( mEditor->currentFrame(), 0 );
417 vectorImage->insertCurve( 0, curve, mEditor->view()->scaling(), false );
419 mScribbleArea->setModified( mEditor->layers()->currentLayerIndex(), mEditor->currentFrame() );
420 mScribbleArea->setAllDirty();