1 /*
2 Copyright (c) 2007 Sven Langkamp <sven.langkamp@gmail.com>
3 Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
4 Copyright (c) 2009 Jan Hambrecht <jaham@gmx.net>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "KoAbstractGradient.h"
22 #include "KoColorSpaceRegistry.h"
23
24 #include <KoColor.h>
25
26 #include <QBuffer>
27 #include <QByteArray>
28
29 #define PREVIEW_WIDTH 64
30 #define PREVIEW_HEIGHT 64
31
32
33 struct Q_DECL_HIDDEN KoAbstractGradient::Private {
34 const KoColorSpace* colorSpace;
35 QGradient::Spread spread;
36 QGradient::Type type;
37 };
38
KoAbstractGradient(const QString & filename)39 KoAbstractGradient::KoAbstractGradient(const QString& filename)
40 : KoResource(filename)
41 , d(new Private)
42 {
43 d->colorSpace = KoColorSpaceRegistry::instance()->rgb8();
44 d->spread = QGradient::PadSpread;
45 d->type = QGradient::NoGradient;
46 }
47
~KoAbstractGradient()48 KoAbstractGradient::~KoAbstractGradient()
49 {
50 delete d;
51 }
52
KoAbstractGradient(const KoAbstractGradient & rhs)53 KoAbstractGradient::KoAbstractGradient(const KoAbstractGradient &rhs)
54 : KoResource(rhs)
55 , d(new Private(*rhs.d))
56 {
57 }
58
colorAt(KoColor &,qreal t) const59 void KoAbstractGradient::colorAt(KoColor&, qreal t) const
60 {
61 Q_UNUSED(t);
62 }
63
setColorSpace(KoColorSpace * colorSpace)64 void KoAbstractGradient::setColorSpace(KoColorSpace* colorSpace)
65 {
66 d->colorSpace = colorSpace;
67 }
68
colorSpace() const69 const KoColorSpace* KoAbstractGradient::colorSpace() const
70 {
71 return d->colorSpace;
72 }
73
setSpread(QGradient::Spread spreadMethod)74 void KoAbstractGradient::setSpread(QGradient::Spread spreadMethod)
75 {
76 d->spread = spreadMethod;
77 }
78
spread() const79 QGradient::Spread KoAbstractGradient::spread() const
80 {
81 return d->spread;
82 }
83
setType(QGradient::Type repeatType)84 void KoAbstractGradient::setType(QGradient::Type repeatType)
85 {
86 d->type = repeatType;
87 }
88
type() const89 QGradient::Type KoAbstractGradient::type() const
90 {
91 return d->type;
92 }
93
generatePreview(int width,int height) const94 QImage KoAbstractGradient::generatePreview(int width, int height) const
95 {
96 QImage image(width, height, QImage::Format_RGB32);
97
98 const int checkerSize = 4;
99 const int checkerSize_2 = 2 * checkerSize;
100 const int darkBackground = 128;
101 const int lightBackground = 128 + 63;
102
103 QRgb * lineA = reinterpret_cast<QRgb*>(image.scanLine(0));
104 QRgb * lineB = reinterpret_cast<QRgb*>(image.scanLine(checkerSize));
105
106 KoColor c;
107 QColor color;
108 // first create the two reference lines
109 for (int x = 0; x < image.width(); ++x) {
110
111 qreal t = static_cast<qreal>(x) / (image.width() - 1);
112 colorAt(c, t);
113 c.toQColor(&color);
114 const qreal alpha = color.alphaF();
115
116 int darkR = static_cast<int>((1 - alpha) * darkBackground + alpha * color.red() + 0.5);
117 int darkG = static_cast<int>((1 - alpha) * darkBackground + alpha * color.green() + 0.5);
118 int darkB = static_cast<int>((1 - alpha) * darkBackground + alpha * color.blue() + 0.5);
119
120 int lightR = static_cast<int>((1 - alpha) * lightBackground + alpha * color.red() + 0.5);
121 int lightG = static_cast<int>((1 - alpha) * lightBackground + alpha * color.green() + 0.5);
122 int lightB = static_cast<int>((1 - alpha) * lightBackground + alpha * color.blue() + 0.5);
123
124 bool defColor = (x % checkerSize_2) < checkerSize;
125
126 if (lineA)
127 lineA[x] = defColor ? qRgb(darkR, darkG, darkB) : qRgb(lightR, lightG, lightB);
128 if (lineB)
129 lineB[x] = defColor ? qRgb(lightR, lightG, lightB) : qRgb(darkR, darkG, darkB);
130 }
131
132 int bytesPerLine = image.bytesPerLine();
133
134 // now copy lines accordingly
135 for (int y = 0; y < image.height(); ++y) {
136 bool firstLine = (y % checkerSize_2) < checkerSize;
137 QRgb * line = reinterpret_cast<QRgb*>(image.scanLine(y));
138 if (line == lineA || line == lineB)
139 continue;
140
141 memcpy(line, firstLine ? lineA : lineB, bytesPerLine);
142 }
143
144 return image;
145 }
146
updatePreview()147 void KoAbstractGradient::updatePreview()
148 {
149 setImage(generatePreview(PREVIEW_WIDTH, PREVIEW_HEIGHT));
150 }
151