Home » openjdk-7 » java » awt » [javadoc | source]

    1   /*
    2    * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.awt;
   27   
   28   import java.awt.geom.AffineTransform;
   29   import java.awt.image.ColorModel;
   30   import java.lang.ref.SoftReference;
   31   import java.util.Arrays;
   32   
   33   /**
   34    * This is the superclass for Paints which use a multiple color
   35    * gradient to fill in their raster.  It provides storage for variables and
   36    * enumerated values common to
   37    * {@code LinearGradientPaint} and {@code RadialGradientPaint}.
   38    *
   39    * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
   40    * @since 1.6
   41    */
   42   public abstract class MultipleGradientPaint implements Paint {
   43   
   44       /** The method to use when painting outside the gradient bounds.
   45        * @since 1.6
   46        */
   47       public static enum CycleMethod {
   48           /**
   49            * Use the terminal colors to fill the remaining area.
   50            */
   51           NO_CYCLE,
   52   
   53           /**
   54            * Cycle the gradient colors start-to-end, end-to-start
   55            * to fill the remaining area.
   56            */
   57           REFLECT,
   58   
   59           /**
   60            * Cycle the gradient colors start-to-end, start-to-end
   61            * to fill the remaining area.
   62            */
   63           REPEAT
   64       }
   65   
   66       /** The color space in which to perform the gradient interpolation.
   67        * @since 1.6
   68        */
   69       public static enum ColorSpaceType {
   70           /**
   71            * Indicates that the color interpolation should occur in sRGB space.
   72            */
   73           SRGB,
   74   
   75           /**
   76            * Indicates that the color interpolation should occur in linearized
   77            * RGB space.
   78            */
   79           LINEAR_RGB
   80       }
   81   
   82       /** The transparency of this paint object. */
   83       final int transparency;
   84   
   85       /** Gradient keyframe values in the range 0 to 1. */
   86       final float[] fractions;
   87   
   88       /** Gradient colors. */
   89       final Color[] colors;
   90   
   91       /** Transform to apply to gradient. */
   92       final AffineTransform gradientTransform;
   93   
   94       /** The method to use when painting outside the gradient bounds. */
   95       final CycleMethod cycleMethod;
   96   
   97       /** The color space in which to perform the gradient interpolation. */
   98       final ColorSpaceType colorSpace;
   99   
  100       /**
  101        * The following fields are used only by MultipleGradientPaintContext
  102        * to cache certain values that remain constant and do not need to be
  103        * recalculated for each context created from this paint instance.
  104        */
  105       ColorModel model;
  106       float[] normalizedIntervals;
  107       boolean isSimpleLookup;
  108       SoftReference<int[][]> gradients;
  109       SoftReference<int[]> gradient;
  110       int fastGradientArraySize;
  111   
  112       /**
  113        * Package-private constructor.
  114        *
  115        * @param fractions numbers ranging from 0.0 to 1.0 specifying the
  116        *                  distribution of colors along the gradient
  117        * @param colors array of colors corresponding to each fractional value
  118        * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT},
  119        *                    or {@code REPEAT}
  120        * @param colorSpace which color space to use for interpolation,
  121        *                   either {@code SRGB} or {@code LINEAR_RGB}
  122        * @param gradientTransform transform to apply to the gradient
  123        *
  124        * @throws NullPointerException
  125        * if {@code fractions} array is null,
  126        * or {@code colors} array is null,
  127        * or {@code gradientTransform} is null,
  128        * or {@code cycleMethod} is null,
  129        * or {@code colorSpace} is null
  130        * @throws IllegalArgumentException
  131        * if {@code fractions.length != colors.length},
  132        * or {@code colors} is less than 2 in size,
  133        * or a {@code fractions} value is less than 0.0 or greater than 1.0,
  134        * or the {@code fractions} are not provided in strictly increasing order
  135        */
  136       MultipleGradientPaint(float[] fractions,
  137                             Color[] colors,
  138                             CycleMethod cycleMethod,
  139                             ColorSpaceType colorSpace,
  140                             AffineTransform gradientTransform)
  141       {
  142           if (fractions == null) {
  143               throw new NullPointerException("Fractions array cannot be null");
  144           }
  145   
  146           if (colors == null) {
  147               throw new NullPointerException("Colors array cannot be null");
  148           }
  149   
  150           if (cycleMethod == null) {
  151               throw new NullPointerException("Cycle method cannot be null");
  152           }
  153   
  154           if (colorSpace == null) {
  155               throw new NullPointerException("Color space cannot be null");
  156           }
  157   
  158           if (gradientTransform == null) {
  159               throw new NullPointerException("Gradient transform cannot be "+
  160                                              "null");
  161           }
  162   
  163           if (fractions.length != colors.length) {
  164               throw new IllegalArgumentException("Colors and fractions must " +
  165                                                  "have equal size");
  166           }
  167   
  168           if (colors.length < 2) {
  169               throw new IllegalArgumentException("User must specify at least " +
  170                                                  "2 colors");
  171           }
  172   
  173           // check that values are in the proper range and progress
  174           // in increasing order from 0 to 1
  175           float previousFraction = -1.0f;
  176           for (float currentFraction : fractions) {
  177               if (currentFraction < 0f || currentFraction > 1f) {
  178                   throw new IllegalArgumentException("Fraction values must " +
  179                                                      "be in the range 0 to 1: " +
  180                                                      currentFraction);
  181               }
  182   
  183               if (currentFraction <= previousFraction) {
  184                   throw new IllegalArgumentException("Keyframe fractions " +
  185                                                      "must be increasing: " +
  186                                                      currentFraction);
  187               }
  188   
  189               previousFraction = currentFraction;
  190           }
  191   
  192           // We have to deal with the cases where the first gradient stop is not
  193           // equal to 0 and/or the last gradient stop is not equal to 1.
  194           // In both cases, create a new point and replicate the previous
  195           // extreme point's color.
  196           boolean fixFirst = false;
  197           boolean fixLast = false;
  198           int len = fractions.length;
  199           int off = 0;
  200   
  201           if (fractions[0] != 0f) {
  202               // first stop is not equal to zero, fix this condition
  203               fixFirst = true;
  204               len++;
  205               off++;
  206           }
  207           if (fractions[fractions.length-1] != 1f) {
  208               // last stop is not equal to one, fix this condition
  209               fixLast = true;
  210               len++;
  211           }
  212   
  213           this.fractions = new float[len];
  214           System.arraycopy(fractions, 0, this.fractions, off, fractions.length);
  215           this.colors = new Color[len];
  216           System.arraycopy(colors, 0, this.colors, off, colors.length);
  217   
  218           if (fixFirst) {
  219               this.fractions[0] = 0f;
  220               this.colors[0] = colors[0];
  221           }
  222           if (fixLast) {
  223               this.fractions[len-1] = 1f;
  224               this.colors[len-1] = colors[colors.length - 1];
  225           }
  226   
  227           // copy some flags
  228           this.colorSpace = colorSpace;
  229           this.cycleMethod = cycleMethod;
  230   
  231           // copy the gradient transform
  232           this.gradientTransform = new AffineTransform(gradientTransform);
  233   
  234           // determine transparency
  235           boolean opaque = true;
  236           for (int i = 0; i < colors.length; i++){
  237               opaque = opaque && (colors[i].getAlpha() == 0xff);
  238           }
  239           this.transparency = opaque ? OPAQUE : TRANSLUCENT;
  240       }
  241   
  242       /**
  243        * Returns a copy of the array of floats used by this gradient
  244        * to calculate color distribution.
  245        * The returned array always has 0 as its first value and 1 as its
  246        * last value, with increasing values in between.
  247        *
  248        * @return a copy of the array of floats used by this gradient to
  249        * calculate color distribution
  250        */
  251       public final float[] getFractions() {
  252           return Arrays.copyOf(fractions, fractions.length);
  253       }
  254   
  255       /**
  256        * Returns a copy of the array of colors used by this gradient.
  257        * The first color maps to the first value in the fractions array,
  258        * and the last color maps to the last value in the fractions array.
  259        *
  260        * @return a copy of the array of colors used by this gradient
  261        */
  262       public final Color[] getColors() {
  263           return Arrays.copyOf(colors, colors.length);
  264       }
  265   
  266       /**
  267        * Returns the enumerated type which specifies cycling behavior.
  268        *
  269        * @return the enumerated type which specifies cycling behavior
  270        */
  271       public final CycleMethod getCycleMethod() {
  272           return cycleMethod;
  273       }
  274   
  275       /**
  276        * Returns the enumerated type which specifies color space for
  277        * interpolation.
  278        *
  279        * @return the enumerated type which specifies color space for
  280        * interpolation
  281        */
  282       public final ColorSpaceType getColorSpace() {
  283           return colorSpace;
  284       }
  285   
  286       /**
  287        * Returns a copy of the transform applied to the gradient.
  288        *
  289        * <p>
  290        * Note that if no transform is applied to the gradient
  291        * when it is created, the identity transform is used.
  292        *
  293        * @return a copy of the transform applied to the gradient
  294        */
  295       public final AffineTransform getTransform() {
  296           return new AffineTransform(gradientTransform);
  297       }
  298   
  299       /**
  300        * Returns the transparency mode for this {@code Paint} object.
  301        *
  302        * @return {@code OPAQUE} if all colors used by this
  303        *         {@code Paint} object are opaque,
  304        *         {@code TRANSLUCENT} if at least one of the
  305        *         colors used by this {@code Paint} object is not opaque.
  306        * @see java.awt.Transparency
  307        */
  308       public final int getTransparency() {
  309           return transparency;
  310       }
  311   }

Home » openjdk-7 » java » awt » [javadoc | source]