/***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package com.kitfox.svg.batik; import java.awt.Color; import java.awt.PaintContext; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.ColorModel; /** * The LinearGradientPaint class provides a way to fill * a {@link java.awt.Shape} with a linear color gradient pattern. The user may * specify 2 or more gradient colors, and this paint will provide an * interpolation between each color. The user also specifies start and end * points which define where in user space the color gradient should begin * and end. *

* The user must provide an array of floats specifying how to distribute the * colors along the gradient. These values should range from 0.0 to 1.0 and * act like keyframes along the gradient (they mark where the gradient should * be exactly a particular color). *

* For example: *
* *

* Point2D start = new Point2D.Float(0, 0);
* Point2D end = new Point2D.Float(100,100);
* float[] dist = {0.0, 0.2, 1.0};
* Color[] colors = {Color.red, Color.white, Color.blue};
* LinearGradientPaint p = new LinearGradientPaint(start, end, dist, colors); *
*

* This code will create a LinearGradientPaint which interpolates between * red and white for the first 20% of the gradient and between white and blue * for the remaining 80%. * *

In the event that the user does not set the first keyframe value equal * to 0 and the last keyframe value equal to 1, keyframes will be created at * these positions and the first and last colors will be replicated there. * So, if a user specifies the following arrays to construct a gradient:
* {Color.blue, Color.red}, {.3, .7}
* this will be converted to a gradient with the following keyframes: * {Color.blue, Color.blue, Color.red, Color.red}, {0, .3, .7, 1} * *

* The user may also select what action the LinearGradientPaint should take * when filling color outside the start and end points. If no cycle method is * specified, NO_CYCLE will be chosen by default, so the endpoint colors * will be used to fill the remaining area. * *

The following image demonstrates the options NO_CYCLE and REFLECT. * *

* * *

The colorSpace parameter allows the user to specify in which colorspace * the interpolation should be performed, default sRGB or linearized RGB. * * * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans * @author Vincent Hardy * @version $Id: LinearGradientPaint.java,v 1.2 2004/09/27 09:27:27 kitfox Exp $ * @see java.awt.Paint * @see java.awt.Graphics2D#setPaint * */ public final class LinearGradientPaint extends MultipleGradientPaint { /** Gradient start and end points. */ private Point2D start, end; /**

* Constructs an LinearGradientPaint with the default * NO_CYCLE repeating method and SRGB colorspace. * * @param startX the x coordinate of the gradient axis start point * in user space * * @param startY the y coordinate of the gradient axis start point * in user space * * @param endX the x coordinate of the gradient axis end point * in user space * * @param endY the y coordinate of the gradient axis end point * in user space * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors corresponding to each fractional value * * * @throws IllegalArgumentException if start and end points are the * same points, or if fractions.length != colors.length, or if colors * is less than 2 in size. * */ public LinearGradientPaint(float startX, float startY, float endX, float endY, float[] fractions, Color[] colors) { this(new Point2D.Float(startX, startY), new Point2D.Float(endX, endY), fractions, colors, NO_CYCLE, SRGB); } /**

* Constructs an LinearGradientPaint with default SRGB * colorspace. * * @param startX the x coordinate of the gradient axis start point * in user space * * @param startY the y coordinate of the gradient axis start point * in user space * * @param endX the x coordinate of the gradient axis end point * in user space * * @param endY the y coordinate of the gradient axis end point * in user space * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors corresponding to each fractional value * * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT * * @throws IllegalArgumentException if start and end points are the * same points, or if fractions.length != colors.length, or if colors * is less than 2 in size. * */ public LinearGradientPaint(float startX, float startY, float endX, float endY, float[] fractions, Color[] colors, CycleMethodEnum cycleMethod) { this(new Point2D.Float(startX, startY), new Point2D.Float(endX, endY), fractions, colors, cycleMethod, SRGB); } /**

* Constructs a LinearGradientPaint with the default * NO_CYCLE repeating method and SRGB colorspace. * * @param start the gradient axis start Point in user space * * @param end the gradient axis end Point in user space * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors corresponding to each fractional value * * @throws NullPointerException if one of the points is null * * @throws IllegalArgumentException if start and end points are the * same points, or if fractions.length != colors.length, or if colors * is less than 2 in size. * */ public LinearGradientPaint(Point2D start, Point2D end, float[] fractions, Color[] colors) { this(start, end, fractions, colors, NO_CYCLE, SRGB); } /**

* Constructs a LinearGradientPaint. * * @param start the gradient axis start Point in user space * * @param end the gradient axis end Point in user space * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors corresponding to each fractional value * * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT * * @param colorSpace which colorspace to use for interpolation, * either SRGB or LINEAR_RGB * * @throws NullPointerException if one of the points is null * * @throws IllegalArgumentException if start and end points are the * same points, or if fractions.length != colors.length, or if colors * is less than 2 in size. * */ public LinearGradientPaint(Point2D start, Point2D end, float[] fractions, Color[] colors, CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace) { this(start, end, fractions, colors, cycleMethod, colorSpace, new AffineTransform()); } /**

* Constructs a LinearGradientPaint. * * @param start the gradient axis start Point in user space * * @param end the gradient axis end Point in user space * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors corresponding to each fractional value * * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT * * @param colorSpace which colorspace to use for interpolation, * either SRGB or LINEAR_RGB * * @param gradientTransform transform to apply to the gradient * * @throws NullPointerException if one of the points is null, * or gradientTransform is null * * @throws IllegalArgumentException if start and end points are the * same points, or if fractions.length != colors.length, or if colors * is less than 2 in size. * */ public LinearGradientPaint(Point2D start, Point2D end, float[] fractions, Color[] colors, CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace, AffineTransform gradientTransform) { super(fractions, colors, cycleMethod, colorSpace, gradientTransform); // // Check input parameters // if (start == null || end == null) { throw new NullPointerException("Start and end points must be" + "non-null"); } if (start.equals(end)) { throw new IllegalArgumentException("Start point cannot equal" + "endpoint"); } //copy the points... this.start = (Point2D)start.clone(); this.end = (Point2D)end.clone(); } /** * Creates and returns a PaintContext used to generate the color pattern, * for use by the internal rendering engine. * * @param cm {@link ColorModel} that receives * the Paint data. This is used only as a hint. * * @param deviceBounds the device space bounding box of the * graphics primitive being rendered * * @param userBounds the user space bounding box of the * graphics primitive being rendered * * @param transform the {@link AffineTransform} from user * space into device space * * @param hints the hints that the context object uses to choose * between rendering alternatives * * @return the {@link PaintContext} that generates color patterns. * * @see PaintContext */ public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform transform, RenderingHints hints) { // Can't modify the transform passed in... transform = new AffineTransform(transform); //incorporate the gradient transform transform.concatenate(gradientTransform); try { return new LinearGradientPaintContext(cm, deviceBounds, userBounds, transform, hints, start, end, fractions, this.getColors(), cycleMethod, colorSpace); } catch(NoninvertibleTransformException e) { e.printStackTrace(); throw new IllegalArgumentException("transform should be" + "invertible"); } } /** * Returns a copy of the start point of the gradient axis * @return a {@link Point2D} object that is a copy of the point * that anchors the first color of this * LinearGradientPaint. */ public Point2D getStartPoint() { return new Point2D.Double(start.getX(), start.getY()); } /** Returns a copy of the end point of the gradient axis * @return a {@link Point2D} object that is a copy of the point * that anchors the last color of this * LinearGradientPaint. */ public Point2D getEndPoint() { return new Point2D.Double(end.getX(), end.getY()); } }