/* * Copyright 2006-2017 ICEsoft Technologies Canada Corp. * * Licensed 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.icepdf.core.pobjects.graphics.batik.ext.awt; import java.awt.*; 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; /** * <br> * 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. * <br> * <br> * 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). * <br> * <br> * 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. * <br> * <br> * 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. * <br> * <br> * 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. * <br> * <br> * The following code demonstrates typical usage of RadialGradientPaint: * <br> * <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> * <br> * <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} * <br> * <br> * <br> * <img src = "radial.jpg" alt=""> * <br> * This image demonstrates a radial gradient with NO_CYCLE and default focus. * <br> * <br> * <img src = "radial2.jpg" alt=""> * <br> * This image demonstrates a radial gradient with NO_CYCLE and non-centered * focus. * <br> * <br> * <img src = "radial3.jpg" alt=""> * <br> * 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: RadialGradientPaint.java,v 1.1 2008/09/30 20:44:16 patrickc 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; /** * <br> * <br> * 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); } /** * <br> * <br> * 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); } /** * <br> * <br> * 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); } /** * <br> * <br> * 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); } /** * <br> * <br> * 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()); } /** * <br> * <br> * 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; } /** * <br> * <br> * 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); } /** * 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; } }