KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > MultipleGradientPaint


1 /*
2  * @(#)MultipleGradientPaint.java 1.3 06/06/26
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt;
9
10 import java.awt.geom.AffineTransform JavaDoc;
11 import java.awt.image.ColorModel JavaDoc;
12 import java.lang.ref.SoftReference JavaDoc;
13 import java.util.Arrays JavaDoc;
14
15 /**
16  * This is the superclass for Paints which use a multiple color
17  * gradient to fill in their raster. It provides storage for variables and
18  * enumerated values common to
19  * {@code LinearGradientPaint} and {@code RadialGradientPaint}.
20  *
21  * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
22  * @since 1.6
23  */

24 public abstract class MultipleGradientPaint implements Paint JavaDoc {
25
26     /** The method to use when painting outside the gradient bounds.
27      * @since 1.6
28      */

29     public static enum CycleMethod {
30         /**
31          * Use the terminal colors to fill the remaining area.
32          */

33         NO_CYCLE,
34
35         /**
36          * Cycle the gradient colors start-to-end, end-to-start
37          * to fill the remaining area.
38          */

39         REFLECT,
40
41         /**
42          * Cycle the gradient colors start-to-end, start-to-end
43          * to fill the remaining area.
44          */

45         REPEAT
46     }
47
48     /** The color space in which to perform the gradient interpolation.
49      * @since 1.6
50      */

51     public static enum ColorSpaceType {
52         /**
53          * Indicates that the color interpolation should occur in sRGB space.
54          */

55         SRGB,
56
57         /**
58          * Indicates that the color interpolation should occur in linearized
59          * RGB space.
60          */

61         LINEAR_RGB
62     }
63
64     /** The transparency of this paint object. */
65     final int transparency;
66
67     /** Gradient keyframe values in the range 0 to 1. */
68     final float[] fractions;
69
70     /** Gradient colors. */
71     final Color JavaDoc[] colors;
72
73     /** Transform to apply to gradient. */
74     final AffineTransform JavaDoc gradientTransform;
75
76     /** The method to use when painting outside the gradient bounds. */
77     final CycleMethod cycleMethod;
78
79     /** The color space in which to perform the gradient interpolation. */
80     final ColorSpaceType colorSpace;
81
82     /**
83      * The following fields are used only by MultipleGradientPaintContext
84      * to cache certain values that remain constant and do not need to be
85      * recalculated for each context created from this paint instance.
86      */

87     ColorModel JavaDoc model;
88     float[] normalizedIntervals;
89     boolean isSimpleLookup;
90     SoftReference JavaDoc<int[][]> gradients;
91     SoftReference JavaDoc<int[]> gradient;
92     int fastGradientArraySize;
93
94     /**
95      * Package-private constructor.
96      *
97      * @param fractions numbers ranging from 0.0 to 1.0 specifying the
98      * distribution of colors along the gradient
99      * @param colors array of colors corresponding to each fractional value
100      * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT},
101      * or {@code REPEAT}
102      * @param colorSpace which color space to use for interpolation,
103      * either {@code SRGB} or {@code LINEAR_RGB}
104      * @param gradientTransform transform to apply to the gradient
105      *
106      * @throws NullPointerException
107      * if {@code fractions} array is null,
108      * or {@code colors} array is null,
109      * or {@code gradientTransform} is null,
110      * or {@code cycleMethod} is null,
111      * or {@code colorSpace} is null
112      * @throws IllegalArgumentException
113      * if {@code fractions.length != colors.length},
114      * or {@code colors} is less than 2 in size,
115      * or a {@code fractions} value is less than 0.0 or greater than 1.0,
116      * or the {@code fractions} are not provided in strictly increasing order
117      */

118     MultipleGradientPaint(float[] fractions,
119                           Color JavaDoc[] colors,
120                           CycleMethod cycleMethod,
121                           ColorSpaceType colorSpace,
122                           AffineTransform JavaDoc gradientTransform)
123     {
124         if (fractions == null) {
125             throw new NullPointerException JavaDoc("Fractions array cannot be null");
126         }
127
128         if (colors == null) {
129             throw new NullPointerException JavaDoc("Colors array cannot be null");
130         }
131
132         if (cycleMethod == null) {
133             throw new NullPointerException JavaDoc("Cycle method cannot be null");
134         }
135
136         if (colorSpace == null) {
137             throw new NullPointerException JavaDoc("Color space cannot be null");
138         }
139
140         if (gradientTransform == null) {
141             throw new NullPointerException JavaDoc("Gradient transform cannot be "+
142                                            "null");
143         }
144
145         if (fractions.length != colors.length) {
146             throw new IllegalArgumentException JavaDoc("Colors and fractions must " +
147                                                "have equal size");
148         }
149
150         if (colors.length < 2) {
151             throw new IllegalArgumentException JavaDoc("User must specify at least " +
152                                                "2 colors");
153         }
154
155         // check that values are in the proper range and progress
156
// in increasing order from 0 to 1
157
float previousFraction = -1.0f;
158         for (float currentFraction : fractions) {
159             if (currentFraction < 0f || currentFraction > 1f) {
160                 throw new IllegalArgumentException JavaDoc("Fraction values must " +
161                                                    "be in the range 0 to 1: " +
162                                                    currentFraction);
163             }
164
165             if (currentFraction <= previousFraction) {
166                 throw new IllegalArgumentException JavaDoc("Keyframe fractions " +
167                                                    "must be increasing: " +
168                                                    currentFraction);
169             }
170
171             previousFraction = currentFraction;
172         }
173
174         // We have to deal with the cases where the first gradient stop is not
175
// equal to 0 and/or the last gradient stop is not equal to 1.
176
// In both cases, create a new point and replicate the previous
177
// extreme point's color.
178
boolean fixFirst = false;
179         boolean fixLast = false;
180         int len = fractions.length;
181         int off = 0;
182
183         if (fractions[0] != 0f) {
184             // first stop is not equal to zero, fix this condition
185
fixFirst = true;
186             len++;
187             off++;
188         }
189         if (fractions[fractions.length-1] != 1f) {
190             // last stop is not equal to one, fix this condition
191
fixLast = true;
192             len++;
193         }
194
195         this.fractions = new float[len];
196         System.arraycopy(fractions, 0, this.fractions, off, fractions.length);
197         this.colors = new Color JavaDoc[len];
198         System.arraycopy(colors, 0, this.colors, off, colors.length);
199
200         if (fixFirst) {
201             this.fractions[0] = 0f;
202             this.colors[0] = colors[0];
203         }
204         if (fixLast) {
205             this.fractions[len-1] = 1f;
206             this.colors[len-1] = colors[colors.length - 1];
207         }
208
209         // copy some flags
210
this.colorSpace = colorSpace;
211         this.cycleMethod = cycleMethod;
212
213         // copy the gradient transform
214
this.gradientTransform = new AffineTransform JavaDoc(gradientTransform);
215
216         // determine transparency
217
boolean opaque = true;
218         for (int i = 0; i < colors.length; i++){
219             opaque = opaque && (colors[i].getAlpha() == 0xff);
220         }
221         this.transparency = opaque ? OPAQUE : TRANSLUCENT;
222     }
223
224     /**
225      * Returns a copy of the array of floats used by this gradient
226      * to calculate color distribution.
227      * The returned array always has 0 as its first value and 1 as its
228      * last value, with increasing values in between.
229      *
230      * @return a copy of the array of floats used by this gradient to
231      * calculate color distribution
232      */

233     public final float[] getFractions() {
234         return Arrays.copyOf(fractions, fractions.length);
235     }
236
237     /**
238      * Returns a copy of the array of colors used by this gradient.
239      * The first color maps to the first value in the fractions array,
240      * and the last color maps to the last value in the fractions array.
241      *
242      * @return a copy of the array of colors used by this gradient
243      */

244     public final Color JavaDoc[] getColors() {
245         return Arrays.copyOf(colors, colors.length);
246     }
247
248     /**
249      * Returns the enumerated type which specifies cycling behavior.
250      *
251      * @return the enumerated type which specifies cycling behavior
252      */

253     public final CycleMethod getCycleMethod() {
254         return cycleMethod;
255     }
256
257     /**
258      * Returns the enumerated type which specifies color space for
259      * interpolation.
260      *
261      * @return the enumerated type which specifies color space for
262      * interpolation
263      */

264     public final ColorSpaceType getColorSpace() {
265         return colorSpace;
266     }
267
268     /**
269      * Returns a copy of the transform applied to the gradient.
270      *
271      * @return a copy of the transform applied to the gradient
272      */

273     public final AffineTransform JavaDoc getTransform() {
274         return new AffineTransform JavaDoc(gradientTransform);
275     }
276
277     /**
278      * Returns the transparency mode for this Paint object.
279      *
280      * @return an integer value representing the transparency mode for
281      * this Paint object
282      * @see java.awt.Transparency
283      */

284     public final int getTransparency() {
285         return transparency;
286     }
287 }
288
Popular Tags