~ubuntu-branches/ubuntu/oneiric/koffice/oneiric-updates

« back to all changes in this revision

Viewing changes to krita/plugins/paintops/hairy/brush_shape.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-27 17:52:57 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101027175257-s04zqqk5bs8ckm9o
Tags: 1:2.2.83-0ubuntu1
* Merge with Debian git remaining changes:
 - Add build-deps on librcps-dev, opengtl-dev, libqtgtl-dev, freetds-dev,
   create-resources, libspnav-dev
 - Remove needless build-dep on libwv2-dev
 - koffice-libs recommends create-resources
 - krita recommends pstoedit
 - Keep our patches
* New upstream release 2.3 beta 3
  - Remove debian/patches fixed by upstream
  - Update install files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Copyright (c) 2008-2010 Lukáš Tvrdý <lukast.dev@gmail.com>
3
 
 *
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.
8
 
 *
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.
13
 
 *
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.
17
 
 */
18
 
 
19
 
#include "brush_shape.h"
20
 
 
21
 
#include <QVector>
22
 
#include <QImage>
23
 
 
24
 
#include <cmath>
25
 
#include "kis_debug.h"
26
 
 
27
 
BrushShape::BrushShape()
28
 
{
29
 
    m_hasColor = false;
30
 
}
31
 
 
32
 
BrushShape::~BrushShape()
33
 
{
34
 
/*    qDeleteAll(m_bristles.begin(), m_bristles.end());
35
 
    m_bristles.clear();*/
36
 
}
37
 
 
38
 
void BrushShape::fromDistance(int radius, float scale)
39
 
{
40
 
    Q_UNUSED(scale);
41
 
    m_width = m_height = radius * 2 + 1;
42
 
    qreal distance = 0.0;
43
 
    qreal maxDist = sqrt(radius * radius);
44
 
    
45
 
    Bristle *b;
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);
50
 
                distance /= maxDist;
51
 
                b = new Bristle(x, y, 1.0 - distance);
52
 
                b->setInkAmount(1.0f);
53
 
                m_bristles.append(b);
54
 
            }
55
 
        }
56
 
    }
57
 
}
58
 
 
59
 
void BrushShape::fromGaussian(int radius, float sigma)
60
 
{
61
 
    m_radius = radius;
62
 
    m_sigma = sigma;
63
 
 
64
 
    m_width = m_height = radius * 2 + 1;
65
 
    int gaussLength = (int)(m_width * m_width);
66
 
    //int center = (edgeSize - 1) / 2;
67
 
 
68
 
    float sigmaSquare = - 2.0 * sigma * sigma;
69
 
    float sigmaConst = 1.0 / (2.0 * M_PI * sigma * sigma);
70
 
 
71
 
    float total = 0;
72
 
    float length = 0;
73
 
    int p = 0;
74
 
 
75
 
    Bristle *b;
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);
79
 
            total += length;
80
 
            b = new Bristle(x, y, length);
81
 
            b->setInkAmount(1.0f);
82
 
            m_bristles.append(b);
83
 
            p++;
84
 
        }
85
 
    }
86
 
 
87
 
    float minLen = m_bristles.at(0)->length();
88
 
    float maxLen = m_bristles.at(gaussLength/2)->length();
89
 
    float dist = maxLen - minLen;
90
 
 
91
 
    // normalise lengths
92
 
    float result;
93
 
    int i = 0;
94
 
 
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);
99
 
        }
100
 
    }
101
 
 
102
 
}
103
 
 
104
 
void BrushShape::fromLine(int radius, float sigma)
105
 
{
106
 
    m_radius = radius;
107
 
    m_sigma = sigma;
108
 
 
109
 
    m_width = radius * 2 + 1;
110
 
    m_height = 1;
111
 
 
112
 
    int gaussLength = m_width;
113
 
 
114
 
    float sigmaSquare = - 2.0f * sigma * sigma;
115
 
    float sigmaConst = 1.0f / (sigma * 2.506628f); /* sqrt(2.0*pi) */
116
 
 
117
 
    float length;
118
 
    Bristle *b;
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);
123
 
    }
124
 
 
125
 
    float minLen = m_bristles.at(0)->length();
126
 
    float maxLen = m_bristles.at(gaussLength/2)->length();
127
 
    float dist = maxLen - minLen;
128
 
 
129
 
    // normalise lengths
130
 
    float result;
131
 
 
132
 
    for (int x = 0; x < m_width; x++) {
133
 
        result = (m_bristles.at(x)->length() - minLen) / dist;
134
 
        m_bristles[x]->setLength(result);
135
 
    }
136
 
}
137
 
 
138
 
 
139
 
void BrushShape::fromQImageWithDensity(QImage image, qreal density)
140
 
{
141
 
    m_width = image.width();
142
 
    m_height = image.height();
143
 
 
144
 
    int centerX = m_width * 0.5;
145
 
    int centerY = m_height * 0.5;
146
 
   
147
 
    // make mask 
148
 
    Bristle *bristle;
149
 
    int a;
150
 
    QRgb color;
151
 
    KoColor kcolor(m_colorSpace);
152
 
    QColor qcolor;
153
 
    srand48(12345678);
154
 
    
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; 
161
 
            if (a != 0){
162
 
                if (drand48() > density){
163
 
                    continue;
164
 
                }
165
 
                bristle = new Bristle(x - centerX, y - centerY, a / 255.0); // using value from image as length of bristle    
166
 
                if (m_hasColor){
167
 
                    qcolor.setRgb(color);
168
 
                    kcolor.fromQColor(qcolor);
169
 
                    bristle->setColor(kcolor);
170
 
                } 
171
 
                m_bristles.append(bristle);
172
 
            }
173
 
        }
174
 
    }
175
 
}
176
 
 
177
 
 
178
 
QVector<Bristle*> BrushShape::getBristles()
179
 
{
180
 
    return m_bristles;
181
 
}
182
 
 
183
 
int BrushShape::width()
184
 
{
185
 
    return m_width;
186
 
}
187
 
 
188
 
int BrushShape::height()
189
 
{
190
 
    return m_height;
191
 
}
192
 
 
193
 
int BrushShape::radius()
194
 
{
195
 
    return m_radius;
196
 
}
197
 
 
198
 
float BrushShape::sigma()
199
 
{
200
 
    return m_sigma;
201
 
}
202
 
 
203
 
void BrushShape::thresholdBristles(double threshold)
204
 
{
205
 
    for (int i = 0; i < m_bristles.size(); i++) {
206
 
        if (m_bristles.at(i)->length() < threshold) {
207
 
            m_bristles[i]->setEnabled(false);
208
 
        }
209
 
    }
210
 
}