2
* Copyright (c) 2008-2010 Lukáš Tvrdý <lukast.dev@gmail.com>
4
* This program 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 2 of the License, or
7
* (at your option) any later version.
9
* This program 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.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
#include "brush_shape.h"
25
#include "kis_debug.h"
27
BrushShape::BrushShape()
32
BrushShape::~BrushShape()
34
/* qDeleteAll(m_bristles.begin(), m_bristles.end());
38
void BrushShape::fromDistance(int radius, float scale)
41
m_width = m_height = radius * 2 + 1;
43
qreal maxDist = sqrt(radius * radius);
46
for (int y = -radius; y <= radius; y++) {
47
for (int x = -radius; x <= radius; x++) {
48
if ((x*x + y*y) < radius*radius) {
49
distance = sqrt(x * x + y * y);
51
b = new Bristle(x, y, 1.0 - distance);
52
b->setInkAmount(1.0f);
59
void BrushShape::fromGaussian(int radius, float sigma)
64
m_width = m_height = radius * 2 + 1;
65
int gaussLength = (int)(m_width * m_width);
66
//int center = (edgeSize - 1) / 2;
68
float sigmaSquare = - 2.0 * sigma * sigma;
69
float sigmaConst = 1.0 / (2.0 * M_PI * sigma * sigma);
76
for (int y = -radius; y <= radius; y++) {
77
for (int x = -radius; x <= radius; x++) {
78
length = (exp((x * x + y * y) / sigmaSquare) * sigmaConst);
80
b = new Bristle(x, y, length);
81
b->setInkAmount(1.0f);
87
float minLen = m_bristles.at(0)->length();
88
float maxLen = m_bristles.at(gaussLength/2)->length();
89
float dist = maxLen - minLen;
95
for (int x = 0; x < m_width; x++) {
96
for (int y = 0; y < m_height; y++, i++) {
97
result = (m_bristles.at(i)->length() - minLen) / dist;
98
m_bristles[i]->setLength(result);
104
void BrushShape::fromLine(int radius, float sigma)
109
m_width = radius * 2 + 1;
112
int gaussLength = m_width;
114
float sigmaSquare = - 2.0f * sigma * sigma;
115
float sigmaConst = 1.0f / (sigma * 2.506628f); /* sqrt(2.0*pi) */
119
for (int x = -radius; x <= radius; x++) {
120
length = exp(x * x / sigmaSquare) * sigmaConst;
121
b = new Bristle(0.0 , x , length);
122
m_bristles.append(b);
125
float minLen = m_bristles.at(0)->length();
126
float maxLen = m_bristles.at(gaussLength/2)->length();
127
float dist = maxLen - minLen;
132
for (int x = 0; x < m_width; x++) {
133
result = (m_bristles.at(x)->length() - minLen) / dist;
134
m_bristles[x]->setLength(result);
139
void BrushShape::fromQImageWithDensity(QImage image, qreal density)
141
m_width = image.width();
142
m_height = image.height();
144
int centerX = m_width * 0.5;
145
int centerY = m_height * 0.5;
151
KoColor kcolor(m_colorSpace);
155
for (int y = 0; y < m_height; y++) {
156
QRgb *pixelLine = reinterpret_cast<QRgb *>(image.scanLine(y));
157
for (int x = 0; x < m_width; x++) {
158
// density computation
159
color = pixelLine[x];
160
a = ((255 - qGray(color)) * qAlpha(color)) / 255;
162
if (drand48() > density){
165
bristle = new Bristle(x - centerX, y - centerY, a / 255.0); // using value from image as length of bristle
167
qcolor.setRgb(color);
168
kcolor.fromQColor(qcolor);
169
bristle->setColor(kcolor);
171
m_bristles.append(bristle);
178
QVector<Bristle*> BrushShape::getBristles()
183
int BrushShape::width()
188
int BrushShape::height()
193
int BrushShape::radius()
198
float BrushShape::sigma()
203
void BrushShape::thresholdBristles(double threshold)
205
for (int i = 0; i < m_bristles.size(); i++) {
206
if (m_bristles.at(i)->length() < threshold) {
207
m_bristles[i]->setEnabled(false);