Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/svg/Gradient.java
1463 views
1
package org.newdawn.slick.svg;
2
3
import java.util.ArrayList;
4
5
import org.newdawn.slick.Color;
6
import org.newdawn.slick.Image;
7
import org.newdawn.slick.ImageBuffer;
8
import org.newdawn.slick.geom.Transform;
9
10
/**
11
* A gradient definition from an SVG file, includes the stops, name and transform.
12
*
13
* @author kevin
14
*/
15
public class Gradient {
16
/** The name/id given to the gradient */
17
private String name;
18
/** The steps in colour of the gradient */
19
private ArrayList steps = new ArrayList();
20
/** The first x coordiante given in the gradient (cx in radial) */
21
private float x1;
22
/** The second x coordiante given in the gradient (fx in radial) */
23
private float x2;
24
/** The first y coordiante given in the gradient (cy in radial) */
25
private float y1;
26
/** The first y coordiante given in the gradient (fy in radial) */
27
private float y2;
28
/** The radius given if any */
29
private float r;
30
/** The texture representing this gradient */
31
private Image image;
32
/** True if this gradient is radial in nature */
33
private boolean radial;
34
/** The transform specified for the gradient */
35
private Transform transform;
36
/** The name of the referenced gradient */
37
private String ref;
38
39
/**
40
* Create a new gradient definition
41
*
42
* @param name The name of the gradient
43
* @param radial True if the gradient is radial
44
*/
45
public Gradient(String name, boolean radial) {
46
this.name = name;
47
this.radial = radial;
48
}
49
50
/**
51
* Check if the gradient is radial
52
*
53
* @return True if the gradient is radial
54
*/
55
public boolean isRadial() {
56
return radial;
57
}
58
59
/**
60
* Set the transform given for this definition
61
*
62
* @param trans The transform given for this definition
63
*/
64
public void setTransform(Transform trans) {
65
this.transform = trans;
66
}
67
68
/**
69
* Get the transform to apply during this gradient application
70
*
71
* @return The transform given for this gradient
72
*/
73
public Transform getTransform() {
74
return transform;
75
}
76
77
/**
78
* Reference another gradient, i.e. use it's colour stops
79
*
80
* @param ref The name of the other gradient to reference
81
*/
82
public void reference(String ref) {
83
this.ref = ref;
84
}
85
86
/**
87
* Resolve the gradient reference
88
*
89
* @param diagram The diagram to resolve against
90
*/
91
public void resolve(Diagram diagram) {
92
if (ref == null) {
93
return;
94
}
95
96
Gradient other = diagram.getGradient(ref);
97
98
for (int i=0;i<other.steps.size();i++) {
99
steps.add(other.steps.get(i));
100
}
101
}
102
103
/**
104
* Generate the image used for texturing the gradient across shapes
105
*/
106
public void genImage() {
107
if (image == null) {
108
ImageBuffer buffer = new ImageBuffer(128,16);
109
for (int i=0;i<128;i++) {
110
Color col = getColorAt(i / 128.0f);
111
for (int j=0;j<16;j++) {
112
buffer.setRGBA(i, j, col.getRedByte(), col.getGreenByte(), col.getBlueByte(), col.getAlphaByte());
113
}
114
}
115
image = buffer.getImage();
116
}
117
}
118
119
/**
120
* Get the image generated for this gradient
121
*
122
* @return The image generated for the gradient
123
*/
124
public Image getImage() {
125
genImage();
126
127
return image;
128
}
129
130
/**
131
* Set the radius given in the SVG
132
*
133
* @param r The radius for radial gradients
134
*/
135
public void setR(float r) {
136
this.r = r;
137
}
138
139
/**
140
* Set the first x value given for the gradient (cx in the case of radial)
141
*
142
* @param x1 The first x value given for the gradient
143
*/
144
public void setX1(float x1) {
145
this.x1 = x1;
146
}
147
148
/**
149
* Set the second x value given for the gradient (fx in the case of radial)
150
*
151
* @param x2 The second x value given for the gradient
152
*/
153
public void setX2(float x2) {
154
this.x2 = x2;
155
}
156
157
/**
158
* Set the first y value given for the gradient (cy in the case of radial)
159
*
160
* @param y1 The first y value given for the gradient
161
*/
162
public void setY1(float y1) {
163
this.y1 = y1;
164
}
165
166
/**
167
* Set the second y value given for the gradient (fy in the case of radial)
168
*
169
* @param y2 The second y value given for the gradient
170
*/
171
public void setY2(float y2) {
172
this.y2 = y2;
173
}
174
175
/**
176
* Get the radius value given for this gradient
177
*
178
* @return The radius value given for this gradient
179
*/
180
public float getR() {
181
return r;
182
}
183
184
/**
185
* Get the first x value given for this gradient (cx in the case of radial)
186
*
187
* @return The first x value given for this gradient
188
*/
189
public float getX1() {
190
return x1;
191
}
192
193
/**
194
* Get the second x value given for this gradient (fx in the case of radial)
195
*
196
* @return The second x value given for this gradient
197
*/
198
public float getX2() {
199
return x2;
200
}
201
202
/**
203
* Get the first y value given for this gradient (cy in the case of radial)
204
*
205
* @return The first y value given for this gradient
206
*/
207
public float getY1() {
208
return y1;
209
}
210
211
/**
212
* Get the second y value given for this gradient (fy in the case of radial)
213
*
214
* @return The second y value given for this gradient
215
*/
216
public float getY2() {
217
return y2;
218
}
219
220
/**
221
* Add a colour step/stop to the gradient
222
*
223
* @param location The location on the gradient the colour affects
224
* @param c The color to apply
225
*/
226
public void addStep(float location, Color c) {
227
steps.add(new Step(location, c));
228
}
229
230
/**
231
* Get the intepolated colour at the given location on the gradient
232
*
233
* @param p The point of the gradient (0 >= n >= 1)
234
* @return The interpolated colour at the given location
235
*/
236
public Color getColorAt(float p) {
237
if (p <= 0) {
238
return ((Step) steps.get(0)).col;
239
}
240
if (p > 1) {
241
return ((Step) steps.get(steps.size()-1)).col;
242
}
243
244
for (int i=1;i<steps.size();i++) {
245
Step prev = ((Step) steps.get(i-1));
246
Step current = ((Step) steps.get(i));
247
248
if (p <= current.location) {
249
float dis = current.location - prev.location;
250
p -= prev.location;
251
float v = p / dis;
252
253
Color c = new Color(1,1,1,1);
254
c.a = (prev.col.a * (1 - v)) + (current.col.a * (v));
255
c.r = (prev.col.r * (1 - v)) + (current.col.r * (v));
256
c.g = (prev.col.g * (1 - v)) + (current.col.g * (v));
257
c.b = (prev.col.b * (1 - v)) + (current.col.b * (v));
258
259
return c;
260
}
261
}
262
263
// shouldn't ever happen
264
return Color.black;
265
}
266
267
/**
268
* The description of a single step on the gradient
269
*
270
* @author kevin
271
*/
272
private class Step {
273
/** The location on the gradient */
274
float location;
275
/** The colour applied */
276
Color col;
277
278
/**
279
* Create a new step
280
*
281
* @param location The location on the gradient the colour affects
282
* @param c The colour to apply
283
*/
284
public Step(float location, Color c) {
285
this.location = location;
286
this.col = c;
287
}
288
}
289
}
290
291