001: /*
002:
003: Copyright 2001-2003 The Apache Software Foundation
004:
005: Licensed under the Apache License, Version 2.0 (the "License");
006: you may not use this file except in compliance with the License.
007: You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016:
017: */
018: package com.xoetrope.batik.ext.awt;
019:
020: import java.awt.Color;
021: import java.awt.PaintContext;
022: import java.awt.Rectangle;
023: import java.awt.RenderingHints;
024: import java.awt.geom.AffineTransform;
025: import java.awt.geom.NoninvertibleTransformException;
026: import java.awt.geom.Point2D;
027: import java.awt.geom.Rectangle2D;
028: import java.awt.image.ColorModel;
029:
030: /**
031: * The <code>LinearGradientPaint</code> class provides a way to fill
032: * a {@link java.awt.Shape} with a linear color gradient pattern. The user may
033: * specify 2 or more gradient colors, and this paint will provide an
034: * interpolation between each color. The user also specifies start and end
035: * points which define where in user space the color gradient should begin
036: * and end.
037: * <p>
038: * The user must provide an array of floats specifying how to distribute the
039: * colors along the gradient. These values should range from 0.0 to 1.0 and
040: * act like keyframes along the gradient (they mark where the gradient should
041: * be exactly a particular color).
042: * <p>
043: * For example:
044: * <br>
045: * <code>
046: * <p>
047: * Point2D start = new Point2D.Float(0, 0);<br>
048: * Point2D end = new Point2D.Float(100,100);<br>
049: * float[] dist = {0.0, 0.2, 1.0};<br>
050: * Color[] colors = {Color.red, Color.white, Color.blue};<br>
051: * LinearGradientPaint p = new LinearGradientPaint(start, end, dist, colors);
052: * </code>
053: *<p>
054: * This code will create a LinearGradientPaint which interpolates between
055: * red and white for the first 20% of the gradient and between white and blue
056: * for the remaining 80%.
057: *
058: * <p> In the event that the user does not set the first keyframe value equal
059: * to 0 and the last keyframe value equal to 1, keyframes will be created at
060: * these positions and the first and last colors will be replicated there.
061: * So, if a user specifies the following arrays to construct a gradient:<br>
062: * {Color.blue, Color.red}, {.3, .7}<br>
063: * this will be converted to a gradient with the following keyframes:
064: * {Color.blue, Color.blue, Color.red, Color.red}, {0, .3, .7, 1}
065: *
066: * <p>
067: * The user may also select what action the LinearGradientPaint should take
068: * when filling color outside the start and end points. If no cycle method is
069: * specified, NO_CYCLE will be chosen by default, so the endpoint colors
070: * will be used to fill the remaining area.
071: *
072: * <p> The following image demonstrates the options NO_CYCLE and REFLECT.
073: *
074: * <p>
075: * <img src = "cyclic.jpg">
076: *
077: * <p> The colorSpace parameter allows the user to specify in which colorspace
078: * the interpolation should be performed, default sRGB or linearized RGB.
079: *
080: *
081: * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
082: * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
083: * @version $Id: LinearGradientPaint.java,v 1.2 2006/08/31 09:28:43 val Exp $
084: * @see java.awt.Paint
085: * @see java.awt.Graphics2D#setPaint
086: *
087: */
088: public final class LinearGradientPaint extends MultipleGradientPaint {
089:
090: /** Gradient start and end points. */
091: private Point2D start, end;
092:
093: /**<p>
094: * Constructs an <code>LinearGradientPaint</code> with the default
095: * NO_CYCLE repeating method and SRGB colorspace.
096: *
097: * @param startX the x coordinate of the gradient axis start point
098: * in user space
099: *
100: * @param startY the y coordinate of the gradient axis start point
101: * in user space
102: *
103: * @param endX the x coordinate of the gradient axis end point
104: * in user space
105: *
106: * @param endY the y coordinate of the gradient axis end point
107: * in user space
108: *
109: * @param fractions numbers ranging from 0.0 to 1.0 specifying the
110: * distribution of colors along the gradient
111: *
112: * @param colors array of colors corresponding to each fractional value
113: *
114: *
115: * @throws IllegalArgumentException if start and end points are the
116: * same points, or if fractions.length != colors.length, or if colors
117: * is less than 2 in size.
118: *
119: */
120: public LinearGradientPaint(float startX, float startY, float endX,
121: float endY, float[] fractions, Color[] colors) {
122:
123: this (new Point2D.Float(startX, startY), new Point2D.Float(endX,
124: endY), fractions, colors, NO_CYCLE, SRGB);
125: }
126:
127: /**<p>
128: * Constructs an <code>LinearGradientPaint</code> with default SRGB
129: * colorspace.
130: *
131: * @param startX the x coordinate of the gradient axis start point
132: * in user space
133: *
134: * @param startY the y coordinate of the gradient axis start point
135: * in user space
136: *
137: * @param endX the x coordinate of the gradient axis end point
138: * in user space
139: *
140: * @param endY the y coordinate of the gradient axis end point
141: * in user space
142: *
143: * @param fractions numbers ranging from 0.0 to 1.0 specifying the
144: * distribution of colors along the gradient
145: *
146: * @param colors array of colors corresponding to each fractional value
147: *
148: * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
149: *
150: * @throws IllegalArgumentException if start and end points are the
151: * same points, or if fractions.length != colors.length, or if colors
152: * is less than 2 in size.
153: *
154: */
155: public LinearGradientPaint(float startX, float startY, float endX,
156: float endY, float[] fractions, Color[] colors,
157: CycleMethodEnum cycleMethod) {
158: this (new Point2D.Float(startX, startY), new Point2D.Float(endX,
159: endY), fractions, colors, cycleMethod, SRGB);
160: }
161:
162: /**<p>
163: * Constructs a <code>LinearGradientPaint</code> with the default
164: * NO_CYCLE repeating method and SRGB colorspace.
165: *
166: * @param start the gradient axis start <code>Point</code> in user space
167: *
168: * @param end the gradient axis end <code>Point</code> in user space
169: *
170: * @param fractions numbers ranging from 0.0 to 1.0 specifying the
171: * distribution of colors along the gradient
172: *
173: * @param colors array of colors corresponding to each fractional value
174: *
175: * @throws NullPointerException if one of the points is null
176: *
177: * @throws IllegalArgumentException if start and end points are the
178: * same points, or if fractions.length != colors.length, or if colors
179: * is less than 2 in size.
180: *
181: */
182: public LinearGradientPaint(Point2D start, Point2D end,
183: float[] fractions, Color[] colors) {
184:
185: this (start, end, fractions, colors, NO_CYCLE, SRGB);
186: }
187:
188: /**<p>
189: * Constructs a <code>LinearGradientPaint</code>.
190: *
191: * @param start the gradient axis start <code>Point</code> in user space
192: *
193: * @param end the gradient axis end <code>Point</code> in user space
194: *
195: * @param fractions numbers ranging from 0.0 to 1.0 specifying the
196: * distribution of colors along the gradient
197: *
198: * @param colors array of colors corresponding to each fractional value
199: *
200: * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
201: *
202: * @param colorSpace which colorspace to use for interpolation,
203: * either SRGB or LINEAR_RGB
204: *
205: * @throws NullPointerException if one of the points is null
206: *
207: * @throws IllegalArgumentException if start and end points are the
208: * same points, or if fractions.length != colors.length, or if colors
209: * is less than 2 in size.
210: *
211: */
212: public LinearGradientPaint(Point2D start, Point2D end,
213: float[] fractions, Color[] colors,
214: CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace) {
215:
216: this (start, end, fractions, colors, cycleMethod, colorSpace,
217: new AffineTransform());
218:
219: }
220:
221: /**<p>
222: * Constructs a <code>LinearGradientPaint</code>.
223: *
224: * @param start the gradient axis start <code>Point</code> in user space
225: *
226: * @param end the gradient axis end <code>Point</code> in user space
227: *
228: * @param fractions numbers ranging from 0.0 to 1.0 specifying the
229: * distribution of colors along the gradient
230: *
231: * @param colors array of colors corresponding to each fractional value
232: *
233: * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
234: *
235: * @param colorSpace which colorspace to use for interpolation,
236: * either SRGB or LINEAR_RGB
237: *
238: * @param gradientTransform transform to apply to the gradient
239: *
240: * @throws NullPointerException if one of the points is null,
241: * or gradientTransform is null
242: *
243: * @throws IllegalArgumentException if start and end points are the
244: * same points, or if fractions.length != colors.length, or if colors
245: * is less than 2 in size.
246: *
247: */
248: public LinearGradientPaint(Point2D start, Point2D end,
249: float[] fractions, Color[] colors,
250: CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace,
251: AffineTransform gradientTransform) {
252: super (fractions, colors, cycleMethod, colorSpace,
253: gradientTransform);
254:
255: //
256: // Check input parameters
257: //
258: if (start == null || end == null) {
259: throw new NullPointerException(
260: "Start and end points must be" + "non-null");
261: }
262:
263: if (start.equals(end)) {
264: throw new IllegalArgumentException(
265: "Start point cannot equal" + "endpoint");
266: }
267:
268: //copy the points...
269: this .start = (Point2D) start.clone();
270:
271: this .end = (Point2D) end.clone();
272:
273: }
274:
275: /**
276: * Creates and returns a PaintContext used to generate the color pattern,
277: * for use by the internal rendering engine.
278: *
279: * @param cm {@link ColorModel} that receives
280: * the <code>Paint</code> data. This is used only as a hint.
281: *
282: * @param deviceBounds the device space bounding box of the
283: * graphics primitive being rendered
284: *
285: * @param userBounds the user space bounding box of the
286: * graphics primitive being rendered
287: *
288: * @param transform the {@link AffineTransform} from user
289: * space into device space
290: *
291: * @param hints the hints that the context object uses to choose
292: * between rendering alternatives
293: *
294: * @return the {@link PaintContext} that generates color patterns.
295: *
296: * @see PaintContext
297: */
298: public PaintContext createContext(ColorModel cm,
299: Rectangle deviceBounds, Rectangle2D userBounds,
300: AffineTransform transform, RenderingHints hints) {
301:
302: // Can't modify the transform passed in...
303: transform = new AffineTransform(transform);
304: //incorporate the gradient transform
305: transform.concatenate(gradientTransform);
306:
307: try {
308: return new LinearGradientPaintContext(cm, deviceBounds,
309: userBounds, transform, hints, start, end,
310: fractions, this .getColors(), cycleMethod,
311: colorSpace);
312: }
313:
314: catch (NoninvertibleTransformException e) {
315: e.printStackTrace();
316: throw new IllegalArgumentException("transform should be"
317: + "invertible");
318: }
319: }
320:
321: /**
322: * Returns a copy of the start point of the gradient axis
323: * @return a {@link Point2D} object that is a copy of the point
324: * that anchors the first color of this
325: * <code>LinearGradientPaint</code>.
326: */
327: public Point2D getStartPoint() {
328: return new Point2D.Double(start.getX(), start.getY());
329: }
330:
331: /** Returns a copy of the end point of the gradient axis
332: * @return a {@link Point2D} object that is a copy of the point
333: * that anchors the last color of this
334: * <code>LinearGradientPaint</code>.
335: */
336: public Point2D getEndPoint() {
337: return new Point2D.Double(end.getX(), end.getY());
338: }
339:
340: }
|