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