1 /*
2 This file is part of Photoflare.
3
4 Photoflare is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 Photoflare is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with Photoflare. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 // SmudgeTool - Smudge pixels while dragging the mouse.
19
20 #include "SmudgeTool.h"
21 #include "PaintWidget.h"
22
23 #include <QPainter>
24 #include <QImage>
25 #include <QtMath>
26
27 class SmudgeToolPrivate
28 {
29 public:
SmudgeToolPrivate()30 SmudgeToolPrivate()
31 {
32 primaryPen = QPen(QBrush(), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
33 pixmap = QPixmap(32,32);
34 }
35 int radius;
36 int pressure;
37 QPoint lastPos;
38 QPen primaryPen;
39 Qt::MouseButton mouseButton;
40 QPixmap pixmap;
41 QImage completeImage;
42 };
43
SmudgeTool(QObject * parent)44 SmudgeTool::SmudgeTool(QObject *parent)
45 : Tool(parent)
46 , d(new SmudgeToolPrivate){}
47
~SmudgeTool()48 SmudgeTool::~SmudgeTool()
49 {
50 delete d;
51 }
52
getCursor()53 QCursor SmudgeTool::getCursor()
54 {
55 int width = d->radius * m_scale;
56 if(width < 5)
57 width = 5;
58 QPixmap pixmap(QSize(width,width));
59 pixmap.fill(Qt::transparent);
60 QPainter painter(&pixmap);
61 QPen pen = QPen(QBrush(), 1, Qt::DashLine);
62 pen.setColor(Qt::gray);
63 painter.setPen(pen);
64
65 painter.drawEllipse(pixmap.rect());
66 return QCursor(pixmap);
67 }
68
setRadius(int radius)69 void SmudgeTool::setRadius(int radius)
70 {
71 d->radius = radius;
72 emit cursorChanged(getCursor());
73 }
74
setPressure(int pressure)75 void SmudgeTool::setPressure(int pressure)
76 {
77 d->pressure = pressure;
78 }
79
onMousePress(const QPoint & pos,Qt::MouseButton button)80 void SmudgeTool::onMousePress(const QPoint &pos, Qt::MouseButton button)
81 {
82 Q_UNUSED(button);
83 d->lastPos = pos;
84 d->mouseButton = button;
85 const QImage *image = dynamic_cast<QImage*>(m_paintDevice);
86 d->completeImage = *image;
87 }
88
onMouseMove(const QPoint & pos)89 void SmudgeTool::onMouseMove(const QPoint &pos)
90 {
91 if (m_paintDevice)
92 {
93 float pressure = d->pressure / 20.0f;
94 QImage lastImage = d->completeImage.copy(d->lastPos.x() - d->radius/2, d->lastPos.y() - d->radius/2, d->radius, d->radius);
95 QImage currImage = lastImage.scaled(int(d->radius * pressure), int(d->radius * pressure));
96 QImage pattern(int(d->radius * pressure), int(d->radius * pressure), QImage::Format_ARGB32);
97 pattern.fill(Qt::transparent);
98 int w = pattern.width();
99 for(int i=0; i<w; i++)
100 {
101 for(int j=0; j<w; j++)
102 {
103 float l = qSqrt( qPow(i-w/2, 2) + qPow(j-w/2, 2) );
104 if(l <= w/2)
105 {
106 pattern.setPixel(i, j, currImage.pixel(i, j));
107 }
108 }
109 }
110
111 QPainter painter(m_paintDevice);
112 painter.drawPixmap(pos.x()-int(d->radius * pressure / 2), pos.y()-int(d->radius * pressure / 2), d->pixmap.fromImage(pattern));
113
114 d->lastPos = pos;
115 emit painted(m_paintDevice);
116
117 const QImage *image = dynamic_cast<QImage*>(m_paintDevice);
118 d->completeImage = *image;
119 }
120 }
121
onMouseRelease(const QPoint & pos)122 void SmudgeTool::onMouseRelease(const QPoint &pos)
123 {
124 Q_UNUSED(pos);
125 d->mouseButton = Qt::NoButton;
126 d->completeImage = QImage();
127 }
128
129