/***************************************************************************** * 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; /** *

* This class provides a way to fill a shape with a circular radial color * gradient pattern. The user may specify 2 or more gradient colors, and this * paint will provide an interpolation between each color. *

* * 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). * *

* This paint will map the first color of the gradient to a focus point within * the circle, and the last color to the perimeter of the circle, interpolating * smoothly for any inbetween colors specified by the user. Any line drawn * from the focus point to the circumference will span the all the gradient * colors. By default the focus is set to be the center of the circle. * *

* Specifying a focus point outside of the circle's radius will result in the * focus being set to the intersection point of the focus-center line and the * perimenter of the circle. *

* * Specifying a cycle method allows the user to control the painting behavior * outside of the bounds of the circle's radius. See LinearGradientPaint for * more details. * *

* The following code demonstrates typical usage of RadialGradientPaint: *

* * Point2D center = new Point2D.Float(0, 0);
* float radius = 20; * float[] dist = {0.0, 0.2, 1.0};
* Color[] colors = {Color.red, Color.white, Color.blue};
* RadialGradientPaint p = new RadialGradientPaint(center, radius, * dist, colors); *
* *

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} * * *

* *

* This image demonstrates a radial gradient with NO_CYCLE and default focus. *

* * *

* This image demonstrates a radial gradient with NO_CYCLE and non-centered * focus. *

* * *

* This image demonstrates a radial gradient with REFLECT and non-centered * focus. * * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans * @author Vincent Hardy * @version $Id: RadialGradientPaint.java,v 1.1 2004/09/06 19:35:39 kitfox Exp $ * */ public final class RadialGradientPaint extends MultipleGradientPaint { /** Focus point which defines the 0% gradient stop x coordinate. */ private Point2D focus; /** Center of the circle defining the 100% gradient stop x coordinate. */ private Point2D center; /** Radius of the outermost circle defining the 100% gradient stop. */ private float radius; /** *

* * Constructs a RadialGradientPaint, using the center as the * focus point. * * @param cx the x coordinate in user space of the center point of the * circle defining the gradient. The last color of the gradient is mapped * to the perimeter of this circle * * @param cy the y coordinate in user space of the center point of the * circle defining the gradient. The last color of the gradient is mapped * to the perimeter of this circle * * @param radius the radius of the circle defining the extents of the * color gradient * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors to use in the gradient. The first color * is used at the focus point, the last color around the perimeter of the * circle. * * * @throws IllegalArgumentException * if fractions.length != colors.length, or if colors is less * than 2 in size, or if radius < 0 * * */ public RadialGradientPaint(float cx, float cy, float radius, float[] fractions, Color[] colors) { this(cx, cy, radius, cx, cy, fractions, colors); } /** *

* * Constructs a RadialGradientPaint, using the center as the * focus point. * * @param center the center point, in user space, of the circle defining * the gradient * * @param radius the radius of the circle defining the extents of the * color gradient * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors to use in the gradient. The first color * is used at the focus point, the last color around the perimeter of the * circle. * * @throws NullPointerException if center point is null * * @throws IllegalArgumentException * if fractions.length != colors.length, or if colors is less * than 2 in size, or if radius < 0 * * */ public RadialGradientPaint(Point2D center, float radius, float[] fractions, Color[] colors) { this(center, radius, center, fractions, colors); } /** *

* * Constructs a RadialGradientPaint. * * @param cx the x coordinate in user space of the center point of the * circle defining the gradient. The last color of the gradient is mapped * to the perimeter of this circle * * @param cy the y coordinate in user space of the center point of the * circle defining the gradient. The last color of the gradient is mapped * to the perimeter of this circle * * @param radius the radius of the circle defining the extents of the * color gradient * * @param fx the x coordinate of the point in user space to which the * first color is mapped * * @param fy the y coordinate of the point in user space to which the * first color is mapped * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors to use in the gradient. The first color * is used at the focus point, the last color around the perimeter of the * circle. * * @throws IllegalArgumentException * if fractions.length != colors.length, or if colors is less * than 2 in size, or if radius < 0 * * */ public RadialGradientPaint(float cx, float cy, float radius, float fx, float fy, float[] fractions, Color[] colors) { this(new Point2D.Float(cx, cy), radius, new Point2D.Float(fx, fy), fractions, colors, NO_CYCLE, SRGB); } /** *

* * Constructs a RadialGradientPaint. * * @param center the center point, in user space, of the circle defining * the gradient. The last color of the gradient is mapped to the perimeter * of this circle * * @param radius the radius of the circle defining the extents of the color * gradient * * @param focus the point, in user space, to which the first color is * mapped * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors to use in the gradient. The first color * is used at the focus point, the last color around the perimeter of the * circle. * * @throws NullPointerException if one of the points is null * * @throws IllegalArgumentException * if fractions.length != colors.length, or if colors is less * than 2 in size, or if radius < 0 * */ public RadialGradientPaint(Point2D center, float radius, Point2D focus, float[] fractions, Color[] colors) { this(center, radius, focus, fractions, colors, NO_CYCLE, SRGB); } /** *

* * Constructs a RadialGradientPaint. * * @param center the center point in user space of the circle defining the * gradient. The last color of the gradient is mapped to the perimeter of * this circle * * @param radius the radius of the circle defining the extents of the color * gradient * * @param focus the point in user space to which the first color is mapped * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors to use in the gradient. The first color is * used at the focus point, the last color around the perimeter of the * circle. * * @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 fractions.length != colors.length, or if colors is less * than 2 in size, or if radius < 0 * */ public RadialGradientPaint(Point2D center, float radius, Point2D focus, float[] fractions, Color[] colors, CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace) { this(center, radius, focus, fractions, colors, cycleMethod, colorSpace, new AffineTransform()); } /** *

* * Constructs a RadialGradientPaint. * * @param center the center point in user space of the circle defining the * gradient. The last color of the gradient is mapped to the perimeter of * this circle * * @param radius the radius of the circle defining the extents of the color * gradient. * * @param focus the point in user space to which the first color is mapped * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors to use in the gradient. The first color is * used at the focus point, the last color around the perimeter of the * circle. * * @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 fractions.length != colors.length, or if colors is less * than 2 in size, or if radius < 0 * */ public RadialGradientPaint(Point2D center, float radius, Point2D focus, float[] fractions, Color[] colors, CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace, AffineTransform gradientTransform){ super(fractions, colors, cycleMethod, colorSpace, gradientTransform); // Check input arguments if (center == null) { throw new NullPointerException("Center point should not be null."); } if (focus == null) { throw new NullPointerException("Focus point should not be null."); } if (radius <= 0) { throw new IllegalArgumentException("radius should be greater than zero"); } //copy parameters this.center = (Point2D)center.clone(); this.focus = (Point2D)focus.clone(); this.radius = radius; } /** *

* * Constructs a RadialGradientPaint, the gradient circle is * defined by a bounding box. * * @param gradientBounds the bounding box, in user space, of the circle * defining outermost extent of the gradient. * * @param fractions numbers ranging from 0.0 to 1.0 specifying the * distribution of colors along the gradient * * @param colors array of colors to use in the gradient. The first color * is used at the focus point, the last color around the perimeter of the * circle. * * @throws NullPointerException if the gradientBounds is null * * @throws IllegalArgumentException * if fractions.length != colors.length, or if colors is less * than 2 in size, or if radius < 0 * */ public RadialGradientPaint(Rectangle2D gradientBounds, float[] fractions, Color[] colors) { //calculate center point and radius based on bounding box coordinates. this((float)gradientBounds.getX() + ( (float)gradientBounds.getWidth() / 2), (float)gradientBounds.getY() + ( (float)gradientBounds.getWidth() / 2), (float)gradientBounds.getWidth() / 2, fractions, colors); } /**

* 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. * * @throws IllegalArgumentException if the transform is not invertible * * @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 RadialGradientPaintContext (cm, deviceBounds, userBounds, transform, hints, (float)center.getX(), (float)center.getY(), radius, (float)focus.getX(), (float)focus.getY(), fractions, colors, cycleMethod, colorSpace); } catch(NoninvertibleTransformException e){ throw new IllegalArgumentException("transform should be " + "invertible"); } } /** * Returns a copy of the center point of the radial gradient. * @return a {@link Point2D} object that is a copy of the center point */ public Point2D getCenterPoint() { return new Point2D.Double(center.getX(), center.getY()); } /** Returns a copy of the end point of the gradient axis. * @return a {@link Point2D} object that is a copy of the focus point */ public Point2D getFocusPoint() { return new Point2D.Double(focus.getX(), focus.getY()); } /** Returns the radius of the circle defining the radial gradient. * @return the radius of the circle defining the radial gradient */ public float getRadius() { return radius; } }