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 }