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      */
GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2)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      */
GradientPaint(Point2D pt1, Color color1, Point2D pt2, Color color2)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      */
GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2, boolean cyclic)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" })
GradientPaint(Point2D pt1, Color color1, Point2D pt2, Color color2, boolean 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      */
getPoint1()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      */
getColor1()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      */
getPoint2()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      */
getColor2()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      */
isCyclic()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      */
createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints)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      */
getTransparency()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