--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/awt/MultipleGradientPaint.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.ColorModel;
+import java.lang.ref.SoftReference;
+import java.util.Arrays;
+
+/**
+ * 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
+ * {@code LinearGradientPaint} and {@code RadialGradientPaint}.
+ *
+ * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
+ * @since 1.6
+ */
+public abstract class MultipleGradientPaint implements Paint {
+
+ /** The method to use when painting outside the gradient bounds.
+ * @since 1.6
+ */
+ public static enum CycleMethod {
+ /**
+ * Use the terminal colors to fill the remaining area.
+ */
+ NO_CYCLE,
+
+ /**
+ * Cycle the gradient colors start-to-end, end-to-start
+ * to fill the remaining area.
+ */
+ REFLECT,
+
+ /**
+ * Cycle the gradient colors start-to-end, start-to-end
+ * to fill the remaining area.
+ */
+ REPEAT
+ }
+
+ /** The color space in which to perform the gradient interpolation.
+ * @since 1.6
+ */
+ public static enum ColorSpaceType {
+ /**
+ * Indicates that the color interpolation should occur in sRGB space.
+ */
+ SRGB,
+
+ /**
+ * Indicates that the color interpolation should occur in linearized
+ * RGB space.
+ */
+ LINEAR_RGB
+ }
+
+ /** The transparency of this paint object. */
+ final int transparency;
+
+ /** Gradient keyframe values in the range 0 to 1. */
+ final float[] fractions;
+
+ /** Gradient colors. */
+ final Color[] colors;
+
+ /** Transform to apply to gradient. */
+ final AffineTransform gradientTransform;
+
+ /** The method to use when painting outside the gradient bounds. */
+ final CycleMethod cycleMethod;
+
+ /** The color space in which to perform the gradient interpolation. */
+ final ColorSpaceType colorSpace;
+
+ /**
+ * The following fields are used only by MultipleGradientPaintContext
+ * to cache certain values that remain constant and do not need to be
+ * recalculated for each context created from this paint instance.
+ */
+ ColorModel model;
+ float[] normalizedIntervals;
+ boolean isSimpleLookup;
+ SoftReference<int[][]> gradients;
+ SoftReference<int[]> gradient;
+ int fastGradientArraySize;
+
+ /**
+ * Package-private constructor.
+ *
+ * @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 {@code NO_CYCLE}, {@code REFLECT},
+ * or {@code REPEAT}
+ * @param colorSpace which color space to use for interpolation,
+ * either {@code SRGB} or {@code LINEAR_RGB}
+ * @param gradientTransform transform to apply to the gradient
+ *
+ * @throws NullPointerException
+ * if {@code fractions} array is null,
+ * or {@code colors} array is null,
+ * or {@code gradientTransform} is null,
+ * or {@code cycleMethod} is null,
+ * or {@code colorSpace} is null
+ * @throws IllegalArgumentException
+ * if {@code fractions.length != colors.length},
+ * or {@code colors} is less than 2 in size,
+ * or a {@code fractions} value is less than 0.0 or greater than 1.0,
+ * or the {@code fractions} are not provided in strictly increasing order
+ */
+ MultipleGradientPaint(float[] fractions,
+ Color[] colors,
+ CycleMethod cycleMethod,
+ ColorSpaceType colorSpace,
+ AffineTransform gradientTransform)
+ {
+ if (fractions == null) {
+ throw new NullPointerException("Fractions array cannot be null");
+ }
+
+ if (colors == null) {
+ throw new NullPointerException("Colors array cannot be null");
+ }
+
+ if (cycleMethod == null) {
+ throw new NullPointerException("Cycle method cannot be null");
+ }
+
+ if (colorSpace == null) {
+ throw new NullPointerException("Color space cannot be null");
+ }
+
+ if (gradientTransform == null) {
+ throw new NullPointerException("Gradient transform 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");
+ }
+
+ // check that values are in the proper range and progress
+ // in increasing order from 0 to 1
+ float previousFraction = -1.0f;
+ for (float currentFraction : fractions) {
+ if (currentFraction < 0f || currentFraction > 1f) {
+ throw new IllegalArgumentException("Fraction values must " +
+ "be in the range 0 to 1: " +
+ currentFraction);
+ }
+
+ if (currentFraction <= previousFraction) {
+ throw new IllegalArgumentException("Keyframe fractions " +
+ "must be increasing: " +
+ currentFraction);
+ }
+
+ previousFraction = currentFraction;
+ }
+
+ // We have to deal with the cases where the first gradient stop is not
+ // equal to 0 and/or the last gradient stop is not equal to 1.
+ // In both cases, create a new point and replicate the previous
+ // extreme point's color.
+ boolean fixFirst = false;
+ boolean fixLast = false;
+ int len = fractions.length;
+ int off = 0;
+
+ if (fractions[0] != 0f) {
+ // first stop is not equal to zero, fix this condition
+ fixFirst = true;
+ len++;
+ off++;
+ }
+ if (fractions[fractions.length-1] != 1f) {
+ // last stop is not equal to one, fix this condition
+ fixLast = true;
+ len++;
+ }
+
+ this.fractions = new float[len];
+ System.arraycopy(fractions, 0, this.fractions, off, fractions.length);
+ this.colors = new Color[len];
+ System.arraycopy(colors, 0, this.colors, off, colors.length);
+
+ if (fixFirst) {
+ this.fractions[0] = 0f;
+ this.colors[0] = colors[0];
+ }
+ if (fixLast) {
+ this.fractions[len-1] = 1f;
+ this.colors[len-1] = colors[colors.length - 1];
+ }
+
+ // copy some flags
+ this.colorSpace = colorSpace;
+ this.cycleMethod = cycleMethod;
+
+ // copy the gradient transform
+ this.gradientTransform = new AffineTransform(gradientTransform);
+
+ // determine transparency
+ boolean opaque = true;
+ for (int i = 0; i < colors.length; i++){
+ opaque = opaque && (colors[i].getAlpha() == 0xff);
+ }
+ this.transparency = opaque ? OPAQUE : TRANSLUCENT;
+ }
+
+ /**
+ * Returns a copy of the array of floats used by this gradient
+ * to calculate color distribution.
+ * The returned array always has 0 as its first value and 1 as its
+ * last value, with increasing values in between.
+ *
+ * @return a copy of the array of floats used by this gradient to
+ * calculate color distribution
+ */
+ public final float[] getFractions() {
+ return Arrays.copyOf(fractions, fractions.length);
+ }
+
+ /**
+ * Returns a copy of the array of colors used by this gradient.
+ * The first color maps to the first value in the fractions array,
+ * and the last color maps to the last value in the fractions array.
+ *
+ * @return a copy of the array of colors used by this gradient
+ */
+ public final Color[] getColors() {
+ return Arrays.copyOf(colors, colors.length);
+ }
+
+ /**
+ * Returns the enumerated type which specifies cycling behavior.
+ *
+ * @return the enumerated type which specifies cycling behavior
+ */
+ public final CycleMethod getCycleMethod() {
+ return cycleMethod;
+ }
+
+ /**
+ * Returns the enumerated type which specifies color space for
+ * interpolation.
+ *
+ * @return the enumerated type which specifies color space for
+ * interpolation
+ */
+ public final ColorSpaceType getColorSpace() {
+ return colorSpace;
+ }
+
+ /**
+ * Returns a copy of the transform applied to the gradient.
+ *
+ * @return a copy of the transform applied to the gradient
+ */
+ public final AffineTransform getTransform() {
+ return new AffineTransform(gradientTransform);
+ }
+
+ /**
+ * Returns the transparency mode for this Paint object.
+ *
+ * @return an integer value representing the transparency mode for
+ * this Paint object
+ * @see java.awt.Transparency
+ */
+ public final int getTransparency() {
+ return transparency;
+ }
+}