Class MultipleGradientPaintContext

  • All Implemented Interfaces:
    java.awt.PaintContext
    Direct Known Subclasses:
    LinearGradientPaintContext, RadialGradientPaintContext

    abstract class MultipleGradientPaintContext
    extends java.lang.Object
    implements java.awt.PaintContext
    This is the superclass for all PaintContexts which use a multiple color gradient to fill in their raster. It provides the actual color interpolation functionality. Subclasses only have to deal with using the gradient to fill pixels in a raster.
    Version:
    $Id: MultipleGradientPaintContext.java 1804130 2017-08-04 14:41:11Z ssteiner $
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected float a00
      Elements of the inverse transform matrix.
      protected float a01
      Elements of the inverse transform matrix.
      protected float a02
      Elements of the inverse transform matrix.
      protected float a10
      Elements of the inverse transform matrix.
      protected float a11
      Elements of the inverse transform matrix.
      protected float a12
      Elements of the inverse transform matrix.
      protected static java.lang.ref.WeakReference cached
      The cached raster, which is reusable among instances
      protected static java.awt.image.ColorModel cachedModel
      The cached colorModel
      protected MultipleGradientPaint.ColorSpaceEnum colorSpace
      The colorSpace in which to perform the interpolation
      protected MultipleGradientPaint.CycleMethodEnum cycleMethod
      The method to use when painting out of the gradient bounds.
      protected java.awt.image.ColorModel dataModel
      The color model data is generated in (always un premult).
      protected static boolean DEBUG  
      protected int fastGradientArraySize
      Size of gradients array for scaling the 0-1 index when looking up colors the fast way.
      protected float[] fractions
      fractions array
      protected int[] gradient
      Array which contains the interpolated color values for each interval, used by calculateSingleArrayGradient().
      protected static int GRADIENT_SIZE
      Constant number of max colors between any 2 arbitrary colors.
      protected static int GRADIENT_SIZE_INDEX  
      protected int gradientAverage
      This holds the blend of all colors in the gradient.
      protected int gradientOverflow
      This holds the color to use when we are off the top of the gradient
      protected int[][] gradients
      Array of gradient arrays, one array for each interval.
      protected int gradientsLength
      Length of the 2D slow lookup gradients array.
      protected int gradientUnderflow
      This holds the color to use when we are off the bottom of the gradient
      protected boolean hasDiscontinuity
      This boolean indicates if the gradient appears to have sudden discontinuities in it, this may be because of multiple stops at the same location or use of the REPEATE mode.
      protected boolean isSimpleLookup
      This boolean specifies wether we are in simple lookup mode, where an input value between 0 and 1 may be used to directly index into a single array of gradient colors.
      private static int[] LinearRGBtoSRGB  
      private static java.awt.image.ColorModel lrgbmodel_A
      Color model used if some gradient colors are transparent
      private static java.awt.image.ColorModel lrgbmodel_NA
      Color model used if gradient colors are all opaque
      private static int MAX_GRADIENT_ARRAY_SIZE
      Maximum length of the fast single-array.
      protected java.awt.image.ColorModel model
      PaintContext's output ColorModel ARGB if colors are not all opaque, RGB otherwise.
      protected float[] normalizedIntervals
      Normalized intervals array
      protected java.awt.image.WritableRaster saved
      Raster is reused whenever possible
      private static java.awt.image.ColorModel srgbmodel_A  
      private static java.awt.image.ColorModel srgbmodel_NA  
      private static int[] SRGBtoLinearRGB
      Colorspace conversion lookup tables
      private int transparencyTest
      Used to determine if gradient colors are all opaque
    • Method Summary

      All Methods Static Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      protected void calculateGradientFractions​(java.awt.Color[] loColors, java.awt.Color[] hiColors)
      This function is the meat of this class.
      private void calculateMultipleArrayGradient​(java.awt.Color[] loColors, java.awt.Color[] hiColors)
      SLOW LOOKUP METHOD This method calculates the gradient color values for each interval and places each into its own 255 size array.
      private void calculateSingleArrayGradient​(java.awt.Color[] loColors, java.awt.Color[] hiColors, float Imin)
      FAST LOOKUP METHOD This method calculates the gradient color values and places them in a single int array, gradient[].
      private static int convertEntireColorLinearRGBtoSRGB​(int rgb)
      Yet another helper function.
      private static int convertEntireColorSRGBtoLinearRGB​(int rgb)
      Yet another helper function.
      private static int convertLinearRGBtoSRGB​(int color)
      Helper function to convert a color component in linear RGB space to SRGB space.
      private static int convertSRGBtoLinearRGB​(int color)
      Helper function to convert a color component in sRGB space to linear RGB space.
      void dispose()
      Release the resources allocated for the operation.
      protected abstract void fillRaster​(int[] pixels, int off, int adjust, int x, int y, int w, int h)
      Subclasses should implement this.
      private int getAntiAlias​(float p1, boolean p1_up, float p2, boolean p2_up, float sz, float weight)  
      protected static java.awt.image.WritableRaster getCachedRaster​(java.awt.image.ColorModel cm, int w, int h)
      Took this cacheRaster code from GradientPaint.
      java.awt.image.ColorModel getColorModel()
      Return the ColorModel of the output.
      java.awt.image.Raster getRaster​(int x, int y, int w, int h)
      Superclass getRaster...
      protected int indexGradientAntiAlias​(float position, float sz)
      Helper function to index into the gradients array.
      protected int indexIntoGradientsArrays​(float position)
      Helper function to index into the gradients array.
      private void interpolate​(int rgb1, int rgb2, int[] output)
      Yet another helper function.
      private static java.awt.Color interpolateColor​(int[] workTbl, java.awt.Color inColor)
      We assume, that we always generate valid colors.
      protected static void putCachedRaster​(java.awt.image.ColorModel cm, java.awt.image.WritableRaster ras)
      Took this cacheRaster code from GradientPaint.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • dataModel

        protected java.awt.image.ColorModel dataModel
        The color model data is generated in (always un premult).
      • model

        protected java.awt.image.ColorModel model
        PaintContext's output ColorModel ARGB if colors are not all opaque, RGB otherwise. Linear and premult are matched to output ColorModel.
      • lrgbmodel_NA

        private static java.awt.image.ColorModel lrgbmodel_NA
        Color model used if gradient colors are all opaque
      • srgbmodel_NA

        private static java.awt.image.ColorModel srgbmodel_NA
      • lrgbmodel_A

        private static java.awt.image.ColorModel lrgbmodel_A
        Color model used if some gradient colors are transparent
      • srgbmodel_A

        private static java.awt.image.ColorModel srgbmodel_A
      • cachedModel

        protected static java.awt.image.ColorModel cachedModel
        The cached colorModel
      • cached

        protected static java.lang.ref.WeakReference cached
        The cached raster, which is reusable among instances
      • saved

        protected java.awt.image.WritableRaster saved
        Raster is reused whenever possible
      • a00

        protected float a00
        Elements of the inverse transform matrix.
      • a01

        protected float a01
        Elements of the inverse transform matrix.
      • a10

        protected float a10
        Elements of the inverse transform matrix.
      • a11

        protected float a11
        Elements of the inverse transform matrix.
      • a02

        protected float a02
        Elements of the inverse transform matrix.
      • a12

        protected float a12
        Elements of the inverse transform matrix.
      • isSimpleLookup

        protected boolean isSimpleLookup
        This boolean specifies wether we are in simple lookup mode, where an input value between 0 and 1 may be used to directly index into a single array of gradient colors. If this boolean value is false, then we have to use a 2-step process where we have to determine which gradient array we fall into, then determine the index into that array.
      • hasDiscontinuity

        protected boolean hasDiscontinuity
        This boolean indicates if the gradient appears to have sudden discontinuities in it, this may be because of multiple stops at the same location or use of the REPEATE mode.
      • fastGradientArraySize

        protected int fastGradientArraySize
        Size of gradients array for scaling the 0-1 index when looking up colors the fast way.
      • gradient

        protected int[] gradient
        Array which contains the interpolated color values for each interval, used by calculateSingleArrayGradient(). It is protected for possible direct access by subclasses.
      • gradients

        protected int[][] gradients
        Array of gradient arrays, one array for each interval. Used by calculateMultipleArrayGradient().
      • gradientAverage

        protected int gradientAverage
        This holds the blend of all colors in the gradient. we use this at extreamly low resolutions to ensure we get a decent blend of the colors.
      • gradientUnderflow

        protected int gradientUnderflow
        This holds the color to use when we are off the bottom of the gradient
      • gradientOverflow

        protected int gradientOverflow
        This holds the color to use when we are off the top of the gradient
      • gradientsLength

        protected int gradientsLength
        Length of the 2D slow lookup gradients array.
      • normalizedIntervals

        protected float[] normalizedIntervals
        Normalized intervals array
      • fractions

        protected float[] fractions
        fractions array
      • transparencyTest

        private int transparencyTest
        Used to determine if gradient colors are all opaque
      • SRGBtoLinearRGB

        private static final int[] SRGBtoLinearRGB
        Colorspace conversion lookup tables
      • LinearRGBtoSRGB

        private static final int[] LinearRGBtoSRGB
      • GRADIENT_SIZE

        protected static final int GRADIENT_SIZE
        Constant number of max colors between any 2 arbitrary colors. Used for creating and indexing gradients arrays.
        See Also:
        Constant Field Values
      • MAX_GRADIENT_ARRAY_SIZE

        private static final int MAX_GRADIENT_ARRAY_SIZE
        Maximum length of the fast single-array. If the estimated array size is greater than this, switch over to the slow lookup method. No particular reason for choosing this number, but it seems to provide satisfactory performance for the common case (fast lookup).
        See Also:
        Constant Field Values
    • Constructor Detail

      • MultipleGradientPaintContext

        protected MultipleGradientPaintContext​(java.awt.image.ColorModel cm,
                                               java.awt.Rectangle deviceBounds,
                                               java.awt.geom.Rectangle2D userBounds,
                                               java.awt.geom.AffineTransform t,
                                               java.awt.RenderingHints hints,
                                               float[] fractions,
                                               java.awt.Color[] colors,
                                               MultipleGradientPaint.CycleMethodEnum cycleMethod,
                                               MultipleGradientPaint.ColorSpaceEnum colorSpace)
                                        throws java.awt.geom.NoninvertibleTransformException
        Constructor for superclass. Does some initialization, but leaves most of the heavy-duty math for calculateGradient(), so the subclass may do some other manipulation beforehand if necessary. This is not possible if this computation is done in the superclass constructor which always gets called first.
        Throws:
        java.awt.geom.NoninvertibleTransformException
    • Method Detail

      • calculateGradientFractions

        protected final void calculateGradientFractions​(java.awt.Color[] loColors,
                                                        java.awt.Color[] hiColors)
        This function is the meat of this class. It calculates an array of gradient colors based on an array of fractions and color values at those fractions.
      • interpolateColor

        private static java.awt.Color interpolateColor​(int[] workTbl,
                                                       java.awt.Color inColor)
        We assume, that we always generate valid colors. When this is valid, we can compose the color-value by ourselves and use the faster Color-ctor, which does not check the incoming values.
        Parameters:
        workTbl - typically SRGBtoLinearRGB
        inColor - the color to interpolate
        Returns:
        the interpolated color
      • calculateSingleArrayGradient

        private void calculateSingleArrayGradient​(java.awt.Color[] loColors,
                                                  java.awt.Color[] hiColors,
                                                  float Imin)
        FAST LOOKUP METHOD This method calculates the gradient color values and places them in a single int array, gradient[]. It does this by allocating space for each interval based on its size relative to the smallest interval in the array. The smallest interval is allocated 255 interpolated values (the maximum number of unique in-between colors in a 24 bit color system), and all other intervals are allocated size = (255 * the ratio of their size to the smallest interval). This scheme expedites a speedy retrieval because the colors are distributed along the array according to their user-specified distribution. All that is needed is a relative index from 0 to 1. The only problem with this method is that the possibility exists for the array size to balloon in the case where there is a disproportionately small gradient interval. In this case the other intervals will be allocated huge space, but much of that data is redundant. We thus need to use the space conserving scheme below.
        Parameters:
        Imin - the size of the smallest interval
      • calculateMultipleArrayGradient

        private void calculateMultipleArrayGradient​(java.awt.Color[] loColors,
                                                    java.awt.Color[] hiColors)
        SLOW LOOKUP METHOD This method calculates the gradient color values for each interval and places each into its own 255 size array. The arrays are stored in gradients[][]. (255 is used because this is the maximum number of unique colors between 2 arbitrary colors in a 24 bit color system) This method uses the minimum amount of space (only 255 * number of intervals), but it aggravates the lookup procedure, because now we have to find out which interval to select, then calculate the index within that interval. This causes a significant performance hit, because it requires this calculation be done for every point in the rendering loop. For those of you who are interested, this is a classic example of the time-space tradeoff.
      • interpolate

        private void interpolate​(int rgb1,
                                 int rgb2,
                                 int[] output)
        Yet another helper function. This one linearly interpolates between 2 colors, filling up the output array.
        Parameters:
        rgb1 - the start color
        rgb2 - the end color
        output - the output array of colors... assuming this is not null or length 0.
      • convertEntireColorLinearRGBtoSRGB

        private static int convertEntireColorLinearRGBtoSRGB​(int rgb)
        Yet another helper function. This one extracts the color components of an integer RGB triple, converts them from LinearRGB to SRGB, then recompacts them into an int.
      • convertEntireColorSRGBtoLinearRGB

        private static int convertEntireColorSRGBtoLinearRGB​(int rgb)
        Yet another helper function. This one extracts the color components of an integer RGB triple, converts them from LinearRGB to SRGB, then recompacts them into an int.
      • indexIntoGradientsArrays

        protected final int indexIntoGradientsArrays​(float position)
        Helper function to index into the gradients array. This is necessary because each interval has an array of colors with uniform size 255. However, the color intervals are not necessarily of uniform length, so a conversion is required.
        Parameters:
        position - the unmanipulated position. want to map this into the range 0 to 1
        Returns:
        integer color to display
      • indexGradientAntiAlias

        protected final int indexGradientAntiAlias​(float position,
                                                   float sz)
        Helper function to index into the gradients array. This is necessary because each interval has an array of colors with uniform size 255. However, the color intervals are not necessarily of uniform length, so a conversion is required. This version also does anti-aliasing by averaging the gradient over position+/-(sz/2).
        Parameters:
        position - the unmanipulated position. want to map this into the range 0 to 1
        sz - the size in gradient space to average.
        Returns:
        ARGB integer color to display
      • getAntiAlias

        private final int getAntiAlias​(float p1,
                                       boolean p1_up,
                                       float p2,
                                       boolean p2_up,
                                       float sz,
                                       float weight)
      • convertSRGBtoLinearRGB

        private static int convertSRGBtoLinearRGB​(int color)
        Helper function to convert a color component in sRGB space to linear RGB space. Used to build a static lookup table.
      • convertLinearRGBtoSRGB

        private static int convertLinearRGBtoSRGB​(int color)
        Helper function to convert a color component in linear RGB space to SRGB space. Used to build a static lookup table.
      • getRaster

        public final java.awt.image.Raster getRaster​(int x,
                                                     int y,
                                                     int w,
                                                     int h)
        Superclass getRaster...
        Specified by:
        getRaster in interface java.awt.PaintContext
      • fillRaster

        protected abstract void fillRaster​(int[] pixels,
                                           int off,
                                           int adjust,
                                           int x,
                                           int y,
                                           int w,
                                           int h)
        Subclasses should implement this.
      • getCachedRaster

        protected static final java.awt.image.WritableRaster getCachedRaster​(java.awt.image.ColorModel cm,
                                                                             int w,
                                                                             int h)
        Took this cacheRaster code from GradientPaint. It appears to recycle rasters for use by any other instance, as long as they are sufficiently large.
      • putCachedRaster

        protected static final void putCachedRaster​(java.awt.image.ColorModel cm,
                                                    java.awt.image.WritableRaster ras)
        Took this cacheRaster code from GradientPaint. It appears to recycle rasters for use by any other instance, as long as they are sufficiently large.
      • dispose

        public final void dispose()
        Release the resources allocated for the operation.
        Specified by:
        dispose in interface java.awt.PaintContext
      • getColorModel

        public final java.awt.image.ColorModel getColorModel()
        Return the ColorModel of the output.
        Specified by:
        getColorModel in interface java.awt.PaintContext