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 trueif 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 trueif 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 trueif the gradient cycles repeatedly
220      * between the two colors C1 and C2.
221      * @return {@code trueif 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