/* Copyright 2001,2003 The Apache Software Foundation 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 ch.randelshofer.quaqua.ext.batik.ext.awt; import java.awt.Color; import java.awt.Paint; import java.awt.geom.AffineTransform; /** This is the superclass for Paints which use a multiple color * gradient to fill in their raster. It provides storage for variables and * enumerated values common to LinearGradientPaint and RadialGradientPaint. * * * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a> * @version $Id: MultipleGradientPaint.java,v 1.7 2005/03/27 08:58:32 cam Exp $ * */ public abstract class MultipleGradientPaint implements Paint { /** Transparency. */ protected int transparency; /** Gradient keyframe values in the range 0 to 1. */ protected float[] fractions; /** Gradient colors. */ protected Color[] colors; /** Transform to apply to gradient. */ protected AffineTransform gradientTransform; /** The method to use when painting out of the gradient bounds. */ protected CycleMethodEnum cycleMethod; /** The colorSpace in which to perform the interpolation. */ protected ColorSpaceEnum colorSpace; /** Inner class to allow for typesafe enumerated ColorSpace values. */ public static class ColorSpaceEnum { } /** Inner class to allow for typesafe enumerated CycleMethod values. */ public static class CycleMethodEnum { } /** Indicates (if the gradient starts or ends inside the target region) * to use the terminal colors to fill the remaining area. (default) */ public static final CycleMethodEnum NO_CYCLE = new CycleMethodEnum(); /** Indicates (if the gradient starts or ends inside the target region), * to cycle the gradient colors start-to-end, end-to-start to fill the * remaining area. */ public static final CycleMethodEnum REFLECT = new CycleMethodEnum(); /** Indicates (if the gradient starts or ends inside the target region), * to cycle the gradient colors start-to-end, start-to-end to fill the * remaining area. */ public static final CycleMethodEnum REPEAT = new CycleMethodEnum(); /** Indicates that the color interpolation should occur in sRGB space. * (default) */ public static final ColorSpaceEnum SRGB = new ColorSpaceEnum(); /** Indicates that the color interpolation should occur in linearized * RGB space. */ public static final ColorSpaceEnum LINEAR_RGB = new ColorSpaceEnum(); /** * Superclass constructor, typical user should never have to call this. * * @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 arrays are null, or * gradientTransform is null * * @throws IllegalArgumentException if fractions.length != colors.length, * or if colors is less than 2 in size, or if an enumerated value is bad. */ public MultipleGradientPaint(float[] fractions, Color[] colors, CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace, AffineTransform gradientTransform) { if (fractions == null) { throw new IllegalArgumentException("Fractions array cannot be " + "null"); } if (colors == null) { throw new IllegalArgumentException("Colors array cannot be null"); } if (fractions.length != colors.length) { throw new IllegalArgumentException("Colors and fractions must " + "have equal size"); } if (colors.length < 2) { throw new IllegalArgumentException("User must specify at least " + "2 colors"); } if ((colorSpace != LINEAR_RGB) && (colorSpace != SRGB)) { throw new IllegalArgumentException("Invalid colorspace for " + "interpolation."); } if ((cycleMethod != NO_CYCLE) && (cycleMethod != REFLECT) && (cycleMethod != REPEAT)) { throw new IllegalArgumentException("Invalid cycle method."); } if (gradientTransform == null) { throw new IllegalArgumentException("Gradient transform cannot be "+ "null."); } //copy the fractions array this.fractions = new float[fractions.length]; System.arraycopy(fractions, 0, this.fractions, 0, fractions.length); //copy the colors array this.colors = new Color[colors.length]; System.arraycopy(colors, 0, this.colors, 0, colors.length); //copy some flags this.colorSpace = colorSpace; this.cycleMethod = cycleMethod; //copy the gradient transform this.gradientTransform = (AffineTransform)gradientTransform.clone(); // Process transparency boolean opaque = true; for(int i=0; i<colors.length; i++){ opaque = opaque && (colors[i].getAlpha()==0xff); } if(opaque) { transparency = OPAQUE; } else { transparency = TRANSLUCENT; } } /** * Returns a copy of the array of colors used by this gradient. * @return a copy of the array of colors used by this gradient * */ public Color[] getColors() { Color colors[] = new Color[this.colors.length]; System.arraycopy(this.colors, 0, colors, 0, this.colors.length); return colors; } /** * Returns a copy of the array of floats used by this gradient * to calculate color distribution. * @return a copy of the array of floats used by this gradient to * calculate color distribution * */ public float[] getFractions() { float fractions[] = new float[this.fractions.length]; System.arraycopy(this.fractions, 0, fractions, 0, this.fractions.length); return fractions; } /** * Returns the transparency mode for this LinearGradientPaint. * @return an integer value representing this LinearGradientPaint object's * transparency mode. */ public int getTransparency() { return transparency; } /** * Returns the enumerated type which specifies cycling behavior. * @return the enumerated type which specifies cycling behavior */ public CycleMethodEnum getCycleMethod() { return cycleMethod; } /** * Returns the enumerated type which specifies color space for * interpolation. * @return the enumerated type which specifies color space for * interpolation */ public ColorSpaceEnum getColorSpace() { return colorSpace; } /** * Returns a copy of the transform applied to the gradient. * @return a copy of the transform applied to the gradient. */ public AffineTransform getTransform() { return (AffineTransform)gradientTransform.clone(); } }