1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * 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 import java.beans.ConstructorProperties;
33
34 /**
35 * The {@code GradientPaint} class provides a way to fill
36 * a {@link Shape} with a linear color gradient pattern.
37 * If {@link Point} P1 with {@link Color} C1 and {@code Point} P2 with
38 * {@code Color} C2 are specified in user space, the
39 * {@code Color} on the P1, P2 connecting line is proportionally
40 * changed from C1 to C2. Any point P not on the extended P1, P2
41 * connecting line has the color of the point P' that is the perpendicular
42 * projection of P on the extended P1, P2 connecting line.
43 * Points on the extended line outside of the P1, P2 segment can be colored
44 * in one of two ways.
45 * <ul>
46 * <li>
47 * If the gradient is cyclic then the points on the extended P1, P2
48 * connecting line cycle back and forth between the colors C1 and C2.
49 * <li>
50 * If the gradient is acyclic then points on the P1 side of the segment
51 * have the constant {@code Color} C1 while points on the P2 side
52 * have the constant {@code Color} C2.
53 * </ul>
54 *
55 * @see Paint
56 * @see Graphics2D#setPaint
57 * @version 10 Feb 1997
58 */
59
60 public class GradientPaint implements Paint {
61 Point2D.Float p1;
62 Point2D.Float p2;
63 Color color1;
64 Color color2;
65 boolean cyclic;
66
67 /**
68 * Constructs a simple acyclic {@code GradientPaint} object.
69 * @param x1 x coordinate of the first specified
70 * {@code Point} in user space
71 * @param y1 y coordinate of the first specified
72 * {@code Point} in user space
73 * @param color1 {@code Color} at the first specified
74 * {@code Point}
75 * @param x2 x coordinate of the second specified
76 * {@code Point} in user space
77 * @param y2 y coordinate of the second specified
78 * {@code Point} in user space
79 * @param color2 {@code Color} at the second specified
80 * {@code Point}
81 * @throws NullPointerException if either one of colors is null
82 */
83 public GradientPaint(float x1,
84 float y1,
85 Color color1,
86 float x2,
87 float y2,
88 Color color2) {
89 if ((color1 == null) || (color2 == null)) {
90 throw new NullPointerException("Colors cannot be null");
91 }
92
93 p1 = new Point2D.Float(x1, y1);
94 p2 = new Point2D.Float(x2, y2);
95 this.color1 = color1;
96 this.color2 = color2;
97 }
98
99 /**
100 * Constructs a simple acyclic {@code GradientPaint} object.
101 * @param pt1 the first specified {@code Point} in user space
102 * @param color1 {@code Color} at the first specified
103 * {@code Point}
104 * @param pt2 the second specified {@code Point} in user space
105 * @param color2 {@code Color} at the second specified
106 * {@code Point}
107 * @throws NullPointerException if either one of colors or points
108 * is null
109 */
110 public GradientPaint(Point2D pt1,
111 Color color1,
112 Point2D pt2,
113 Color color2) {
114 if ((color1 == null) || (color2 == null) ||
115 (pt1 == null) || (pt2 == null)) {
116 throw new NullPointerException("Colors and points should be non-null");
117 }
118
119 p1 = new Point2D.Float((float)pt1.getX(), (float)pt1.getY());
120 p2 = new Point2D.Float((float)pt2.getX(), (float)pt2.getY());
121 this.color1 = color1;
122 this.color2 = color2;
123 }
124
125 /**
126 * Constructs either a cyclic or acyclic {@code GradientPaint}
127 * object depending on the {@code boolean} parameter.
128 * @param x1 x coordinate of the first specified
129 * {@code Point} in user space
130 * @param y1 y coordinate of the first specified
131 * {@code Point} in user space
132 * @param color1 {@code Color} at the first specified
133 * {@code Point}
134 * @param x2 x coordinate of the second specified
135 * {@code Point} in user space
136 * @param y2 y coordinate of the second specified
137 * {@code Point} in user space
138 * @param color2 {@code Color} at the second specified
139 * {@code Point}
140 * @param cyclic {@code true} if the gradient pattern should cycle
141 * repeatedly between the two colors; {@code false} otherwise
142 */
143 public GradientPaint(float x1,
144 float y1,
145 Color color1,
146 float x2,
147 float y2,
148 Color color2,
149 boolean cyclic) {
150 this (x1, y1, color1, x2, y2, color2);
151 this.cyclic = cyclic;
152 }
153
154 /**
155 * Constructs either a cyclic or acyclic {@code GradientPaint}
156 * object depending on the {@code boolean} parameter.
157 * @param pt1 the first specified {@code Point}
158 * in user space
159 * @param color1 {@code Color} at the first specified
160 * {@code Point}
161 * @param pt2 the second specified {@code Point}
162 * in user space
163 * @param color2 {@code Color} at the second specified
164 * {@code Point}
165 * @param cyclic {@code true} if the gradient pattern should cycle
166 * repeatedly between the two colors; {@code false} otherwise
167 * @throws NullPointerException if either one of colors or points
168 * is null
169 */
170 @ConstructorProperties({ "point1", "color1", "point2", "color2", "cyclic" })
171 public GradientPaint(Point2D pt1,
172 Color color1,
173 Point2D pt2,
174 Color color2,
175 boolean cyclic) {
176 this (pt1, color1, pt2, color2);
177 this.cyclic = cyclic;
178 }
179
180 /**
181 * Returns a copy of the point P1 that anchors the first color.
182 * @return a {@link Point2D} object that is a copy of the point
183 * that anchors the first color of this
184 * {@code GradientPaint}.
185 */
186 public Point2D getPoint1() {
187 return new Point2D.Float(p1.x, p1.y);
188 }
189
190 /**
191 * Returns the color C1 anchored by the point P1.
192 * @return a {@code Color} object that is the color
193 * anchored by P1.
194 */
195 public Color getColor1() {
196 return color1;
197 }
198
199 /**
200 * Returns a copy of the point P2 which anchors the second color.
201 * @return a {@link Point2D} object that is a copy of the point
202 * that anchors the second color of this
203 * {@code GradientPaint}.
204 */
205 public Point2D getPoint2() {
206 return new Point2D.Float(p2.x, p2.y);
207 }
208
209 /**
210 * Returns the color C2 anchored by the point P2.
211 * @return a {@code Color} object that is the color
212 * anchored by P2.
213 */
214 public Color getColor2() {
215 return color2;
216 }
217
218 /**
219 * Returns {@code true} if the gradient cycles repeatedly
220 * between the two colors C1 and C2.
221 * @return {@code true} if the gradient cycles repeatedly
222 * between the two colors; {@code false} otherwise.
223 */
224 public boolean isCyclic() {
225 return cyclic;
226 }
227
228 /**
229 * Creates and returns a {@link PaintContext} used to
230 * generate a linear color gradient pattern.
231 * See the {@link Paint#createContext specification} of the
232 * method in the {@link Paint} interface for information
233 * on null parameter handling.
234 *
235 * @param cm the preferred {@link ColorModel} which represents the most convenient
236 * format for the caller to receive the pixel data, or {@code null}
237 * if there is no preference.
238 * @param deviceBounds the device space bounding box
239 * of the graphics primitive being rendered.
240 * @param userBounds the user space bounding box
241 * of the graphics primitive being rendered.
242 * @param xform the {@link AffineTransform} from user
243 * space into device space.
244 * @param hints the set of hints that the context object can use to
245 * choose between rendering alternatives.
246 * @return the {@code PaintContext} for
247 * generating color patterns.
248 * @see Paint
249 * @see PaintContext
250 * @see ColorModel
251 * @see Rectangle
252 * @see Rectangle2D
253 * @see AffineTransform
254 * @see RenderingHints
255 */
256 public PaintContext createContext(ColorModel cm,
257 Rectangle deviceBounds,
258 Rectangle2D userBounds,
259 AffineTransform xform,
260 RenderingHints hints) {
261
262 return new GradientPaintContext(cm, p1, p2, xform,
263 color1, color2, cyclic);
264 }
265
266 /**
267 * Returns the transparency mode for this {@code GradientPaint}.
268 * @return an integer value representing this {@code GradientPaint}
269 * object's transparency mode.
270 * @see Transparency
271 */
272 public int getTransparency() {
273 int a1 = color1.getAlpha();
274 int a2 = color2.getAlpha();
275 return (((a1 & a2) == 0xff) ? OPAQUE : TRANSLUCENT);
276 }
277
278 }
279