001    /* GradientPaint.java -- 
002       Copyright (C) 2002, 2005, Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package java.awt;
040    
041    import java.awt.geom.AffineTransform;
042    import java.awt.geom.Point2D;
043    import java.awt.geom.Rectangle2D;
044    import java.awt.image.ColorModel;
045    import gnu.java.awt.GradientPaintContext;
046    
047    /**
048     * A paint object that can be used to color a region by blending two colors. 
049     * Instances of this class are immutable.
050     */
051    public class GradientPaint implements Paint
052    {
053      private final float x1;
054      private final float y1;
055      private final Color c1;
056      private final float x2;
057      private final float y2;
058      private final Color c2;
059      private final boolean cyclic;
060    
061      /**
062       * Creates a new acyclic <code>GradientPaint</code>.
063       * 
064       * @param x1  the x-coordinate of the anchor point for color 1.
065       * @param y1  the y-coordinate of the anchor point for color 1.
066       * @param c1  color 1 (<code>null</code> not permitted).
067       * @param x2  the x-coordinate of the anchor point for color 2.
068       * @param y2  the y-coordinate of the anchor point for color 2.
069       * @param c2  the second color (<code>null</code> not permitted).
070       */
071      public GradientPaint(float x1, float y1, Color c1,
072                           float x2, float y2, Color c2)
073      {
074        this(x1, y1, c1, x2, y2, c2, false);
075      }
076    
077      /**
078       * Creates a new acyclic <code>GradientPaint</code>.
079       * 
080       * @param p1  anchor point 1 (<code>null</code> not permitted).
081       * @param c1  color 1 (<code>null</code> not permitted).
082       * @param p2  anchor point 2 (<code>null</code> not permitted).
083       * @param c2  color 2 (<code>null</code> not permitted).
084       */
085      public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2)
086      {
087        this((float) p1.getX(), (float) p1.getY(), c1,
088             (float) p2.getX(), (float) p2.getY(), c2, false);
089      }
090    
091      /**
092       * Creates a new cyclic or acyclic <code>GradientPaint</code>.
093       * 
094       * @param x1  the x-coordinate of the anchor point for color 1.
095       * @param y1  the y-coordinate of the anchor point for color 1.
096       * @param c1  color 1 (<code>null</code> not permitted).
097       * @param x2  the x-coordinate of the anchor point for color 2.
098       * @param y2  the y-coordinate of the anchor point for color 2.
099       * @param c2  the second color (<code>null</code> not permitted).
100       * @param cyclic  a flag that controls whether the gradient is cyclic or
101       *                acyclic.
102       */
103      public GradientPaint(float x1, float y1, Color c1,
104                           float x2, float y2, Color c2, boolean cyclic)
105      {
106        if (c1 == null || c2 == null)
107          throw new NullPointerException();
108        this.x1 = x1;
109        this.y1 = y1;
110        this.c1 = c1;
111        this.x2 = x2;
112        this.y2 = y2;
113        this.c2 = c2;
114        this.cyclic = cyclic;
115      }
116    
117      /**
118       * Creates a new cyclic or acyclic <code>GradientPaint</code>.
119       * 
120       * @param p1  anchor point 1 (<code>null</code> not permitted).
121       * @param c1  color 1 (<code>null</code> not permitted).
122       * @param p2  anchor point 2 (<code>null</code> not permitted).
123       * @param c2  color 2 (<code>null</code> not permitted).
124       * @param cyclic  a flag that controls whether the gradient is cyclic or
125       *                acyclic.
126       */
127      public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2,
128                           boolean cyclic)
129      {
130        this((float) p1.getX(), (float) p1.getY(), c1,
131             (float) p2.getX(), (float) p2.getY(), c2, cyclic);
132      }
133    
134      /**
135       * Returns a point with the same coordinates as the anchor point for color 1.
136       * Note that if you modify this point, the <code>GradientPaint</code> remains
137       * unchanged.
138       * 
139       * @return A point with the same coordinates as the anchor point for color 1.
140       */
141      public Point2D getPoint1()
142      {
143        return new Point2D.Float(x1, y1);
144      }
145    
146      /**
147       * Returns the first color.
148       * 
149       * @return The color (never <code>null</code>).
150       */
151      public Color getColor1()
152      {
153        return c1;
154      }
155    
156      /**
157       * Returns a point with the same coordinates as the anchor point for color 2.
158       * Note that if you modify this point, the <code>GradientPaint</code> remains
159       * unchanged.
160       * 
161       * @return A point with the same coordinates as the anchor point for color 2.
162       */
163      public Point2D getPoint2()
164      {
165        return new Point2D.Float(x2, y2);
166      }
167    
168      /**
169       * Returns the second color.
170       * 
171       * @return The color (never <code>null</code>).
172       */
173      public Color getColor2()
174      {
175        return c2;
176      }
177    
178      /**
179       * Returns <code>true</code> if this <code>GradientPaint</code> instance is
180       * cyclic, and <code>false</code> otherwise.
181       * 
182       * @return A boolean.
183       */
184      public boolean isCyclic()
185      {
186        return cyclic;
187      }
188    
189      /**
190       * Returns the {@link PaintContext} used to generate the color pattern.
191       * 
192       * @param cm  the color model, used as a hint (ignored in this 
193       *            implementation).
194       * @param deviceBounds  the device space bounding box of the painted area.
195       * @param userBounds  the user space bounding box of the painted area.
196       * @param xform  the transformation from user space to device space.
197       * @param hints  any hints for choosing between rendering alternatives.
198       * 
199       * @return The context for performing the paint
200       */
201      public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
202                                        Rectangle2D userBounds,
203                                        AffineTransform xform,
204                                        RenderingHints hints)
205      {
206        Point2D xp1 = xform.transform(getPoint1(), null);
207        Point2D xp2 = xform.transform(getPoint2(), null);
208        return new GradientPaintContext((float) xp1.getX(), (float) xp1.getY(), c1, 
209                (float) xp2.getX(), (float) xp2.getY(), c2, cyclic);
210      }
211    
212      /**
213       * Returns the transparency code for this <code>GradientPaint</code> instance.
214       * This is derived from the two {@link Color} objects used in creating this
215       * object:  if both colors are opaque, this method returns 
216       * {@link Transparency#OPAQUE}, otherwise it returns 
217       * {@link Transparency#TRANSLUCENT}.
218       * 
219       * @return {@link Transparency#OPAQUE} or {@link Transparency#TRANSLUCENT}.
220       */
221      public int getTransparency()
222      {
223        if (c1.getAlpha() == 255 && c2.getAlpha() == 255)
224          return Transparency.OPAQUE;
225        else
226          return Transparency.TRANSLUCENT;   
227      }
228      
229    } // class GradientPaint