source: josm/trunk/src/com/kitfox/svg/batik/RadialGradientPaint.java@ 10746

Last change on this file since 10746 was 8084, checked in by bastiK, 10 years ago

add svn:eol-style=native for svgsalamander

  • Property svn:eol-style set to native
File size: 17.3 KB
Line 
1/*****************************************************************************
2 * Copyright (C) The Apache Software Foundation. All rights reserved. *
3 * ------------------------------------------------------------------------- *
4 * This software is published under the terms of the Apache Software License *
5 * version 1.1, a copy of which has been included with this distribution in *
6 * the LICENSE file. *
7 *****************************************************************************/
8
9package com.kitfox.svg.batik;
10
11import java.awt.Color;
12import java.awt.PaintContext;
13import java.awt.Rectangle;
14import java.awt.RenderingHints;
15import java.awt.geom.AffineTransform;
16import java.awt.geom.NoninvertibleTransformException;
17import java.awt.geom.Point2D;
18import java.awt.geom.Rectangle2D;
19import java.awt.image.ColorModel;
20
21/**
22 * <p>
23 * This class provides a way to fill a shape with a circular radial color
24 * gradient pattern. The user may specify 2 or more gradient colors, and this
25 * paint will provide an interpolation between each color.
26 * <p>
27 *
28 * The user must provide an array of floats specifying how to distribute the
29 * colors along the gradient. These values should range from 0.0 to 1.0 and
30 * act like keyframes along the gradient (they mark where the gradient should
31 * be exactly a particular color).
32 *
33 * <p>
34 * This paint will map the first color of the gradient to a focus point within
35 * the circle, and the last color to the perimeter of the circle, interpolating
36 * smoothly for any inbetween colors specified by the user. Any line drawn
37 * from the focus point to the circumference will span the all the gradient
38 * colors. By default the focus is set to be the center of the circle.
39 *
40 * <p>
41 * Specifying a focus point outside of the circle's radius will result in the
42 * focus being set to the intersection point of the focus-center line and the
43 * perimenter of the circle.
44 * <p>
45 *
46 * Specifying a cycle method allows the user to control the painting behavior
47 * outside of the bounds of the circle's radius. See LinearGradientPaint for
48 * more details.
49 *
50 * <p>
51 * The following code demonstrates typical usage of RadialGradientPaint:
52 * <p>
53 * <code>
54 * Point2D center = new Point2D.Float(0, 0);<br>
55 * float radius = 20;
56 * float[] dist = {0.0, 0.2, 1.0};<br>
57 * Color[] colors = {Color.red, Color.white, Color.blue};<br>
58 * RadialGradientPaint p = new RadialGradientPaint(center, radius,
59 * dist, colors);
60 * </code>
61 *
62 * <p> In the event that the user does not set the first keyframe value equal
63 * to 0 and the last keyframe value equal to 1, keyframes will be created at
64 * these positions and the first and last colors will be replicated there.
65 * So, if a user specifies the following arrays to construct a gradient:<br>
66 * {Color.blue, Color.red}, {.3, .7}<br>
67 * this will be converted to a gradient with the following keyframes:
68 * {Color.blue, Color.blue, Color.red, Color.red}, {0, .3, .7, 1}
69 *
70 *
71 * <p>
72 * <img src = "radial.jpg">
73 * <p>
74 * This image demonstrates a radial gradient with NO_CYCLE and default focus.
75 * <p>
76 *
77 * <img src = "radial2.jpg">
78 * <p>
79 * This image demonstrates a radial gradient with NO_CYCLE and non-centered
80 * focus.
81 * <p>
82 *
83 * <img src = "radial3.jpg">
84 * <p>
85 * This image demonstrates a radial gradient with REFLECT and non-centered
86 * focus.
87 *
88 * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
89 * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
90 * @version $Id: RadialGradientPaint.java,v 1.1 2004/09/06 19:35:39 kitfox Exp $
91 *
92 */
93
94public final class RadialGradientPaint extends MultipleGradientPaint {
95
96 /** Focus point which defines the 0% gradient stop x coordinate. */
97 private Point2D focus;
98
99 /** Center of the circle defining the 100% gradient stop x coordinate. */
100 private Point2D center;
101
102 /** Radius of the outermost circle defining the 100% gradient stop. */
103 private float radius;
104
105 /**
106 * <p>
107 *
108 * Constructs a <code>RadialGradientPaint</code>, using the center as the
109 * focus point.
110 *
111 * @param cx the x coordinate in user space of the center point of the
112 * circle defining the gradient. The last color of the gradient is mapped
113 * to the perimeter of this circle
114 *
115 * @param cy the y coordinate in user space of the center point of the
116 * circle defining the gradient. The last color of the gradient is mapped
117 * to the perimeter of this circle
118 *
119 * @param radius the radius of the circle defining the extents of the
120 * color gradient
121 *
122 * @param fractions numbers ranging from 0.0 to 1.0 specifying the
123 * distribution of colors along the gradient
124 *
125 * @param colors array of colors to use in the gradient. The first color
126 * is used at the focus point, the last color around the perimeter of the
127 * circle.
128 *
129 *
130 * @throws IllegalArgumentException
131 * if fractions.length != colors.length, or if colors is less
132 * than 2 in size, or if radius < 0
133 *
134 *
135 */
136 public RadialGradientPaint(float cx, float cy, float radius,
137 float[] fractions, Color[] colors) {
138 this(cx, cy,
139 radius,
140 cx, cy,
141 fractions,
142 colors);
143 }
144
145 /**
146 * <p>
147 *
148 * Constructs a <code>RadialGradientPaint</code>, using the center as the
149 * focus point.
150 *
151 * @param center the center point, in user space, of the circle defining
152 * the gradient
153 *
154 * @param radius the radius of the circle defining the extents of the
155 * color gradient
156 *
157 * @param fractions numbers ranging from 0.0 to 1.0 specifying the
158 * distribution of colors along the gradient
159 *
160 * @param colors array of colors to use in the gradient. The first color
161 * is used at the focus point, the last color around the perimeter of the
162 * circle.
163 *
164 * @throws NullPointerException if center point is null
165 *
166 * @throws IllegalArgumentException
167 * if fractions.length != colors.length, or if colors is less
168 * than 2 in size, or if radius < 0
169 *
170 *
171 */
172 public RadialGradientPaint(Point2D center, float radius,
173 float[] fractions, Color[] colors) {
174 this(center,
175 radius,
176 center,
177 fractions,
178 colors);
179 }
180
181 /**
182 * <p>
183 *
184 * Constructs a <code>RadialGradientPaint</code>.
185 *
186 * @param cx the x coordinate in user space of the center point of the
187 * circle defining the gradient. The last color of the gradient is mapped
188 * to the perimeter of this circle
189 *
190 * @param cy the y coordinate in user space of the center point of the
191 * circle defining the gradient. The last color of the gradient is mapped
192 * to the perimeter of this circle
193 *
194 * @param radius the radius of the circle defining the extents of the
195 * color gradient
196 *
197 * @param fx the x coordinate of the point in user space to which the
198 * first color is mapped
199 *
200 * @param fy the y coordinate of the point in user space to which the
201 * first color is mapped
202 *
203 * @param fractions numbers ranging from 0.0 to 1.0 specifying the
204 * distribution of colors along the gradient
205 *
206 * @param colors array of colors to use in the gradient. The first color
207 * is used at the focus point, the last color around the perimeter of the
208 * circle.
209 *
210 * @throws IllegalArgumentException
211 * if fractions.length != colors.length, or if colors is less
212 * than 2 in size, or if radius < 0
213 *
214 *
215 */
216 public RadialGradientPaint(float cx, float cy, float radius,
217 float fx, float fy,
218 float[] fractions, Color[] colors) {
219 this(new Point2D.Float(cx, cy),
220 radius,
221 new Point2D.Float(fx, fy),
222 fractions,
223 colors,
224 NO_CYCLE,
225 SRGB);
226 }
227
228 /**
229 * <p>
230 *
231 * Constructs a <code>RadialGradientPaint</code>.
232 *
233 * @param center the center point, in user space, of the circle defining
234 * the gradient. The last color of the gradient is mapped to the perimeter
235 * of this circle
236 *
237 * @param radius the radius of the circle defining the extents of the color
238 * gradient
239 *
240 * @param focus the point, in user space, to which the first color is
241 * mapped
242 *
243 * @param fractions numbers ranging from 0.0 to 1.0 specifying the
244 * distribution of colors along the gradient
245 *
246 * @param colors array of colors to use in the gradient. The first color
247 * is used at the focus point, the last color around the perimeter of the
248 * circle.
249 *
250 * @throws NullPointerException if one of the points is null
251 *
252 * @throws IllegalArgumentException
253 * if fractions.length != colors.length, or if colors is less
254 * than 2 in size, or if radius < 0
255 *
256 */
257 public RadialGradientPaint(Point2D center, float radius,
258 Point2D focus,
259 float[] fractions, Color[] colors) {
260 this(center,
261 radius,
262 focus,
263 fractions,
264 colors,
265 NO_CYCLE,
266 SRGB);
267 }
268
269 /**
270 * <p>
271 *
272 * Constructs a <code>RadialGradientPaint</code>.
273 *
274 * @param center the center point in user space of the circle defining the
275 * gradient. The last color of the gradient is mapped to the perimeter of
276 * this circle
277 *
278 * @param radius the radius of the circle defining the extents of the color
279 * gradient
280 *
281 * @param focus the point in user space to which the first color is mapped
282 *
283 * @param fractions numbers ranging from 0.0 to 1.0 specifying the
284 * distribution of colors along the gradient
285 *
286 * @param colors array of colors to use in the gradient. The first color is
287 * used at the focus point, the last color around the perimeter of the
288 * circle.
289 *
290 * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
291 *
292 * @param colorSpace which colorspace to use for interpolation,
293 * either SRGB or LINEAR_RGB
294 *
295 * @throws NullPointerException if one of the points is null
296 *
297 * @throws IllegalArgumentException
298 * if fractions.length != colors.length, or if colors is less
299 * than 2 in size, or if radius < 0
300 *
301 */
302 public RadialGradientPaint(Point2D center, float radius,
303 Point2D focus,
304 float[] fractions, Color[] colors,
305 CycleMethodEnum cycleMethod,
306 ColorSpaceEnum colorSpace) {
307 this(center,
308 radius,
309 focus,
310 fractions,
311 colors,
312 cycleMethod,
313 colorSpace,
314 new AffineTransform());
315 }
316
317 /**
318 * <p>
319 *
320 * Constructs a <code>RadialGradientPaint</code>.
321 *
322 * @param center the center point in user space of the circle defining the
323 * gradient. The last color of the gradient is mapped to the perimeter of
324 * this circle
325 *
326 * @param radius the radius of the circle defining the extents of the color
327 * gradient.
328 *
329 * @param focus the point in user space to which the first color is mapped
330 *
331 * @param fractions numbers ranging from 0.0 to 1.0 specifying the
332 * distribution of colors along the gradient
333 *
334 * @param colors array of colors to use in the gradient. The first color is
335 * used at the focus point, the last color around the perimeter of the
336 * circle.
337 *
338 * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
339 *
340 * @param colorSpace which colorspace to use for interpolation,
341 * either SRGB or LINEAR_RGB
342 *
343 * @param gradientTransform transform to apply to the gradient
344 *
345 * @throws NullPointerException if one of the points is null,
346 * or gradientTransform is null
347 *
348 * @throws IllegalArgumentException
349 * if fractions.length != colors.length, or if colors is less
350 * than 2 in size, or if radius < 0
351 *
352 */
353 public RadialGradientPaint(Point2D center,
354 float radius,
355 Point2D focus,
356 float[] fractions, Color[] colors,
357 CycleMethodEnum cycleMethod,
358 ColorSpaceEnum colorSpace,
359 AffineTransform gradientTransform){
360 super(fractions, colors, cycleMethod, colorSpace, gradientTransform);
361
362 // Check input arguments
363 if (center == null) {
364 throw new NullPointerException("Center point should not be null.");
365 }
366
367 if (focus == null) {
368 throw new NullPointerException("Focus point should not be null.");
369 }
370
371 if (radius <= 0) {
372 throw new IllegalArgumentException("radius should be greater than zero");
373 }
374
375 //copy parameters
376 this.center = (Point2D)center.clone();
377 this.focus = (Point2D)focus.clone();
378 this.radius = radius;
379 }
380
381 /**
382 * <p>
383 *
384 * Constructs a <code>RadialGradientPaint</code>, the gradient circle is
385 * defined by a bounding box.
386 *
387 * @param gradientBounds the bounding box, in user space, of the circle
388 * defining outermost extent of the gradient.
389 *
390 * @param fractions numbers ranging from 0.0 to 1.0 specifying the
391 * distribution of colors along the gradient
392 *
393 * @param colors array of colors to use in the gradient. The first color
394 * is used at the focus point, the last color around the perimeter of the
395 * circle.
396 *
397 * @throws NullPointerException if the gradientBounds is null
398 *
399 * @throws IllegalArgumentException
400 * if fractions.length != colors.length, or if colors is less
401 * than 2 in size, or if radius < 0
402 *
403 */
404 public RadialGradientPaint(Rectangle2D gradientBounds,
405 float[] fractions, Color[] colors) {
406
407 //calculate center point and radius based on bounding box coordinates.
408 this((float)gradientBounds.getX() +
409 ( (float)gradientBounds.getWidth() / 2),
410
411 (float)gradientBounds.getY() +
412 ( (float)gradientBounds.getWidth() / 2),
413
414 (float)gradientBounds.getWidth() / 2,
415 fractions, colors);
416 }
417
418
419 /** <p>
420 * Creates and returns a PaintContext used to generate the color pattern,
421 * for use by the internal rendering engine.
422 *
423 * @param cm {@link ColorModel} that receives
424 * the <code>Paint</code> data. This is used only as a hint.
425 *
426 * @param deviceBounds the device space bounding box of the
427 * graphics primitive being rendered
428 *
429 * @param userBounds the user space bounding box of the
430 * graphics primitive being rendered
431 *
432 * @param transform the {@link AffineTransform} from user
433 * space into device space
434 *
435 * @param hints the hints that the context object uses to choose
436 * between rendering alternatives
437 *
438 * @return the {@link PaintContext} that generates color patterns.
439 *
440 * @throws IllegalArgumentException if the transform is not invertible
441 *
442 * @see PaintContext
443 */
444 public PaintContext createContext(ColorModel cm,
445 Rectangle deviceBounds,
446 Rectangle2D userBounds,
447 AffineTransform transform,
448 RenderingHints hints) {
449 // Can't modify the transform passed in...
450 transform = new AffineTransform(transform);
451 // incorporate the gradient transform
452 transform.concatenate(gradientTransform);
453
454 try{
455 return new RadialGradientPaintContext
456 (cm, deviceBounds, userBounds, transform, hints,
457 (float)center.getX(), (float)center.getY(), radius,
458 (float)focus.getX(), (float)focus.getY(),
459 fractions, colors, cycleMethod, colorSpace);
460 }
461
462 catch(NoninvertibleTransformException e){
463 throw new IllegalArgumentException("transform should be " +
464 "invertible");
465 }
466 }
467
468 /**
469 * Returns a copy of the center point of the radial gradient.
470 * @return a {@link Point2D} object that is a copy of the center point
471 */
472 public Point2D getCenterPoint() {
473 return new Point2D.Double(center.getX(), center.getY());
474 }
475
476 /** Returns a copy of the end point of the gradient axis.
477 * @return a {@link Point2D} object that is a copy of the focus point
478 */
479 public Point2D getFocusPoint() {
480 return new Point2D.Double(focus.getX(), focus.getY());
481 }
482
483 /** Returns the radius of the circle defining the radial gradient.
484 * @return the radius of the circle defining the radial gradient
485 */
486 public float getRadius() {
487 return radius;
488 }
489
490}
491
Note: See TracBrowser for help on using the repository browser.