Rev 14154 | Rev 19103 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4430 | cbradney | 1 | /* |
2 | For general Scribus (>=1.3.2) copyright and licensing information please refer |
||
3 | to the COPYING file provided with the program. Following this notice may exist |
||
4 | a copyright and/or license notice that predates the release of Scribus 1.3.2 |
||
5 | for which a new license (GPL+exception) is in place. |
||
6 | */ |
||
68 | Franz | 7 | /* This file is part of the KDE project |
8 | Copyright (C) 2002, The Karbon Developers |
||
295 | Franz | 9 | |
68 | Franz | 10 | This library is free software; you can redistribute it and/or |
11 | modify it under the terms of the GNU Library General Public |
||
12 | License as published by the Free Software Foundation; either |
||
13 | version 2 of the License, or (at your option) any later version. |
||
295 | Franz | 14 | |
68 | Franz | 15 | This library is distributed in the hope that it will be useful, |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
18 | Library General Public License for more details. |
||
295 | Franz | 19 | |
68 | Franz | 20 | You should have received a copy of the GNU Library General Public License |
21 | along with this library; see the file COPYING.LIB. If not, write to |
||
18122 | mrdocs | 22 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
23 | Boston, MA 02110-1301, USA. |
||
68 | Franz | 24 | */ |
10223 | cbradney | 25 | |
9982 | fschmid | 26 | #include <QMutableListIterator> |
10009 | jghali | 27 | #include <QtAlgorithms> |
68 | Franz | 28 | |
10223 | cbradney | 29 | #include "vgradient.h" |
30 | |||
6506 | jghali | 31 | // colorStop comparison function for stable_sort function |
10009 | jghali | 32 | bool compareStops(const VColorStop* item1, const VColorStop* item2 ) |
6506 | jghali | 33 | { |
34 | double r1 = item1->rampPoint; |
||
35 | double r2 = item2->rampPoint; |
||
36 | return ( r1 < r2 ? true : false ); |
||
37 | } |
||
38 | |||
10009 | jghali | 39 | int VGradient::compareItems(const VColorStop* item1, const VColorStop* item2 ) const |
68 | Franz | 40 | { |
9982 | fschmid | 41 | double r1 = item1->rampPoint; |
42 | double r2 = item2->rampPoint; |
||
68 | Franz | 43 | |
44 | return ( r1 == r2 ? 0 : r1 < r2 ? -1 : 1 ); |
||
45 | } // VGradient::VColorStopList::compareItems |
||
46 | |||
6495 | jghali | 47 | |
10009 | jghali | 48 | void VGradient::inSort( VColorStop* d ) |
6495 | jghali | 49 | { |
50 | int index = 0; |
||
10009 | jghali | 51 | register VColorStop *n = m_colorStops.value(index); |
9982 | fschmid | 52 | while (n && compareItems(n,d) <= 0) |
53 | { |
||
10336 | fschmid | 54 | ++index; |
10009 | jghali | 55 | n = m_colorStops.value(index); |
6495 | jghali | 56 | } |
10009 | jghali | 57 | m_colorStops.insert( qMin(index, m_colorStops.size()), d ); |
6495 | jghali | 58 | } |
59 | |||
9982 | fschmid | 60 | VGradient::VGradient( VGradientType type ) : m_type( type ) |
68 | Franz | 61 | { |
62 | // set up dummy gradient |
||
63 | QColor color; |
||
64 | |||
65 | color = QColor(255,0,0); |
||
66 | addStop( color, 0.0, 0.5, 1.0 ); |
||
67 | |||
68 | color = QColor(255,255,0); |
||
69 | addStop( color, 1.0, 0.5, 1.0 ); |
||
70 | |||
71 | setOrigin( FPoint( 0, 0 ) ); |
||
72 | setVector( FPoint( 0, 50 ) ); |
||
73 | setRepeatMethod( VGradient::reflect ); |
||
74 | } |
||
75 | |||
76 | VGradient::VGradient( const VGradient& gradient ) |
||
77 | { |
||
78 | m_origin = gradient.m_origin; |
||
79 | m_focalPoint = gradient.m_focalPoint; |
||
80 | m_vector = gradient.m_vector; |
||
81 | m_type = gradient.m_type; |
||
82 | m_repeatMethod = gradient.m_repeatMethod; |
||
10009 | jghali | 83 | clearStops(); |
84 | QList<VColorStop*> cs = gradient.colorStops(); |
||
85 | qStableSort(cs.begin(), cs.end(), compareStops); |
||
9982 | fschmid | 86 | for( int i = 0; i < cs.count(); ++i) |
68 | Franz | 87 | m_colorStops.append( new VColorStop( *cs[i] ) ); |
88 | } // VGradient::VGradient |
||
89 | |||
9992 | jghali | 90 | VGradient::~VGradient() |
91 | { |
||
92 | clearStops(); |
||
93 | } |
||
94 | |||
68 | Franz | 95 | VGradient& VGradient::operator=( const VGradient& gradient ) |
96 | { |
||
97 | if ( this == &gradient ) |
||
98 | return *this; |
||
99 | |||
100 | m_origin = gradient.m_origin; |
||
101 | m_focalPoint = gradient.m_focalPoint; |
||
102 | m_vector = gradient.m_vector; |
||
103 | m_type = gradient.m_type; |
||
104 | m_repeatMethod = gradient.m_repeatMethod; |
||
105 | |||
10009 | jghali | 106 | clearStops(); |
107 | QList<VColorStop*> cs = gradient.colorStops(); |
||
108 | qStableSort(cs.begin(), cs.end(), compareStops); |
||
9982 | fschmid | 109 | for( int i = 0; i < cs.count(); ++i ) |
68 | Franz | 110 | m_colorStops.append( new VColorStop( *cs[i] ) ); |
80 | Franz | 111 | return *this; |
68 | Franz | 112 | } // VGradient::operator= |
113 | |||
14154 | fschmid | 114 | bool VGradient::operator==(const VGradient &gradient) const |
115 | { |
||
116 | if (static_cast<uint>(m_colorStops.count()) != gradient.Stops()) |
||
117 | return false; |
||
118 | QList<VColorStop*> cs = gradient.colorStops(); |
||
119 | bool retVal = true; |
||
120 | for (int i = 0; i < m_colorStops.count(); ++i) |
||
121 | { |
||
122 | if (m_colorStops.at(i)->rampPoint != cs.at(i)->rampPoint) |
||
123 | { |
||
124 | retVal = false; |
||
125 | break; |
||
126 | } |
||
127 | if (m_colorStops.at(i)->opacity != cs.at(i)->opacity) |
||
128 | { |
||
129 | retVal = false; |
||
130 | break; |
||
131 | } |
||
132 | if (m_colorStops.at(i)->name != cs.at(i)->name) |
||
133 | { |
||
134 | retVal = false; |
||
135 | break; |
||
136 | } |
||
137 | if (m_colorStops.at(i)->shade != cs.at(i)->shade) |
||
138 | { |
||
139 | retVal = false; |
||
140 | break; |
||
141 | } |
||
142 | } |
||
143 | return retVal; |
||
144 | } |
||
145 | |||
10009 | jghali | 146 | const QList<VColorStop*>& VGradient::colorStops() const |
80 | Franz | 147 | { |
10009 | jghali | 148 | return m_colorStops; |
68 | Franz | 149 | } // VGradient::colorStops() |
150 | |||
151 | void |
||
152 | VGradient::clearStops() |
||
153 | { |
||
9982 | fschmid | 154 | while (!m_colorStops.isEmpty()) |
155 | delete m_colorStops.takeFirst(); |
||
68 | Franz | 156 | } |
157 | |||
158 | void |
||
159 | VGradient::addStop( const VColorStop& colorStop ) |
||
160 | { |
||
10009 | jghali | 161 | inSort( new VColorStop( colorStop ) ); |
68 | Franz | 162 | } // VGradient::addStop |
163 | |||
164 | void |
||
295 | Franz | 165 | VGradient::addStop( const QColor &color, double rampPoint, double midPoint, double opa, QString name, int shade ) |
68 | Franz | 166 | { |
167 | // Clamping between 0.0 and 1.0 |
||
8562 | jghali | 168 | rampPoint = qMax( 0.0, rampPoint ); |
169 | rampPoint = qMin( 1.0, rampPoint ); |
||
68 | Franz | 170 | // Clamping between 0.0 and 1.0 |
8562 | jghali | 171 | midPoint = qMax( 0.0, midPoint ); |
172 | midPoint = qMin( 1.0, midPoint ); |
||
68 | Franz | 173 | |
10009 | jghali | 174 | inSort( new VColorStop( rampPoint, midPoint, color, opa, name, shade ) ); |
68 | Franz | 175 | } |
176 | |||
13182 | jghali | 177 | void |
178 | VGradient::setStop( const QColor &color, double rampPoint, double midPoint, double opa, QString name, int shade ) |
||
179 | { |
||
180 | for (int i = 0; i < m_colorStops.count(); ++i) |
||
181 | { |
||
182 | if (m_colorStops.at(i)->rampPoint == rampPoint) |
||
183 | { |
||
184 | delete m_colorStops.takeAt(i); |
||
185 | break; |
||
186 | } |
||
187 | } |
||
188 | addStop(color, rampPoint, midPoint, opa, name, shade); |
||
189 | } |
||
190 | |||
9982 | fschmid | 191 | void VGradient::removeStop( VColorStop& colorstop ) |
68 | Franz | 192 | { |
9982 | fschmid | 193 | int n = m_colorStops.indexOf(&colorstop); |
194 | delete m_colorStops.takeAt(n); |
||
295 | Franz | 195 | } |
196 | |||
197 | void VGradient::removeStop( uint n ) |
||
68 | Franz | 198 | { |
9982 | fschmid | 199 | delete m_colorStops.takeAt(n); |
68 | Franz | 200 | } |
296 | Franz | 201 | |
6495 | jghali | 202 | void VGradient::filterStops(void) |
203 | { |
||
204 | VColorStop* colorStop = NULL; |
||
205 | bool zeroFound = false; |
||
9982 | fschmid | 206 | QMutableListIterator<VColorStop*> i(m_colorStops); |
207 | i.toBack(); |
||
208 | while (i.hasPrevious()) |
||
6495 | jghali | 209 | { |
9982 | fschmid | 210 | colorStop = i.previous(); |
6495 | jghali | 211 | if (colorStop->rampPoint == 0.0 && zeroFound) |
9982 | fschmid | 212 | { |
213 | delete i.value(); |
||
214 | i.remove(); |
||
215 | } |
||
6495 | jghali | 216 | else if (colorStop->rampPoint == 0.0) |
217 | zeroFound = true; |
||
218 | } |
||
10031 | fschmid | 219 | bool oneFound = false; |
9982 | fschmid | 220 | i.toFront(); |
221 | while (i.hasNext()) |
||
6495 | jghali | 222 | { |
9982 | fschmid | 223 | colorStop = i.next(); |
10031 | fschmid | 224 | if (colorStop->rampPoint == 1.0 && oneFound) |
6495 | jghali | 225 | { |
9982 | fschmid | 226 | delete i.value(); |
227 | i.remove(); |
||
6495 | jghali | 228 | } |
10031 | fschmid | 229 | else if (colorStop->rampPoint == 1.0) |
230 | oneFound = true; |
||
6495 | jghali | 231 | } |
232 | } |
||
233 | |||
13951 | fschmid | 234 | void VGradient::transform( const QTransform &m ) |
296 | Franz | 235 | { |
236 | double mx, my; |
||
237 | mx = m.m11() * m_origin.x() + m.m21() * m_origin.y() + m.dx(); |
||
238 | my = m.m22() * m_origin.y() + m.m12() * m_origin.x() + m.dy(); |
||
239 | m_origin = FPoint(mx, my); |
||
240 | mx = m.m11() * m_focalPoint.x() + m.m21() * m_focalPoint.y() + m.dx(); |
||
241 | my = m.m22() * m_focalPoint.y() + m.m12() * m_focalPoint.x() + m.dy(); |
||
242 | m_focalPoint = FPoint(mx, my); |
||
243 | mx = m.m11() * m_vector.x() + m.m21() * m_vector.y() + m.dx(); |
||
244 | my = m.m22() * m_vector.y() + m.m12() * m_vector.x() + m.dy(); |
||
245 | m_vector = FPoint(mx, my); |
||
246 | } |