/*
 * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.java2d.pipe;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import sun.awt.image.PixelConverter;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.SurfaceType;
import static sun.java2d.pipe.BufferedOpCodes.*;

public class BufferedPaints {

    static void setPaint(RenderQueue rq, SunGraphics2D sg2d,
                         Paint paint, int ctxflags)
    {
        if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
            setColor(rq, sg2d.pixel);
        } else {
            boolean useMask = (ctxflags & BufferedContext.USE_MASK) != 0;
            switch (sg2d.paintState) {
            case SunGraphics2D.PAINT_GRADIENT:
                setGradientPaint(rq, sg2d,
                                 (GradientPaint)paint, useMask);
                break;
            case SunGraphics2D.PAINT_LIN_GRADIENT:
                setLinearGradientPaint(rq, sg2d,
                                       (LinearGradientPaint)paint, useMask);
                break;
            case SunGraphics2D.PAINT_RAD_GRADIENT:
                setRadialGradientPaint(rq, sg2d,
                                       (RadialGradientPaint)paint, useMask);
                break;
            case SunGraphics2D.PAINT_TEXTURE:
                setTexturePaint(rq, sg2d,
                                (TexturePaint)paint, useMask);
                break;
            default:
                break;
            }
        }
    }

    static void resetPaint(RenderQueue rq) {
        // assert rq.lock.isHeldByCurrentThread();
        rq.ensureCapacity(4);
        RenderBuffer buf = rq.getBuffer();
        buf.putInt(RESET_PAINT);
    }

/****************************** Color support *******************************/

    private static void setColor(RenderQueue rq, int pixel) {
        // assert rq.lock.isHeldByCurrentThread();
        rq.ensureCapacity(8);
        RenderBuffer buf = rq.getBuffer();
        buf.putInt(SET_COLOR);
        buf.putInt(pixel);
    }

/************************* GradientPaint support ****************************/

    /**
     * Note: This code is factored out into a separate static method
     * so that it can be shared by both the Gradient and LinearGradient
     * implementations.  LinearGradient uses this code (for the
     * two-color sRGB case only) because it can be much faster than the
     * equivalent implementation that uses fragment shaders.
     *
     * We use OpenGL's texture coordinate generator to automatically
     * apply a smooth gradient (either cyclic or acyclic) to the geometry
     * being rendered.  This technique is almost identical to the one
     * described in the comments for BufferedPaints.setTexturePaint(),
     * except the calculations take place in one dimension instead of two.
     * Instead of an anchor rectangle in the TexturePaint case, we use
     * the vector between the two GradientPaint end points in our
     * calculations.  The generator uses a single plane equation that
     * takes the (x,y) location (in device space) of the fragment being
     * rendered to calculate a (u) texture coordinate for that fragment:
     *     u = Ax + By + Cz + Dw
     *
     * The gradient renderer uses a two-pixel 1D texture where the first
     * pixel contains the first GradientPaint color, and the second pixel
     * contains the second GradientPaint color.  (Note that we use the
     * GL_CLAMP_TO_EDGE wrapping mode for acyclic gradients so that we
     * clamp the colors properly at the extremes.)  The following diagram
     * attempts to show the layout of the texture containing the two
     * GradientPaint colors (C1 and C2):
     *
     *                        +-----------------+
     *                        |   C1   |   C2   |
     *                        |        |        |
     *                        +-----------------+
     *                      u=0  .25  .5   .75  1
     *
     * We calculate our plane equation constants (A,B,D) such that u=0.25
     * corresponds to the first GradientPaint end point in user space and
     * u=0.75 corresponds to the second end point.  This is somewhat
     * non-obvious, but since the gradient colors are generated by
     * interpolating between C1 and C2, we want the pure color at the
     * end points, and we will get the pure color only when u correlates
     * to the center of a texel.  The following chart shows the expected
     * color for some sample values of u (where C' is the color halfway
     * between C1 and C2):
     *
     *       u value      acyclic (GL_CLAMP)      cyclic (GL_REPEAT)
     *       -------      ------------------      ------------------
     *        -0.25              C1                       C2
     *         0.0               C1                       C'
     *         0.25              C1                       C1
     *         0.5               C'                       C'
     *         0.75              C2                       C2
     *         1.0               C2                       C'
     *         1.25              C2                       C1
     *
     * Original inspiration for this technique came from UMD's Agile2D
     * project (GradientManager.java).
     */
    private static void setGradientPaint(RenderQueue rq, AffineTransform at,
                                         Color c1, Color c2,
                                         Point2D pt1, Point2D pt2,
                                         boolean isCyclic, boolean useMask)
    {
        // convert gradient colors to IntArgbPre format
        PixelConverter pc = PixelConverter.ArgbPre.instance;
        int pixel1 = pc.rgbToPixel(c1.getRGB(), null);
        int pixel2 = pc.rgbToPixel(c2.getRGB(), null);

        // 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(2*len, 1);
        // now gradient point 2 is at (0.5, 0)
        at.translate(-0.25, 0);
        // now gradient point 1 is at (0.25, 0), point 2 is at (0.75, 0)

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

        // assert rq.lock.isHeldByCurrentThread();
        rq.ensureCapacityAndAlignment(44, 12);
        RenderBuffer buf = rq.getBuffer();
        buf.putInt(SET_GRADIENT_PAINT);
        buf.putInt(useMask ? 1 : 0);
        buf.putInt(isCyclic ? 1 : 0);
        buf.putDouble(p0).putDouble(p1).putDouble(p3);
        buf.putInt(pixel1).putInt(pixel2);
    }

    private static void setGradientPaint(RenderQueue rq,
                                         SunGraphics2D sg2d,
                                         GradientPaint paint,
                                         boolean useMask)
    {
        setGradientPaint(rq, (AffineTransform)sg2d.transform.clone(),
                         paint.getColor1(), paint.getColor2(),
                         paint.getPoint1(), paint.getPoint2(),
                         paint.isCyclic(), useMask);
    }

/************************** TexturePaint support ****************************/

    /**
     * We use OpenGL's texture coordinate generator to automatically
     * map the TexturePaint image to the geometry being rendered.  The
     * generator uses two separate plane equations that take the (x,y)
     * location (in device space) of the fragment being rendered to
     * calculate (u,v) texture coordinates for that fragment:
     *     u = Ax + By + Cz + Dw
     *     v = Ex + Fy + Gz + Hw
     *
     * Since we use a 2D orthographic projection, we can assume that z=0
     * and w=1 for any fragment.  So we need to calculate appropriate
     * values for the plane equation constants (A,B,D) and (E,F,H) such
     * that {u,v}=0 for the top-left of the TexturePaint's anchor
     * rectangle and {u,v}=1 for the bottom-right of the anchor rectangle.
     * We can easily make the texture image repeat for {u,v} values
     * outside the range [0,1] by specifying the GL_REPEAT texture wrap
     * mode.
     *
     * Calculating the plane equation constants is surprisingly simple.
     * We can think of it as an inverse matrix operation that takes
     * device space coordinates and transforms them into user space
     * coordinates that correspond to a location relative to the anchor
     * rectangle.  First, we translate and scale the current user space
     * transform by applying the anchor rectangle bounds.  We then take
     * the inverse of this affine transform.  The rows of the resulting
     * inverse matrix correlate nicely to the plane equation constants
     * we were seeking.
     */
    private static void setTexturePaint(RenderQueue rq,
                                        SunGraphics2D sg2d,
                                        TexturePaint paint,
                                        boolean useMask)
    {
        BufferedImage bi = paint.getImage();
        SurfaceData dstData = sg2d.surfaceData;
        SurfaceData srcData =
            dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
                                         CompositeType.SrcOver, null);
        boolean filter =
            (sg2d.interpolationType !=
             AffineTransformOp.TYPE_NEAREST_NEIGHBOR);

        // calculate plane equation constants
        AffineTransform at = (AffineTransform)sg2d.transform.clone();
        Rectangle2D anchor = paint.getAnchorRect();
        at.translate(anchor.getX(), anchor.getY());
        at.scale(anchor.getWidth(), anchor.getHeight());

        double xp0, xp1, xp3, yp0, yp1, yp3;
        try {
            at.invert();
            xp0 = at.getScaleX();
            xp1 = at.getShearX();
            xp3 = at.getTranslateX();
            yp0 = at.getShearY();
            yp1 = at.getScaleY();
            yp3 = at.getTranslateY();
        } catch (java.awt.geom.NoninvertibleTransformException e) {
            xp0 = xp1 = xp3 = yp0 = yp1 = yp3 = 0.0;
        }

        // assert rq.lock.isHeldByCurrentThread();
        rq.ensureCapacityAndAlignment(68, 12);
        RenderBuffer buf = rq.getBuffer();
        buf.putInt(SET_TEXTURE_PAINT);
        buf.putInt(useMask ? 1 : 0);
        buf.putInt(filter ? 1 : 0);
        buf.putLong(srcData.getNativeOps());
        buf.putDouble(xp0).putDouble(xp1).putDouble(xp3);
        buf.putDouble(yp0).putDouble(yp1).putDouble(yp3);
    }

/****************** Shared MultipleGradientPaint support ********************/

    /**
     * The maximum number of gradient "stops" supported by our native
     * fragment shader implementations.
     *
     * This value has been empirically determined and capped to allow
     * our native shaders to run on all shader-level graphics hardware,
     * even on the older, more limited GPUs.  Even the oldest Nvidia
     * hardware could handle 16, or even 32 fractions without any problem.
     * But the first-generation boards from ATI would fall back into
     * software mode (which is unusably slow) for values larger than 12;
     * it appears that those boards do not have enough native registers
     * to support the number of array accesses required by our gradient
     * shaders.  So for now we will cap this value at 12, but we can
     * re-evaluate this in the future as hardware becomes more capable.
     */
    public static final int MULTI_MAX_FRACTIONS = 12;

    /**
     * Helper function to convert a color component in sRGB space to
     * linear RGB space.  Copied directly from the
     * MultipleGradientPaintContext class.
     */
    private static int convertSRGBtoLinearRGB(int color) {
        float input, output;

        input = color / 255.0f;
        if (input <= 0.04045f) {
            output = input / 12.92f;
        } else {
            output = (float)Math.pow((input + 0.055) / 1.055, 2.4);
        }

        return Math.round(output * 255.0f);
    }

    /**
     * Helper function to convert a (non-premultiplied) Color in sRGB
     * space to an IntArgbPre pixel value, optionally in linear RGB space.
     * Based on the PixelConverter.ArgbPre.rgbToPixel() method.
     */
    private static int colorToIntArgbPrePixel(Color c, boolean linear) {
        int rgb = c.getRGB();
        if (!linear && ((rgb >> 24) == -1)) {
            return rgb;
        }
        int a = rgb >>> 24;
        int r = (rgb >> 16) & 0xff;
        int g = (rgb >>  8) & 0xff;
        int b = (rgb      ) & 0xff;
        if (linear) {
            r = convertSRGBtoLinearRGB(r);
            g = convertSRGBtoLinearRGB(g);
            b = convertSRGBtoLinearRGB(b);
        }
        int a2 = a + (a >> 7);
        r = (r * a2) >> 8;
        g = (g * a2) >> 8;
        b = (b * a2) >> 8;
        return ((a << 24) | (r << 16) | (g << 8) | (b));
    }

    /**
     * Converts the given array of Color objects into an int array
     * containing IntArgbPre pixel values.  If the linear parameter
     * is true, the Color values will be converted into a linear RGB
     * color space before being returned.
     */
    private static int[] convertToIntArgbPrePixels(Color[] colors,
                                                   boolean linear)
    {
        int[] pixels = new int[colors.length];
        for (int i = 0; i < colors.length; i++) {
            pixels[i] = colorToIntArgbPrePixel(colors[i], linear);
        }
        return pixels;
    }

/********************** LinearGradientPaint support *************************/

    /**
     * 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);
    }

/********************** RadialGradientPaint support *************************/

    /**
     * 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);
    }
}
