java.awt.MultipleGradientPaint.ColorSpaceType#LINEAR_RGB源码实例Demo

下面列出了java.awt.MultipleGradientPaint.ColorSpaceType#LINEAR_RGB 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: jdk8u_jdk   文件: D3DPaints.java
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
    LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;

    if (paint.getFractions().length == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT &&
        paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
    {
        D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
        D3DGraphicsDevice gd = (D3DGraphicsDevice)
            dstData.getDeviceConfiguration().getDevice();
        if (gd.isCapPresent(CAPS_LCD_SHADER)) {
            // we can delegate to the optimized two-color gradient
            // codepath, which should be faster
            return true;
        }
    }

    return super.isPaintValid(sg2d);
}
 
源代码2 项目: openjdk-jdk9   文件: OGLPaints.java
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
    LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;

    if (paint.getFractions().length == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT &&
        paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
    {
        // we can delegate to the optimized two-color gradient
        // codepath, which does not require fragment shader support
        return true;
    }

    return super.isPaintValid(sg2d);
}
 
/**
 * 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.
 */
private void calculateMultipleArrayGradient(Color[] colors) {
    // set the flag so we know later it is a non-simple lookup
    isSimpleLookup = false;

    // 2 colors to interpolate
    int rgb1, rgb2;

    // for every interval (transition between 2 colors)
    for (int i = 0; i < gradients.length; i++){
        // create an array of the maximum theoretical size for
        // each interval
        gradients[i] = new int[GRADIENT_SIZE];

        // get the the 2 colors
        rgb1 = colors[i].getRGB();
        rgb2 = colors[i+1].getRGB();

        // fill this array with the colors in between rgb1 and rgb2
        interpolate(rgb1, rgb2, gradients[i]);

        // if the colors are opaque, transparency should still
        // be 0xff000000
        transparencyTest &= rgb1;
        transparencyTest &= rgb2;
    }

    // if interpolation occurred in Linear RGB space, convert the
    // gradients back to SRGB using the lookup table
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        for (int j = 0; j < gradients.length; j++) {
            for (int i = 0; i < gradients[j].length; i++) {
                gradients[j][i] =
                    convertEntireColorLinearRGBtoSRGB(gradients[j][i]);
            }
        }
    }
}
 
源代码4 项目: Bytecoder   文件: OGLPaints.java
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
    LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;

    if (paint.getFractions().length == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT &&
        paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
    {
        // we can delegate to the optimized two-color gradient
        // codepath, which does not require fragment shader support
        return true;
    }

    return super.isPaintValid(sg2d);
}
 
源代码5 项目: hottub   文件: OGLPaints.java
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
    LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;

    if (paint.getFractions().length == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT &&
        paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
    {
        // we can delegate to the optimized two-color gradient
        // codepath, which does not require fragment shader support
        return true;
    }

    return super.isPaintValid(sg2d);
}
 
/**
 * 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.
 */
private void calculateMultipleArrayGradient(Color[] colors) {
    // set the flag so we know later it is a non-simple lookup
    isSimpleLookup = false;

    // 2 colors to interpolate
    int rgb1, rgb2;

    // for every interval (transition between 2 colors)
    for (int i = 0; i < gradients.length; i++){
        // create an array of the maximum theoretical size for
        // each interval
        gradients[i] = new int[GRADIENT_SIZE];

        // get the the 2 colors
        rgb1 = colors[i].getRGB();
        rgb2 = colors[i+1].getRGB();

        // fill this array with the colors in between rgb1 and rgb2
        interpolate(rgb1, rgb2, gradients[i]);

        // if the colors are opaque, transparency should still
        // be 0xff000000
        transparencyTest &= rgb1;
        transparencyTest &= rgb2;
    }

    // if interpolation occurred in Linear RGB space, convert the
    // gradients back to SRGB using the lookup table
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        for (int j = 0; j < gradients.length; j++) {
            for (int i = 0; i < gradients[j].length; i++) {
                gradients[j][i] =
                    convertEntireColorLinearRGBtoSRGB(gradients[j][i]);
            }
        }
    }
}
 
源代码7 项目: Bytecoder   文件: MultipleGradientPaintContext.java
/**
 * 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.
 */
private void calculateMultipleArrayGradient(Color[] colors) {
    // set the flag so we know later it is a non-simple lookup
    isSimpleLookup = false;

    // 2 colors to interpolate
    int rgb1, rgb2;

    // for every interval (transition between 2 colors)
    for (int i = 0; i < gradients.length; i++){
        // create an array of the maximum theoretical size for
        // each interval
        gradients[i] = new int[GRADIENT_SIZE];

        // get the 2 colors
        rgb1 = colors[i].getRGB();
        rgb2 = colors[i+1].getRGB();

        // fill this array with the colors in between rgb1 and rgb2
        interpolate(rgb1, rgb2, gradients[i]);

        // if the colors are opaque, transparency should still
        // be 0xff000000
        transparencyTest &= rgb1;
        transparencyTest &= rgb2;
    }

    // if interpolation occurred in Linear RGB space, convert the
    // gradients back to SRGB using the lookup table
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        for (int j = 0; j < gradients.length; j++) {
            for (int i = 0; i < gradients[j].length; i++) {
                gradients[j][i] =
                    convertEntireColorLinearRGBtoSRGB(gradients[j][i]);
            }
        }
    }
}
 
/**
 * 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.
 */
private void calculateMultipleArrayGradient(Color[] colors) {
    // set the flag so we know later it is a non-simple lookup
    isSimpleLookup = false;

    // 2 colors to interpolate
    int rgb1, rgb2;

    // for every interval (transition between 2 colors)
    for (int i = 0; i < gradients.length; i++){
        // create an array of the maximum theoretical size for
        // each interval
        gradients[i] = new int[GRADIENT_SIZE];

        // get the the 2 colors
        rgb1 = colors[i].getRGB();
        rgb2 = colors[i+1].getRGB();

        // fill this array with the colors in between rgb1 and rgb2
        interpolate(rgb1, rgb2, gradients[i]);

        // if the colors are opaque, transparency should still
        // be 0xff000000
        transparencyTest &= rgb1;
        transparencyTest &= rgb2;
    }

    // if interpolation occurred in Linear RGB space, convert the
    // gradients back to SRGB using the lookup table
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        for (int j = 0; j < gradients.length; j++) {
            for (int i = 0; i < gradients[j].length; i++) {
                gradients[j][i] =
                    convertEntireColorLinearRGBtoSRGB(gradients[j][i]);
            }
        }
    }
}
 
源代码9 项目: jdk8u-jdk   文件: OGLPaints.java
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
    LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;

    if (paint.getFractions().length == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT &&
        paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
    {
        // we can delegate to the optimized two-color gradient
        // codepath, which does not require fragment shader support
        return true;
    }

    return super.isPaintValid(sg2d);
}
 
源代码10 项目: jdk8u-jdk   文件: MultipleGradientPaintContext.java
/**
 * 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.
 */
private void calculateMultipleArrayGradient(Color[] colors) {
    // set the flag so we know later it is a non-simple lookup
    isSimpleLookup = false;

    // 2 colors to interpolate
    int rgb1, rgb2;

    // for every interval (transition between 2 colors)
    for (int i = 0; i < gradients.length; i++){
        // create an array of the maximum theoretical size for
        // each interval
        gradients[i] = new int[GRADIENT_SIZE];

        // get the the 2 colors
        rgb1 = colors[i].getRGB();
        rgb2 = colors[i+1].getRGB();

        // fill this array with the colors in between rgb1 and rgb2
        interpolate(rgb1, rgb2, gradients[i]);

        // if the colors are opaque, transparency should still
        // be 0xff000000
        transparencyTest &= rgb1;
        transparencyTest &= rgb2;
    }

    // if interpolation occurred in Linear RGB space, convert the
    // gradients back to SRGB using the lookup table
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        for (int j = 0; j < gradients.length; j++) {
            for (int i = 0; i < gradients[j].length; i++) {
                gradients[j][i] =
                    convertEntireColorLinearRGBtoSRGB(gradients[j][i]);
            }
        }
    }
}
 
源代码11 项目: openjdk-8-source   文件: OGLPaints.java
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
    LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;

    if (paint.getFractions().length == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT &&
        paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
    {
        // we can delegate to the optimized two-color gradient
        // codepath, which does not require fragment shader support
        return true;
    }

    return super.isPaintValid(sg2d);
}
 
/**
 * 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.
 */
private void calculateLookupData(Color[] colors) {
    Color[] normalizedColors;
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        // create a new colors array
        normalizedColors = new Color[colors.length];
        // convert the colors using the lookup table
        for (int i = 0; i < colors.length; i++) {
            int argb = colors[i].getRGB();
            int a = argb >>> 24;
            int r = SRGBtoLinearRGB[(argb >> 16) & 0xff];
            int g = SRGBtoLinearRGB[(argb >>  8) & 0xff];
            int b = SRGBtoLinearRGB[(argb      ) & 0xff];
            normalizedColors[i] = new Color(r, g, b, a);
        }
    } else {
        // we can just use this array by reference since we do not
        // modify its values in the case of SRGB
        normalizedColors = colors;
    }

    // this will store the intervals (distances) between gradient stops
    normalizedIntervals = new float[fractions.length-1];

    // convert from fractions into intervals
    for (int i = 0; i < normalizedIntervals.length; i++) {
        // interval distance is equal to the difference in positions
        normalizedIntervals[i] = this.fractions[i+1] - this.fractions[i];
    }

    // initialize to be fully opaque for ANDing with colors
    transparencyTest = 0xff000000;

    // array of interpolation arrays
    gradients = new int[normalizedIntervals.length][];

    // find smallest interval
    float Imin = 1;
    for (int i = 0; i < normalizedIntervals.length; i++) {
        Imin = (Imin > normalizedIntervals[i]) ?
            normalizedIntervals[i] : Imin;
    }

    // Estimate the size of the entire gradients array.
    // This is to prevent a tiny interval from causing the size of array
    // to explode.  If the estimated size is too large, break to using
    // separate arrays for each interval, and using an indexing scheme at
    // look-up time.
    int estimatedSize = 0;
    for (int i = 0; i < normalizedIntervals.length; i++) {
        estimatedSize += (normalizedIntervals[i]/Imin) * GRADIENT_SIZE;
    }

    if (estimatedSize > MAX_GRADIENT_ARRAY_SIZE) {
        // slow method
        calculateMultipleArrayGradient(normalizedColors);
    } else {
        // fast method
        calculateSingleArrayGradient(normalizedColors, Imin);
    }

    // use the most "economical" model
    if ((transparencyTest >>> 24) == 0xff) {
        model = xrgbmodel;
    } else {
        model = ColorModel.getRGBdefault();
    }
}
 
源代码13 项目: dragonwell8_jdk   文件: BufferedPaints.java
/**
 * This method uses techniques that are nearly identical to those
 * employed in setGradientPaint() above.  The primary difference
 * is that at the native level we use a fragment shader to manually
 * apply the plane equation constants to the current fragment position
 * to calculate the gradient position in the range [0,1] (the native
 * code for GradientPaint does the same, except that it uses OpenGL's
 * automatic texture coordinate generation facilities).
 *
 * One other minor difference worth mentioning is that
 * setGradientPaint() calculates the plane equation constants
 * such that the gradient end points are positioned at 0.25 and 0.75
 * (for reasons discussed in the comments for that method).  In
 * contrast, for LinearGradientPaint we setup the equation constants
 * such that the gradient end points fall at 0.0 and 1.0.  The
 * reason for this difference is that in the fragment shader we
 * have more control over how the gradient values are interpreted
 * (depending on the paint's CycleMethod).
 */
private static void setLinearGradientPaint(RenderQueue rq,
                                           SunGraphics2D sg2d,
                                           LinearGradientPaint paint,
                                           boolean useMask)
{
    boolean linear =
        (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
    Color[] colors = paint.getColors();
    int numStops = colors.length;
    Point2D pt1 = paint.getStartPoint();
    Point2D pt2 = paint.getEndPoint();
    AffineTransform at = paint.getTransform();
    at.preConcatenate(sg2d.transform);

    if (!linear && numStops == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT)
    {
        // delegate to the optimized two-color gradient codepath
        boolean isCyclic =
            (paint.getCycleMethod() != CycleMethod.NO_CYCLE);
        setGradientPaint(rq, at,
                         colors[0], colors[1],
                         pt1, pt2,
                         isCyclic, useMask);
        return;
    }

    int cycleMethod = paint.getCycleMethod().ordinal();
    float[] fractions = paint.getFractions();
    int[] pixels = convertToIntArgbPrePixels(colors, linear);

    // calculate plane equation constants
    double x = pt1.getX();
    double y = pt1.getY();
    at.translate(x, y);
    // now gradient point 1 is at the origin
    x = pt2.getX() - x;
    y = pt2.getY() - y;
    double len = Math.sqrt(x * x + y * y);
    at.rotate(x, y);
    // now gradient point 2 is on the positive x-axis
    at.scale(len, 1);
    // now gradient point 1 is at (0.0, 0), point 2 is at (1.0, 0)

    float p0, p1, p3;
    try {
        at.invert();
        p0 = (float)at.getScaleX();
        p1 = (float)at.getShearX();
        p3 = (float)at.getTranslateX();
    } catch (java.awt.geom.NoninvertibleTransformException e) {
        p0 = p1 = p3 = 0.0f;
    }

    // assert rq.lock.isHeldByCurrentThread();
    rq.ensureCapacity(20 + 12 + (numStops*4*2));
    RenderBuffer buf = rq.getBuffer();
    buf.putInt(SET_LINEAR_GRADIENT_PAINT);
    buf.putInt(useMask ? 1 : 0);
    buf.putInt(linear  ? 1 : 0);
    buf.putInt(cycleMethod);
    buf.putInt(numStops);
    buf.putFloat(p0);
    buf.putFloat(p1);
    buf.putFloat(p3);
    buf.put(fractions);
    buf.put(pixels);
}
 
/**
 * 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.
 *
 * @param Imin the size of the smallest interval
 */
private void calculateSingleArrayGradient(Color[] colors, float Imin) {
    // set the flag so we know later it is a simple (fast) lookup
    isSimpleLookup = true;

    // 2 colors to interpolate
    int rgb1, rgb2;

    //the eventual size of the single array
    int gradientsTot = 1;

    // for every interval (transition between 2 colors)
    for (int i = 0; i < gradients.length; i++) {
        // create an array whose size is based on the ratio to the
        // smallest interval
        int nGradients = (int)((normalizedIntervals[i]/Imin)*255f);
        gradientsTot += nGradients;
        gradients[i] = new int[nGradients];

        // the 2 colors (keyframes) to interpolate between
        rgb1 = colors[i].getRGB();
        rgb2 = colors[i+1].getRGB();

        // fill this array with the colors in between rgb1 and rgb2
        interpolate(rgb1, rgb2, gradients[i]);

        // if the colors are opaque, transparency should still
        // be 0xff000000
        transparencyTest &= rgb1;
        transparencyTest &= rgb2;
    }

    // put all gradients in a single array
    gradient = new int[gradientsTot];
    int curOffset = 0;
    for (int i = 0; i < gradients.length; i++){
        System.arraycopy(gradients[i], 0, gradient,
                         curOffset, gradients[i].length);
        curOffset += gradients[i].length;
    }
    gradient[gradient.length-1] = colors[colors.length-1].getRGB();

    // if interpolation occurred in Linear RGB space, convert the
    // gradients back to sRGB using the lookup table
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        for (int i = 0; i < gradient.length; i++) {
            gradient[i] = convertEntireColorLinearRGBtoSRGB(gradient[i]);
        }
    }

    fastGradientArraySize = gradient.length - 1;
}
 
源代码15 项目: jdk8u_jdk   文件: BufferedPaints.java
/**
 * This method uses techniques that are nearly identical to those
 * employed in setGradientPaint() above.  The primary difference
 * is that at the native level we use a fragment shader to manually
 * apply the plane equation constants to the current fragment position
 * to calculate the gradient position in the range [0,1] (the native
 * code for GradientPaint does the same, except that it uses OpenGL's
 * automatic texture coordinate generation facilities).
 *
 * One other minor difference worth mentioning is that
 * setGradientPaint() calculates the plane equation constants
 * such that the gradient end points are positioned at 0.25 and 0.75
 * (for reasons discussed in the comments for that method).  In
 * contrast, for LinearGradientPaint we setup the equation constants
 * such that the gradient end points fall at 0.0 and 1.0.  The
 * reason for this difference is that in the fragment shader we
 * have more control over how the gradient values are interpreted
 * (depending on the paint's CycleMethod).
 */
private static void setLinearGradientPaint(RenderQueue rq,
                                           SunGraphics2D sg2d,
                                           LinearGradientPaint paint,
                                           boolean useMask)
{
    boolean linear =
        (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
    Color[] colors = paint.getColors();
    int numStops = colors.length;
    Point2D pt1 = paint.getStartPoint();
    Point2D pt2 = paint.getEndPoint();
    AffineTransform at = paint.getTransform();
    at.preConcatenate(sg2d.transform);

    if (!linear && numStops == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT)
    {
        // delegate to the optimized two-color gradient codepath
        boolean isCyclic =
            (paint.getCycleMethod() != CycleMethod.NO_CYCLE);
        setGradientPaint(rq, at,
                         colors[0], colors[1],
                         pt1, pt2,
                         isCyclic, useMask);
        return;
    }

    int cycleMethod = paint.getCycleMethod().ordinal();
    float[] fractions = paint.getFractions();
    int[] pixels = convertToIntArgbPrePixels(colors, linear);

    // calculate plane equation constants
    double x = pt1.getX();
    double y = pt1.getY();
    at.translate(x, y);
    // now gradient point 1 is at the origin
    x = pt2.getX() - x;
    y = pt2.getY() - y;
    double len = Math.sqrt(x * x + y * y);
    at.rotate(x, y);
    // now gradient point 2 is on the positive x-axis
    at.scale(len, 1);
    // now gradient point 1 is at (0.0, 0), point 2 is at (1.0, 0)

    float p0, p1, p3;
    try {
        at.invert();
        p0 = (float)at.getScaleX();
        p1 = (float)at.getShearX();
        p3 = (float)at.getTranslateX();
    } catch (java.awt.geom.NoninvertibleTransformException e) {
        p0 = p1 = p3 = 0.0f;
    }

    // assert rq.lock.isHeldByCurrentThread();
    rq.ensureCapacity(20 + 12 + (numStops*4*2));
    RenderBuffer buf = rq.getBuffer();
    buf.putInt(SET_LINEAR_GRADIENT_PAINT);
    buf.putInt(useMask ? 1 : 0);
    buf.putInt(linear  ? 1 : 0);
    buf.putInt(cycleMethod);
    buf.putInt(numStops);
    buf.putFloat(p0);
    buf.putFloat(p1);
    buf.putFloat(p3);
    buf.put(fractions);
    buf.put(pixels);
}
 
源代码16 项目: openjdk-jdk8u   文件: BufferedPaints.java
/**
 * This method calculates six m** values and a focusX value that
 * are used by the native fragment shader.  These techniques are
 * based on a whitepaper by Daniel Rice on radial gradient performance
 * (attached to the bug report for 6521533).  One can refer to that
 * document for the complete set of formulas and calculations, but
 * the basic goal is to compose a transform that will convert an
 * (x,y) position in device space into a "u" value that represents
 * the relative distance to the gradient focus point.  The resulting
 * value can be used to look up the appropriate color by linearly
 * interpolating between the two nearest colors in the gradient.
 */
private static void setRadialGradientPaint(RenderQueue rq,
                                           SunGraphics2D sg2d,
                                           RadialGradientPaint paint,
                                           boolean useMask)
{
    boolean linear =
        (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
    int cycleMethod = paint.getCycleMethod().ordinal();
    float[] fractions = paint.getFractions();
    Color[] colors = paint.getColors();
    int numStops = colors.length;
    int[] pixels = convertToIntArgbPrePixels(colors, linear);
    Point2D center = paint.getCenterPoint();
    Point2D focus = paint.getFocusPoint();
    float radius = paint.getRadius();

    // save original (untransformed) center and focus points
    double cx = center.getX();
    double cy = center.getY();
    double fx = focus.getX();
    double fy = focus.getY();

    // transform from gradient coords to device coords
    AffineTransform at = paint.getTransform();
    at.preConcatenate(sg2d.transform);
    focus = at.transform(focus, focus);

    // transform unit circle to gradient coords; we start with the
    // unit circle (center=(0,0), focus on positive x-axis, radius=1)
    // and then transform into gradient space
    at.translate(cx, cy);
    at.rotate(fx - cx, fy - cy);
    at.scale(radius, radius);

    // invert to get mapping from device coords to unit circle
    try {
        at.invert();
    } catch (Exception e) {
        at.setToScale(0.0, 0.0);
    }
    focus = at.transform(focus, focus);

    // clamp the focus point so that it does not rest on, or outside
    // of, the circumference of the gradient circle
    fx = Math.min(focus.getX(), 0.99);

    // assert rq.lock.isHeldByCurrentThread();
    rq.ensureCapacity(20 + 28 + (numStops*4*2));
    RenderBuffer buf = rq.getBuffer();
    buf.putInt(SET_RADIAL_GRADIENT_PAINT);
    buf.putInt(useMask ? 1 : 0);
    buf.putInt(linear  ? 1 : 0);
    buf.putInt(numStops);
    buf.putInt(cycleMethod);
    buf.putFloat((float)at.getScaleX());
    buf.putFloat((float)at.getShearX());
    buf.putFloat((float)at.getTranslateX());
    buf.putFloat((float)at.getShearY());
    buf.putFloat((float)at.getScaleY());
    buf.putFloat((float)at.getTranslateY());
    buf.putFloat((float)fx);
    buf.put(fractions);
    buf.put(pixels);
}
 
源代码17 项目: openjdk-8   文件: BufferedPaints.java
/**
 * This method uses techniques that are nearly identical to those
 * employed in setGradientPaint() above.  The primary difference
 * is that at the native level we use a fragment shader to manually
 * apply the plane equation constants to the current fragment position
 * to calculate the gradient position in the range [0,1] (the native
 * code for GradientPaint does the same, except that it uses OpenGL's
 * automatic texture coordinate generation facilities).
 *
 * One other minor difference worth mentioning is that
 * setGradientPaint() calculates the plane equation constants
 * such that the gradient end points are positioned at 0.25 and 0.75
 * (for reasons discussed in the comments for that method).  In
 * contrast, for LinearGradientPaint we setup the equation constants
 * such that the gradient end points fall at 0.0 and 1.0.  The
 * reason for this difference is that in the fragment shader we
 * have more control over how the gradient values are interpreted
 * (depending on the paint's CycleMethod).
 */
private static void setLinearGradientPaint(RenderQueue rq,
                                           SunGraphics2D sg2d,
                                           LinearGradientPaint paint,
                                           boolean useMask)
{
    boolean linear =
        (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
    Color[] colors = paint.getColors();
    int numStops = colors.length;
    Point2D pt1 = paint.getStartPoint();
    Point2D pt2 = paint.getEndPoint();
    AffineTransform at = paint.getTransform();
    at.preConcatenate(sg2d.transform);

    if (!linear && numStops == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT)
    {
        // delegate to the optimized two-color gradient codepath
        boolean isCyclic =
            (paint.getCycleMethod() != CycleMethod.NO_CYCLE);
        setGradientPaint(rq, at,
                         colors[0], colors[1],
                         pt1, pt2,
                         isCyclic, useMask);
        return;
    }

    int cycleMethod = paint.getCycleMethod().ordinal();
    float[] fractions = paint.getFractions();
    int[] pixels = convertToIntArgbPrePixels(colors, linear);

    // calculate plane equation constants
    double x = pt1.getX();
    double y = pt1.getY();
    at.translate(x, y);
    // now gradient point 1 is at the origin
    x = pt2.getX() - x;
    y = pt2.getY() - y;
    double len = Math.sqrt(x * x + y * y);
    at.rotate(x, y);
    // now gradient point 2 is on the positive x-axis
    at.scale(len, 1);
    // now gradient point 1 is at (0.0, 0), point 2 is at (1.0, 0)

    float p0, p1, p3;
    try {
        at.invert();
        p0 = (float)at.getScaleX();
        p1 = (float)at.getShearX();
        p3 = (float)at.getTranslateX();
    } catch (java.awt.geom.NoninvertibleTransformException e) {
        p0 = p1 = p3 = 0.0f;
    }

    // assert rq.lock.isHeldByCurrentThread();
    rq.ensureCapacity(20 + 12 + (numStops*4*2));
    RenderBuffer buf = rq.getBuffer();
    buf.putInt(SET_LINEAR_GRADIENT_PAINT);
    buf.putInt(useMask ? 1 : 0);
    buf.putInt(linear  ? 1 : 0);
    buf.putInt(cycleMethod);
    buf.putInt(numStops);
    buf.putFloat(p0);
    buf.putFloat(p1);
    buf.putFloat(p3);
    buf.put(fractions);
    buf.put(pixels);
}
 
源代码18 项目: openjdk-8   文件: BufferedPaints.java
/**
 * This method calculates six m** values and a focusX value that
 * are used by the native fragment shader.  These techniques are
 * based on a whitepaper by Daniel Rice on radial gradient performance
 * (attached to the bug report for 6521533).  One can refer to that
 * document for the complete set of formulas and calculations, but
 * the basic goal is to compose a transform that will convert an
 * (x,y) position in device space into a "u" value that represents
 * the relative distance to the gradient focus point.  The resulting
 * value can be used to look up the appropriate color by linearly
 * interpolating between the two nearest colors in the gradient.
 */
private static void setRadialGradientPaint(RenderQueue rq,
                                           SunGraphics2D sg2d,
                                           RadialGradientPaint paint,
                                           boolean useMask)
{
    boolean linear =
        (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
    int cycleMethod = paint.getCycleMethod().ordinal();
    float[] fractions = paint.getFractions();
    Color[] colors = paint.getColors();
    int numStops = colors.length;
    int[] pixels = convertToIntArgbPrePixels(colors, linear);
    Point2D center = paint.getCenterPoint();
    Point2D focus = paint.getFocusPoint();
    float radius = paint.getRadius();

    // save original (untransformed) center and focus points
    double cx = center.getX();
    double cy = center.getY();
    double fx = focus.getX();
    double fy = focus.getY();

    // transform from gradient coords to device coords
    AffineTransform at = paint.getTransform();
    at.preConcatenate(sg2d.transform);
    focus = at.transform(focus, focus);

    // transform unit circle to gradient coords; we start with the
    // unit circle (center=(0,0), focus on positive x-axis, radius=1)
    // and then transform into gradient space
    at.translate(cx, cy);
    at.rotate(fx - cx, fy - cy);
    at.scale(radius, radius);

    // invert to get mapping from device coords to unit circle
    try {
        at.invert();
    } catch (Exception e) {
        at.setToScale(0.0, 0.0);
    }
    focus = at.transform(focus, focus);

    // clamp the focus point so that it does not rest on, or outside
    // of, the circumference of the gradient circle
    fx = Math.min(focus.getX(), 0.99);

    // assert rq.lock.isHeldByCurrentThread();
    rq.ensureCapacity(20 + 28 + (numStops*4*2));
    RenderBuffer buf = rq.getBuffer();
    buf.putInt(SET_RADIAL_GRADIENT_PAINT);
    buf.putInt(useMask ? 1 : 0);
    buf.putInt(linear  ? 1 : 0);
    buf.putInt(numStops);
    buf.putInt(cycleMethod);
    buf.putFloat((float)at.getScaleX());
    buf.putFloat((float)at.getShearX());
    buf.putFloat((float)at.getTranslateX());
    buf.putFloat((float)at.getShearY());
    buf.putFloat((float)at.getScaleY());
    buf.putFloat((float)at.getTranslateY());
    buf.putFloat((float)fx);
    buf.put(fractions);
    buf.put(pixels);
}
 
源代码19 项目: jdk8u60   文件: BufferedPaints.java
/**
 * This method uses techniques that are nearly identical to those
 * employed in setGradientPaint() above.  The primary difference
 * is that at the native level we use a fragment shader to manually
 * apply the plane equation constants to the current fragment position
 * to calculate the gradient position in the range [0,1] (the native
 * code for GradientPaint does the same, except that it uses OpenGL's
 * automatic texture coordinate generation facilities).
 *
 * One other minor difference worth mentioning is that
 * setGradientPaint() calculates the plane equation constants
 * such that the gradient end points are positioned at 0.25 and 0.75
 * (for reasons discussed in the comments for that method).  In
 * contrast, for LinearGradientPaint we setup the equation constants
 * such that the gradient end points fall at 0.0 and 1.0.  The
 * reason for this difference is that in the fragment shader we
 * have more control over how the gradient values are interpreted
 * (depending on the paint's CycleMethod).
 */
private static void setLinearGradientPaint(RenderQueue rq,
                                           SunGraphics2D sg2d,
                                           LinearGradientPaint paint,
                                           boolean useMask)
{
    boolean linear =
        (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
    Color[] colors = paint.getColors();
    int numStops = colors.length;
    Point2D pt1 = paint.getStartPoint();
    Point2D pt2 = paint.getEndPoint();
    AffineTransform at = paint.getTransform();
    at.preConcatenate(sg2d.transform);

    if (!linear && numStops == 2 &&
        paint.getCycleMethod() != CycleMethod.REPEAT)
    {
        // delegate to the optimized two-color gradient codepath
        boolean isCyclic =
            (paint.getCycleMethod() != CycleMethod.NO_CYCLE);
        setGradientPaint(rq, at,
                         colors[0], colors[1],
                         pt1, pt2,
                         isCyclic, useMask);
        return;
    }

    int cycleMethod = paint.getCycleMethod().ordinal();
    float[] fractions = paint.getFractions();
    int[] pixels = convertToIntArgbPrePixels(colors, linear);

    // calculate plane equation constants
    double x = pt1.getX();
    double y = pt1.getY();
    at.translate(x, y);
    // now gradient point 1 is at the origin
    x = pt2.getX() - x;
    y = pt2.getY() - y;
    double len = Math.sqrt(x * x + y * y);
    at.rotate(x, y);
    // now gradient point 2 is on the positive x-axis
    at.scale(len, 1);
    // now gradient point 1 is at (0.0, 0), point 2 is at (1.0, 0)

    float p0, p1, p3;
    try {
        at.invert();
        p0 = (float)at.getScaleX();
        p1 = (float)at.getShearX();
        p3 = (float)at.getTranslateX();
    } catch (java.awt.geom.NoninvertibleTransformException e) {
        p0 = p1 = p3 = 0.0f;
    }

    // assert rq.lock.isHeldByCurrentThread();
    rq.ensureCapacity(20 + 12 + (numStops*4*2));
    RenderBuffer buf = rq.getBuffer();
    buf.putInt(SET_LINEAR_GRADIENT_PAINT);
    buf.putInt(useMask ? 1 : 0);
    buf.putInt(linear  ? 1 : 0);
    buf.putInt(cycleMethod);
    buf.putInt(numStops);
    buf.putFloat(p0);
    buf.putFloat(p1);
    buf.putFloat(p3);
    buf.put(fractions);
    buf.put(pixels);
}
 
/**
 * 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.
 */
private void calculateLookupData(Color[] colors) {
    Color[] normalizedColors;
    if (colorSpace == ColorSpaceType.LINEAR_RGB) {
        // create a new colors array
        normalizedColors = new Color[colors.length];
        // convert the colors using the lookup table
        for (int i = 0; i < colors.length; i++) {
            int argb = colors[i].getRGB();
            int a = argb >>> 24;
            int r = SRGBtoLinearRGB[(argb >> 16) & 0xff];
            int g = SRGBtoLinearRGB[(argb >>  8) & 0xff];
            int b = SRGBtoLinearRGB[(argb      ) & 0xff];
            normalizedColors[i] = new Color(r, g, b, a);
        }
    } else {
        // we can just use this array by reference since we do not
        // modify its values in the case of SRGB
        normalizedColors = colors;
    }

    // this will store the intervals (distances) between gradient stops
    normalizedIntervals = new float[fractions.length-1];

    // convert from fractions into intervals
    for (int i = 0; i < normalizedIntervals.length; i++) {
        // interval distance is equal to the difference in positions
        normalizedIntervals[i] = this.fractions[i+1] - this.fractions[i];
    }

    // initialize to be fully opaque for ANDing with colors
    transparencyTest = 0xff000000;

    // array of interpolation arrays
    gradients = new int[normalizedIntervals.length][];

    // find smallest interval
    float Imin = 1;
    for (int i = 0; i < normalizedIntervals.length; i++) {
        Imin = (Imin > normalizedIntervals[i]) ?
            normalizedIntervals[i] : Imin;
    }

    // Estimate the size of the entire gradients array.
    // This is to prevent a tiny interval from causing the size of array
    // to explode.  If the estimated size is too large, break to using
    // separate arrays for each interval, and using an indexing scheme at
    // look-up time.
    int estimatedSize = 0;
    for (int i = 0; i < normalizedIntervals.length; i++) {
        estimatedSize += (normalizedIntervals[i]/Imin) * GRADIENT_SIZE;
    }

    if (estimatedSize > MAX_GRADIENT_ARRAY_SIZE) {
        // slow method
        calculateMultipleArrayGradient(normalizedColors);
    } else {
        // fast method
        calculateSingleArrayGradient(normalizedColors, Imin);
    }

    // use the most "economical" model
    if ((transparencyTest >>> 24) == 0xff) {
        model = xrgbmodel;
    } else {
        model = ColorModel.getRGBdefault();
    }
}