| /* |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| package org.apache.batik.ext.awt; |
| |
| 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; |
| |
| /** |
| * <p> |
| * 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. |
| * <p> |
| * |
| * 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). |
| * |
| * <p> |
| * 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. |
| * |
| * <p> |
| * 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. |
| * <p> |
| * |
| * 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. |
| * |
| * <p> |
| * The following code demonstrates typical usage of RadialGradientPaint: |
| * <p> |
| * <code> |
| * Point2D center = new Point2D.Float(0, 0);<br> |
| * float radius = 20; |
| * float[] dist = {0.0, 0.2, 1.0};<br> |
| * Color[] colors = {Color.red, Color.white, Color.blue};<br> |
| * RadialGradientPaint p = new RadialGradientPaint(center, radius, |
| * dist, colors); |
| * </code> |
| * |
| * <p> 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:<br> |
| * {Color.blue, Color.red}, {.3, .7}<br> |
| * this will be converted to a gradient with the following keyframes: |
| * {Color.blue, Color.blue, Color.red, Color.red}, {0, .3, .7, 1} |
| * |
| * |
| * <p> |
| * <img src = "radial.jpg"> |
| * <p> |
| * This image demonstrates a radial gradient with NO_CYCLE and default focus. |
| * <p> |
| * |
| * <img src = "radial2.jpg"> |
| * <p> |
| * This image demonstrates a radial gradient with NO_CYCLE and non-centered |
| * focus. |
| * <p> |
| * |
| * <img src = "radial3.jpg"> |
| * <p> |
| * This image demonstrates a radial gradient with REFLECT and non-centered |
| * focus. |
| * |
| * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans |
| * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a> |
| * @version $Id$ |
| * |
| */ |
| 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; |
| |
| /** |
| * <p> |
| * |
| * Constructs a <code>RadialGradientPaint</code>, 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); |
| } |
| |
| /** |
| * <p> |
| * |
| * Constructs a <code>RadialGradientPaint</code>, 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); |
| } |
| |
| /** |
| * <p> |
| * |
| * Constructs a <code>RadialGradientPaint</code>. |
| * |
| * @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); |
| } |
| |
| /** |
| * <p> |
| * |
| * Constructs a <code>RadialGradientPaint</code>. |
| * |
| * @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); |
| } |
| |
| /** |
| * <p> |
| * |
| * Constructs a <code>RadialGradientPaint</code>. |
| * |
| * @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()); |
| } |
| |
| /** |
| * <p> |
| * |
| * Constructs a <code>RadialGradientPaint</code>. |
| * |
| * @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; |
| } |
| |
| /** |
| * <p> |
| * |
| * Constructs a <code>RadialGradientPaint</code>, 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); |
| } |
| |
| |
| /** <p> |
| * 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 <code>Paint</code> 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; |
| } |
| } |