001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.ext.awt;
020:
021: import java.awt.Color;
022: import java.awt.Paint;
023: import java.awt.geom.AffineTransform;
024:
025: /** This is the superclass for Paints which use a multiple color
026: * gradient to fill in their raster. It provides storage for variables and
027: * enumerated values common to LinearGradientPaint and RadialGradientPaint.
028: *
029: *
030: * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
031: * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
032: * @version $Id: MultipleGradientPaint.java 479573 2006-11-27 10:13:36Z dvholten $
033: */
034: public abstract class MultipleGradientPaint implements Paint {
035:
036: /** Transparency. */
037: protected int transparency;
038:
039: /** Gradient keyframe values in the range 0 to 1. */
040: protected float[] fractions;
041:
042: /** Gradient colors. */
043: protected Color[] colors;
044:
045: /** Transform to apply to gradient. */
046: protected AffineTransform gradientTransform;
047:
048: /** The method to use when painting out of the gradient bounds. */
049: protected CycleMethodEnum cycleMethod;
050:
051: /** The colorSpace in which to perform the interpolation. */
052: protected ColorSpaceEnum colorSpace;
053:
054: /** Inner class to allow for typesafe enumerated ColorSpace values. */
055: public static class ColorSpaceEnum {
056: }
057:
058: /** Inner class to allow for typesafe enumerated CycleMethod values. */
059: public static class CycleMethodEnum {
060: }
061:
062: /** Indicates (if the gradient starts or ends inside the target region)
063: * to use the terminal colors to fill the remaining area. (default)
064: */
065: public static final CycleMethodEnum NO_CYCLE = new CycleMethodEnum();
066:
067: /** Indicates (if the gradient starts or ends inside the target region),
068: * to cycle the gradient colors start-to-end, end-to-start to fill the
069: * remaining area.
070: */
071: public static final CycleMethodEnum REFLECT = new CycleMethodEnum();
072:
073: /** Indicates (if the gradient starts or ends inside the target region),
074: * to cycle the gradient colors start-to-end, start-to-end to fill the
075: * remaining area.
076: */
077: public static final CycleMethodEnum REPEAT = new CycleMethodEnum();
078:
079: /** Indicates that the color interpolation should occur in sRGB space.
080: * (default)
081: */
082: public static final ColorSpaceEnum SRGB = new ColorSpaceEnum();
083:
084: /** Indicates that the color interpolation should occur in linearized
085: * RGB space.
086: */
087: public static final ColorSpaceEnum LINEAR_RGB = new ColorSpaceEnum();
088:
089: /**
090: * Superclass constructor, typical user should never have to call this.
091: *
092: * @param fractions numbers ranging from 0.0 to 1.0 specifying the
093: * distribution of colors along the gradient
094: *
095: * @param colors array of colors corresponding to each fractional value
096: *
097: * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
098: *
099: * @param colorSpace which colorspace to use for interpolation,
100: * either SRGB or LINEAR_RGB
101: *
102: * @param gradientTransform transform to apply to the gradient
103: *
104: * @throws NullPointerException if arrays are null, or
105: * gradientTransform is null
106: *
107: * @throws IllegalArgumentException if fractions.length != colors.length,
108: * or if colors is less than 2 in size, or if an enumerated value is bad.
109: */
110: public MultipleGradientPaint(float[] fractions, Color[] colors,
111: CycleMethodEnum cycleMethod, ColorSpaceEnum colorSpace,
112: AffineTransform gradientTransform) {
113:
114: if (fractions == null) {
115: throw new IllegalArgumentException(
116: "Fractions array cannot be " + "null");
117: }
118:
119: if (colors == null) {
120: throw new IllegalArgumentException(
121: "Colors array cannot be null");
122: }
123:
124: if (fractions.length != colors.length) {
125: throw new IllegalArgumentException(
126: "Colors and fractions must " + "have equal size");
127: }
128:
129: if (colors.length < 2) {
130: throw new IllegalArgumentException(
131: "User must specify at least " + "2 colors");
132: }
133:
134: if ((colorSpace != LINEAR_RGB) && (colorSpace != SRGB)) {
135: throw new IllegalArgumentException(
136: "Invalid colorspace for " + "interpolation.");
137: }
138:
139: if ((cycleMethod != NO_CYCLE) && (cycleMethod != REFLECT)
140: && (cycleMethod != REPEAT)) {
141: throw new IllegalArgumentException("Invalid cycle method.");
142: }
143:
144: if (gradientTransform == null) {
145: throw new IllegalArgumentException(
146: "Gradient transform cannot be " + "null.");
147: }
148:
149: //copy the fractions array
150: this .fractions = new float[fractions.length];
151: System.arraycopy(fractions, 0, this .fractions, 0,
152: fractions.length);
153:
154: //copy the colors array
155: this .colors = new Color[colors.length];
156: System.arraycopy(colors, 0, this .colors, 0, colors.length);
157:
158: //copy some flags
159: this .colorSpace = colorSpace;
160: this .cycleMethod = cycleMethod;
161:
162: //copy the gradient transform
163: this .gradientTransform = (AffineTransform) gradientTransform
164: .clone();
165:
166: // Process transparency
167: boolean opaque = true;
168: for (int i = 0; i < colors.length; i++) {
169: opaque = opaque && (colors[i].getAlpha() == 0xff);
170: }
171:
172: if (opaque) {
173: transparency = OPAQUE;
174: }
175:
176: else {
177: transparency = TRANSLUCENT;
178: }
179: }
180:
181: /**
182: * Returns a copy of the array of colors used by this gradient.
183: * @return a copy of the array of colors used by this gradient
184: *
185: */
186: public Color[] getColors() {
187: Color[] colors = new Color[this .colors.length];
188: System.arraycopy(this .colors, 0, colors, 0, this .colors.length);
189: return colors;
190: }
191:
192: /**
193: * Returns a copy of the array of floats used by this gradient
194: * to calculate color distribution.
195: * @return a copy of the array of floats used by this gradient to
196: * calculate color distribution
197: *
198: */
199: public float[] getFractions() {
200: float[] fractions = new float[this .fractions.length];
201: System.arraycopy(this .fractions, 0, fractions, 0,
202: this .fractions.length);
203: return fractions;
204: }
205:
206: /**
207: * Returns the transparency mode for this LinearGradientPaint.
208: * @return an integer value representing this LinearGradientPaint object's
209: * transparency mode.
210: */
211: public int getTransparency() {
212: return transparency;
213: }
214:
215: /**
216: * Returns the enumerated type which specifies cycling behavior.
217: * @return the enumerated type which specifies cycling behavior
218: */
219: public CycleMethodEnum getCycleMethod() {
220: return cycleMethod;
221: }
222:
223: /**
224: * Returns the enumerated type which specifies color space for
225: * interpolation.
226: * @return the enumerated type which specifies color space for
227: * interpolation
228: */
229: public ColorSpaceEnum getColorSpace() {
230: return colorSpace;
231: }
232:
233: /**
234: * Returns a copy of the transform applied to the gradient.
235: * @return a copy of the transform applied to the gradient.
236: */
237: public AffineTransform getTransform() {
238: return (AffineTransform) gradientTransform.clone();
239: }
240: }
|