jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java
author neugens
Sat, 03 Dec 2011 15:40:49 +0100
changeset 11080 7e18e343964e
parent 7668 d4a77089c587
child 12813 c10ab96dcf41
permissions -rw-r--r--
7117914: Fix javac warnings in src/share/classes/sun/java2d Summary: Fix some javac warnings in java2d related code for the Warning Cleanup Day. Reviewed-by: prr, flar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 5580
diff changeset
     2
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.java2d.pipe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Color;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.GradientPaint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.LinearGradientPaint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.MultipleGradientPaint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.MultipleGradientPaint.ColorSpaceType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.MultipleGradientPaint.CycleMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.Paint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.RadialGradientPaint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.TexturePaint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.geom.AffineTransform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.awt.geom.Point2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.awt.geom.Rectangle2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.awt.image.AffineTransformOp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import sun.awt.image.PixelConverter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import sun.java2d.SunGraphics2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import sun.java2d.SurfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import sun.java2d.loops.CompositeType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import sun.java2d.loops.SurfaceType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import static sun.java2d.pipe.BufferedOpCodes.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
public class BufferedPaints {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    static void setPaint(RenderQueue rq, SunGraphics2D sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
                         Paint paint, int ctxflags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
            setColor(rq, sg2d.pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
            boolean useMask = (ctxflags & BufferedContext.USE_MASK) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
            switch (sg2d.paintState) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
            case SunGraphics2D.PAINT_GRADIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
                setGradientPaint(rq, sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
                                 (GradientPaint)paint, useMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
            case SunGraphics2D.PAINT_LIN_GRADIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
                setLinearGradientPaint(rq, sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
                                       (LinearGradientPaint)paint, useMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            case SunGraphics2D.PAINT_RAD_GRADIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
                setRadialGradientPaint(rq, sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
                                       (RadialGradientPaint)paint, useMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
            case SunGraphics2D.PAINT_TEXTURE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
                setTexturePaint(rq, sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
                                (TexturePaint)paint, useMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    static void resetPaint(RenderQueue rq) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        // assert rq.lock.isHeldByCurrentThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        rq.ensureCapacity(4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        RenderBuffer buf = rq.getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        buf.putInt(RESET_PAINT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
/****************************** Color support *******************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    private static void setColor(RenderQueue rq, int pixel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        // assert rq.lock.isHeldByCurrentThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        rq.ensureCapacity(8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        RenderBuffer buf = rq.getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        buf.putInt(SET_COLOR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        buf.putInt(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
/************************* GradientPaint support ****************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * Note: This code is factored out into a separate static method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * so that it can be shared by both the Gradient and LinearGradient
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * implementations.  LinearGradient uses this code (for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * two-color sRGB case only) because it can be much faster than the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * equivalent implementation that uses fragment shaders.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     * We use OpenGL's texture coordinate generator to automatically
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * apply a smooth gradient (either cyclic or acyclic) to the geometry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * being rendered.  This technique is almost identical to the one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * described in the comments for BufferedPaints.setTexturePaint(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * except the calculations take place in one dimension instead of two.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * Instead of an anchor rectangle in the TexturePaint case, we use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * the vector between the two GradientPaint end points in our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * calculations.  The generator uses a single plane equation that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * takes the (x,y) location (in device space) of the fragment being
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * rendered to calculate a (u) texture coordinate for that fragment:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     *     u = Ax + By + Cz + Dw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * The gradient renderer uses a two-pixel 1D texture where the first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * pixel contains the first GradientPaint color, and the second pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * contains the second GradientPaint color.  (Note that we use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * GL_CLAMP_TO_EDGE wrapping mode for acyclic gradients so that we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * clamp the colors properly at the extremes.)  The following diagram
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * attempts to show the layout of the texture containing the two
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * GradientPaint colors (C1 and C2):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     *                        +-----------------+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     *                        |   C1   |   C2   |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     *                        |        |        |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     *                        +-----------------+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     *                      u=0  .25  .5   .75  1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * We calculate our plane equation constants (A,B,D) such that u=0.25
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * corresponds to the first GradientPaint end point in user space and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * u=0.75 corresponds to the second end point.  This is somewhat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * non-obvious, but since the gradient colors are generated by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * interpolating between C1 and C2, we want the pure color at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * end points, and we will get the pure color only when u correlates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * to the center of a texel.  The following chart shows the expected
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * color for some sample values of u (where C' is the color halfway
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * between C1 and C2):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     *       u value      acyclic (GL_CLAMP)      cyclic (GL_REPEAT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     *       -------      ------------------      ------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     *        -0.25              C1                       C2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     *         0.0               C1                       C'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     *         0.25              C1                       C1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     *         0.5               C'                       C'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     *         0.75              C2                       C2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     *         1.0               C2                       C'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     *         1.25              C2                       C1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * Original inspiration for this technique came from UMD's Agile2D
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * project (GradientManager.java).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    private static void setGradientPaint(RenderQueue rq, AffineTransform at,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                                         Color c1, Color c2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                                         Point2D pt1, Point2D pt2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                                         boolean isCyclic, boolean useMask)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        // convert gradient colors to IntArgbPre format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        PixelConverter pc = PixelConverter.ArgbPre.instance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        int pixel1 = pc.rgbToPixel(c1.getRGB(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        int pixel2 = pc.rgbToPixel(c2.getRGB(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        // calculate plane equation constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        double x = pt1.getX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        double y = pt1.getY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        at.translate(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        // now gradient point 1 is at the origin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        x = pt2.getX() - x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        y = pt2.getY() - y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        double len = Math.sqrt(x * x + y * y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        at.rotate(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        // now gradient point 2 is on the positive x-axis
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        at.scale(2*len, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        // now gradient point 2 is at (0.5, 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        at.translate(-0.25, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        // now gradient point 1 is at (0.25, 0), point 2 is at (0.75, 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        double p0, p1, p3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            at.invert();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            p0 = at.getScaleX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            p1 = at.getShearX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            p3 = at.getTranslateX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        } catch (java.awt.geom.NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            p0 = p1 = p3 = 0.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        // assert rq.lock.isHeldByCurrentThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        rq.ensureCapacityAndAlignment(44, 12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        RenderBuffer buf = rq.getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        buf.putInt(SET_GRADIENT_PAINT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        buf.putInt(useMask ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        buf.putInt(isCyclic ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        buf.putDouble(p0).putDouble(p1).putDouble(p3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        buf.putInt(pixel1).putInt(pixel2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    private static void setGradientPaint(RenderQueue rq,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                                         SunGraphics2D sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                                         GradientPaint paint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                                         boolean useMask)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        setGradientPaint(rq, (AffineTransform)sg2d.transform.clone(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                         paint.getColor1(), paint.getColor2(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                         paint.getPoint1(), paint.getPoint2(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                         paint.isCyclic(), useMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
/************************** TexturePaint support ****************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * We use OpenGL's texture coordinate generator to automatically
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * map the TexturePaint image to the geometry being rendered.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * generator uses two separate plane equations that take the (x,y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * location (in device space) of the fragment being rendered to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     * calculate (u,v) texture coordinates for that fragment:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     *     u = Ax + By + Cz + Dw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     *     v = Ex + Fy + Gz + Hw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     * Since we use a 2D orthographic projection, we can assume that z=0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * and w=1 for any fragment.  So we need to calculate appropriate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * values for the plane equation constants (A,B,D) and (E,F,H) such
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * that {u,v}=0 for the top-left of the TexturePaint's anchor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * rectangle and {u,v}=1 for the bottom-right of the anchor rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * We can easily make the texture image repeat for {u,v} values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * outside the range [0,1] by specifying the GL_REPEAT texture wrap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * mode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * Calculating the plane equation constants is surprisingly simple.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * We can think of it as an inverse matrix operation that takes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * device space coordinates and transforms them into user space
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * coordinates that correspond to a location relative to the anchor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * rectangle.  First, we translate and scale the current user space
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * transform by applying the anchor rectangle bounds.  We then take
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * the inverse of this affine transform.  The rows of the resulting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * inverse matrix correlate nicely to the plane equation constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * we were seeking.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    private static void setTexturePaint(RenderQueue rq,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                                        SunGraphics2D sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                                        TexturePaint paint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                                        boolean useMask)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        BufferedImage bi = paint.getImage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        SurfaceData dstData = sg2d.surfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        SurfaceData srcData =
11080
7e18e343964e 7117914: Fix javac warnings in src/share/classes/sun/java2d
neugens
parents: 7668
diff changeset
   250
            dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                                         CompositeType.SrcOver, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        boolean filter =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            (sg2d.interpolationType !=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
             AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        // calculate plane equation constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        AffineTransform at = (AffineTransform)sg2d.transform.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        Rectangle2D anchor = paint.getAnchorRect();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        at.translate(anchor.getX(), anchor.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        at.scale(anchor.getWidth(), anchor.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        double xp0, xp1, xp3, yp0, yp1, yp3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            at.invert();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            xp0 = at.getScaleX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            xp1 = at.getShearX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            xp3 = at.getTranslateX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            yp0 = at.getShearY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            yp1 = at.getScaleY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            yp3 = at.getTranslateY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        } catch (java.awt.geom.NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            xp0 = xp1 = xp3 = yp0 = yp1 = yp3 = 0.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        // assert rq.lock.isHeldByCurrentThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        rq.ensureCapacityAndAlignment(68, 12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        RenderBuffer buf = rq.getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        buf.putInt(SET_TEXTURE_PAINT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        buf.putInt(useMask ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        buf.putInt(filter ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        buf.putLong(srcData.getNativeOps());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        buf.putDouble(xp0).putDouble(xp1).putDouble(xp3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        buf.putDouble(yp0).putDouble(yp1).putDouble(yp3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
/****************** Shared MultipleGradientPaint support ********************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * The maximum number of gradient "stops" supported by our native
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     * fragment shader implementations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     * This value has been empirically determined and capped to allow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     * our native shaders to run on all shader-level graphics hardware,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
     * even on the older, more limited GPUs.  Even the oldest Nvidia
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     * hardware could handle 16, or even 32 fractions without any problem.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * But the first-generation boards from ATI would fall back into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * software mode (which is unusably slow) for values larger than 12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * it appears that those boards do not have enough native registers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * to support the number of array accesses required by our gradient
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * shaders.  So for now we will cap this value at 12, but we can
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * re-evaluate this in the future as hardware becomes more capable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    public static final int MULTI_MAX_FRACTIONS = 12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * Helper function to convert a color component in sRGB space to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * linear RGB space.  Copied directly from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * MultipleGradientPaintContext class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     */
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   310
    public static int convertSRGBtoLinearRGB(int color) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        float input, output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        input = color / 255.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        if (input <= 0.04045f) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            output = input / 12.92f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            output = (float)Math.pow((input + 0.055) / 1.055, 2.4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        return Math.round(output * 255.0f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * Helper function to convert a (non-premultiplied) Color in sRGB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * space to an IntArgbPre pixel value, optionally in linear RGB space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * Based on the PixelConverter.ArgbPre.rgbToPixel() method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    private static int colorToIntArgbPrePixel(Color c, boolean linear) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        int rgb = c.getRGB();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        if (!linear && ((rgb >> 24) == -1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            return rgb;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        int a = rgb >>> 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        int r = (rgb >> 16) & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        int g = (rgb >>  8) & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        int b = (rgb      ) & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if (linear) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            r = convertSRGBtoLinearRGB(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            g = convertSRGBtoLinearRGB(g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            b = convertSRGBtoLinearRGB(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        int a2 = a + (a >> 7);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        r = (r * a2) >> 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        g = (g * a2) >> 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        b = (b * a2) >> 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        return ((a << 24) | (r << 16) | (g << 8) | (b));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * Converts the given array of Color objects into an int array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * containing IntArgbPre pixel values.  If the linear parameter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     * is true, the Color values will be converted into a linear RGB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * color space before being returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    private static int[] convertToIntArgbPrePixels(Color[] colors,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                                                   boolean linear)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        int[] pixels = new int[colors.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        for (int i = 0; i < colors.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            pixels[i] = colorToIntArgbPrePixel(colors[i], linear);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        return pixels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
/********************** LinearGradientPaint support *************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     * This method uses techniques that are nearly identical to those
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * employed in setGradientPaint() above.  The primary difference
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * is that at the native level we use a fragment shader to manually
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * apply the plane equation constants to the current fragment position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * to calculate the gradient position in the range [0,1] (the native
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     * code for GradientPaint does the same, except that it uses OpenGL's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * automatic texture coordinate generation facilities).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     * One other minor difference worth mentioning is that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     * setGradientPaint() calculates the plane equation constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     * such that the gradient end points are positioned at 0.25 and 0.75
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * (for reasons discussed in the comments for that method).  In
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * contrast, for LinearGradientPaint we setup the equation constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * such that the gradient end points fall at 0.0 and 1.0.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * reason for this difference is that in the fragment shader we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * have more control over how the gradient values are interpreted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * (depending on the paint's CycleMethod).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    private static void setLinearGradientPaint(RenderQueue rq,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                                               SunGraphics2D sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                                               LinearGradientPaint paint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                                               boolean useMask)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        boolean linear =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        Color[] colors = paint.getColors();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        int numStops = colors.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        Point2D pt1 = paint.getStartPoint();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        Point2D pt2 = paint.getEndPoint();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        AffineTransform at = paint.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        at.preConcatenate(sg2d.transform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        if (!linear && numStops == 2 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            paint.getCycleMethod() != CycleMethod.REPEAT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            // delegate to the optimized two-color gradient codepath
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            boolean isCyclic =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                (paint.getCycleMethod() != CycleMethod.NO_CYCLE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            setGradientPaint(rq, at,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                             colors[0], colors[1],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                             pt1, pt2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                             isCyclic, useMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        int cycleMethod = paint.getCycleMethod().ordinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        float[] fractions = paint.getFractions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        int[] pixels = convertToIntArgbPrePixels(colors, linear);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        // calculate plane equation constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        double x = pt1.getX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        double y = pt1.getY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        at.translate(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        // now gradient point 1 is at the origin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        x = pt2.getX() - x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        y = pt2.getY() - y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        double len = Math.sqrt(x * x + y * y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        at.rotate(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        // now gradient point 2 is on the positive x-axis
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        at.scale(len, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        // now gradient point 1 is at (0.0, 0), point 2 is at (1.0, 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        float p0, p1, p3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            at.invert();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            p0 = (float)at.getScaleX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            p1 = (float)at.getShearX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            p3 = (float)at.getTranslateX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        } catch (java.awt.geom.NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            p0 = p1 = p3 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        // assert rq.lock.isHeldByCurrentThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        rq.ensureCapacity(20 + 12 + (numStops*4*2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        RenderBuffer buf = rq.getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        buf.putInt(SET_LINEAR_GRADIENT_PAINT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        buf.putInt(useMask ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        buf.putInt(linear  ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        buf.putInt(cycleMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        buf.putInt(numStops);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        buf.putFloat(p0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        buf.putFloat(p1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        buf.putFloat(p3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        buf.put(fractions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        buf.put(pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
/********************** RadialGradientPaint support *************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * This method calculates six m** values and a focusX value that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * are used by the native fragment shader.  These techniques are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * based on a whitepaper by Daniel Rice on radial gradient performance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * (attached to the bug report for 6521533).  One can refer to that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * document for the complete set of formulas and calculations, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * the basic goal is to compose a transform that will convert an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * (x,y) position in device space into a "u" value that represents
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * the relative distance to the gradient focus point.  The resulting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     * value can be used to look up the appropriate color by linearly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * interpolating between the two nearest colors in the gradient.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    private static void setRadialGradientPaint(RenderQueue rq,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                                               SunGraphics2D sg2d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                                               RadialGradientPaint paint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                                               boolean useMask)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        boolean linear =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        int cycleMethod = paint.getCycleMethod().ordinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        float[] fractions = paint.getFractions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        Color[] colors = paint.getColors();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        int numStops = colors.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        int[] pixels = convertToIntArgbPrePixels(colors, linear);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        Point2D center = paint.getCenterPoint();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        Point2D focus = paint.getFocusPoint();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        float radius = paint.getRadius();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        // save original (untransformed) center and focus points
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        double cx = center.getX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        double cy = center.getY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        double fx = focus.getX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        double fy = focus.getY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        // transform from gradient coords to device coords
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        AffineTransform at = paint.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        at.preConcatenate(sg2d.transform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        focus = at.transform(focus, focus);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        // transform unit circle to gradient coords; we start with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        // unit circle (center=(0,0), focus on positive x-axis, radius=1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        // and then transform into gradient space
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        at.translate(cx, cy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        at.rotate(fx - cx, fy - cy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        at.scale(radius, radius);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        // invert to get mapping from device coords to unit circle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            at.invert();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            at.setToScale(0.0, 0.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        focus = at.transform(focus, focus);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        // clamp the focus point so that it does not rest on, or outside
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        // of, the circumference of the gradient circle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        fx = Math.min(focus.getX(), 0.99);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        // assert rq.lock.isHeldByCurrentThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        rq.ensureCapacity(20 + 28 + (numStops*4*2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        RenderBuffer buf = rq.getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        buf.putInt(SET_RADIAL_GRADIENT_PAINT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        buf.putInt(useMask ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        buf.putInt(linear  ? 1 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        buf.putInt(numStops);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        buf.putInt(cycleMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        buf.putFloat((float)at.getScaleX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        buf.putFloat((float)at.getShearX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        buf.putFloat((float)at.getTranslateX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        buf.putFloat((float)at.getShearY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        buf.putFloat((float)at.getScaleY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        buf.putFloat((float)at.getTranslateY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        buf.putFloat((float)fx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        buf.put(fractions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        buf.put(pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
}