1 /*
2 * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package java.awt;
27
28 import java.awt.geom.Point2D;
29 import java.awt.geom.Rectangle2D;
30 import java.awt.geom.AffineTransform;
31 import java.awt.image.ColorModel;
32
33 /**
34 * The <code>GradientPaint</code> class provides a way to fill
35 * a {@link Shape} with a linear color gradient pattern.
36 * If {@link Point} P1 with {@link Color} C1 and <code>Point</code> P2 with
37 * <code>Color</code> C2 are specified in user space, the
38 * <code>Color</code> on the P1, P2 connecting line is proportionally
39 * changed from C1 to C2. Any point P not on the extended P1, P2
40 * connecting line has the color of the point P' that is the perpendicular
41 * projection of P on the extended P1, P2 connecting line.
42 * Points on the extended line outside of the P1, P2 segment can be colored
43 * in one of two ways.
44 * <ul>
45 * <li>
46 * If the gradient is cyclic then the points on the extended P1, P2
47 * connecting line cycle back and forth between the colors C1 and C2.
48 * <li>
49 * If the gradient is acyclic then points on the P1 side of the segment
50 * have the constant <code>Color</code> C1 while points on the P2 side
51 * have the constant <code>Color</code> C2.
52 * </ul>
53 *
54 * @see Paint
55 * @see Graphics2D#setPaint
56 * @version 10 Feb 1997
57 */
58
59 public class GradientPaint implements Paint {
60 Point2D.Float p1;
61 Point2D.Float p2;
62 Color color1;
63 Color color2;
64 boolean cyclic;
65
66 /**
67 * Constructs a simple acyclic <code>GradientPaint</code> object.
68 * @param x1 x coordinate of the first specified
69 * <code>Point</code> in user space
70 * @param y1 y coordinate of the first specified
71 * <code>Point</code> in user space
72 * @param color1 <code>Color</code> at the first specified
73 * <code>Point</code>
74 * @param x2 x coordinate of the second specified
75 * <code>Point</code> in user space
76 * @param y2 y coordinate of the second specified
77 * <code>Point</code> in user space
78 * @param color2 <code>Color</code> at the second specified
79 * <code>Point</code>
80 * @throws NullPointerException if either one of colors is null
81 */
82 public GradientPaint(float x1,
83 float y1,
84 Color color1,
85 float x2,
86 float y2,
87 Color color2) {
88 if ((color1 == null) || (color2 == null)) {
89 throw new NullPointerException("Colors cannot be null");
90 }
91
92 p1 = new Point2D.Float(x1, y1);
93 p2 = new Point2D.Float(x2, y2);
94 this.color1 = color1;
95 this.color2 = color2;
96 }
97
98 /**
99 * Constructs a simple acyclic <code>GradientPaint</code> object.
100 * @param pt1 the first specified <code>Point</code> in user space
101 * @param color1 <code>Color</code> at the first specified
102 * <code>Point</code>
103 * @param pt2 the second specified <code>Point</code> in user space
104 * @param color2 <code>Color</code> at the second specified
105 * <code>Point</code>
106 * @throws NullPointerException if either one of colors or points
107 * is null
108 */
109 public GradientPaint(Point2D pt1,
110 Color color1,
111 Point2D pt2,
112 Color color2) {
113 if ((color1 == null) || (color2 == null) ||
114 (pt1 == null) || (pt2 == null)) {
115 throw new NullPointerException("Colors and points should be non-null");
116 }
117
118 p1 = new Point2D.Float((float)pt1.getX(), (float)pt1.getY());
119 p2 = new Point2D.Float((float)pt2.getX(), (float)pt2.getY());
120 this.color1 = color1;
121 this.color2 = color2;
122 }
123
124 /**
125 * Constructs either a cyclic or acyclic <code>GradientPaint</code>
126 * object depending on the <code>boolean</code> parameter.
127 * @param x1 x coordinate of the first specified
128 * <code>Point</code> in user space
129 * @param y1 y coordinate of the first specified
130 * <code>Point</code> in user space
131 * @param color1 <code>Color</code> at the first specified
132 * <code>Point</code>
133 * @param x2 x coordinate of the second specified
134 * <code>Point</code> in user space
135 * @param y2 y coordinate of the second specified
136 * <code>Point</code> in user space
137 * @param color2 <code>Color</code> at the second specified
138 * <code>Point</code>
139 * @param cyclic <code>true</code> if the gradient pattern should cycle
140 * repeatedly between the two colors; <code>false</code> otherwise
141 */
142 public GradientPaint(float x1,
143 float y1,
144 Color color1,
145 float x2,
146 float y2,
147 Color color2,
148 boolean cyclic) {
149 this (x1, y1, color1, x2, y2, color2);
150 this.cyclic = cyclic;
151 }
152
153 /**
154 * Constructs either a cyclic or acyclic <code>GradientPaint</code>
155 * object depending on the <code>boolean</code> parameter.
156 * @param pt1 the first specified <code>Point</code>
157 * in user space
158 * @param color1 <code>Color</code> at the first specified
159 * <code>Point</code>
160 * @param pt2 the second specified <code>Point</code>
161 * in user space
162 * @param color2 <code>Color</code> at the second specified
163 * <code>Point</code>
164 * @param cyclic <code>true</code> if the gradient pattern should cycle
165 * repeatedly between the two colors; <code>false</code> otherwise
166 * @throws NullPointerException if either one of colors or points
167 * is null
168 */
169 public GradientPaint(Point2D pt1,
170 Color color1,
171 Point2D pt2,
172 Color color2,
173 boolean cyclic) {
174 this (pt1, color1, pt2, color2);
175 this.cyclic = cyclic;
176 }
177
178 /**
179 * Returns a copy of the point P1 that anchors the first color.
180 * @return a {@link Point2D} object that is a copy of the point
181 * that anchors the first color of this
182 * <code>GradientPaint</code>.
183 */
184 public Point2D getPoint1() {
185 return new Point2D.Float(p1.x, p1.y);
186 }
187
188 /**
189 * Returns the color C1 anchored by the point P1.
190 * @return a <code>Color</code> object that is the color
191 * anchored by P1.
192 */
193 public Color getColor1() {
194 return color1;
195 }
196
197 /**
198 * Returns a copy of the point P2 which anchors the second color.
199 * @return a {@link Point2D} object that is a copy of the point
200 * that anchors the second color of this
201 * <code>GradientPaint</code>.
202 */
203 public Point2D getPoint2() {
204 return new Point2D.Float(p2.x, p2.y);
205 }
206
207 /**
208 * Returns the color C2 anchored by the point P2.
209 * @return a <code>Color</code> object that is the color
210 * anchored by P2.
211 */
212 public Color getColor2() {
213 return color2;
214 }
215
216 /**
217 * Returns <code>true</code> if the gradient cycles repeatedly
218 * between the two colors C1 and C2.
219 * @return <code>true</code> if the gradient cycles repeatedly
220 * between the two colors; <code>false</code> otherwise.
221 */
222 public boolean isCyclic() {
223 return cyclic;
224 }
225
226 /**
227 * Creates and returns a {@link PaintContext} used to
228 * generate a linear color gradient pattern.
229 * See the {@link Paint#createContext specification} of the
230 * method in the {@link Paint} interface for information
231 * on null parameter handling.
232 *
233 * @param cm the preferred {@link ColorModel} which represents the most convenient
234 * format for the caller to receive the pixel data, or {@code null}
235 * if there is no preference.
236 * @param deviceBounds the device space bounding box
237 * of the graphics primitive being rendered.
238 * @param userBounds the user space bounding box
239 * of the graphics primitive being rendered.
240 * @param xform the {@link AffineTransform} from user
241 * space into device space.
242 * @param hints the set of hints that the context object can use to
243 * choose between rendering alternatives.
244 * @return the {@code PaintContext} for
245 * generating color patterns.
246 * @see Paint
247 * @see PaintContext
248 * @see ColorModel
249 * @see Rectangle
250 * @see Rectangle2D
251 * @see AffineTransform
252 * @see RenderingHints
253 */
254 public PaintContext createContext(ColorModel cm,
255 Rectangle deviceBounds,
256 Rectangle2D userBounds,
257 AffineTransform xform,
258 RenderingHints hints) {
259
260 return new GradientPaintContext(cm, p1, p2, xform,
261 color1, color2, cyclic);
262 }
263
264 /**
265 * Returns the transparency mode for this <code>GradientPaint</code>.
266 * @return an integer value representing this <code>GradientPaint</code>
267 * object's transparency mode.
268 * @see Transparency
269 */
270 public int getTransparency() {
271 int a1 = color1.getAlpha();
272 int a2 = color2.getAlpha();
273 return (((a1 & a2) == 0xff) ? OPAQUE : TRANSLUCENT);
274 }
275
276 }