19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19af046ab637715e420f714ab48ca4788056311609Chris Craikimport android.annotation.NonNull;
20af046ab637715e420f714ab48ca4788056311609Chris Craikimport android.annotation.Nullable;
21af046ab637715e420f714ab48ca4788056311609Chris Craik
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RadialGradient extends Shader {
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private static final int TYPE_COLORS_AND_POSITIONS = 1;
25e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private static final int TYPE_COLOR_CENTER_AND_COLOR_EDGE = 2;
26e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
27e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
28e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * Type of the RadialGradient: can be either TYPE_COLORS_AND_POSITIONS or
29e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * TYPE_COLOR_CENTER_AND_COLOR_EDGE.
30e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
31e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private int mType;
32e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
33e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float mX;
34e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float mY;
35e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float mRadius;
36e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private int[] mColors;
37e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float[] mPositions;
38af046ab637715e420f714ab48ca4788056311609Chris Craik    private int mCenterColor;
39af046ab637715e420f714ab48ca4788056311609Chris Craik    private int mEdgeColor;
40e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
41e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private TileMode mTileMode;
42e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
438a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock    /** Create a shader that draws a radial gradient given the center and radius.
44af046ab637715e420f714ab48ca4788056311609Chris Craik        @param centerX  The x-coordinate of the center of the radius
45af046ab637715e420f714ab48ca4788056311609Chris Craik        @param centerY  The y-coordinate of the center of the radius
46af046ab637715e420f714ab48ca4788056311609Chris Craik        @param radius   Must be positive. The radius of the circle for this gradient.
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @param colors   The colors to be distributed between the center and edge of the circle
48af046ab637715e420f714ab48ca4788056311609Chris Craik        @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
49af046ab637715e420f714ab48ca4788056311609Chris Craik                        <code>1.0f</code>. The relative position of each corresponding color in
50af046ab637715e420f714ab48ca4788056311609Chris Craik                        the colors array. If <code>null</code>, colors are distributed evenly
51af046ab637715e420f714ab48ca4788056311609Chris Craik                        between the center and edge of the circle.
52af046ab637715e420f714ab48ca4788056311609Chris Craik        @param tileMode The Shader tiling mode
538a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock    */
54af046ab637715e420f714ab48ca4788056311609Chris Craik    public RadialGradient(float centerX, float centerY, float radius,
55af046ab637715e420f714ab48ca4788056311609Chris Craik               @NonNull int colors[], @Nullable float stops[], @NonNull TileMode tileMode) {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (radius <= 0) {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("radius must be > 0");
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (colors.length < 2) {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("needs >= 2 number of colors");
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
62af046ab637715e420f714ab48ca4788056311609Chris Craik        if (stops != null && colors.length != stops.length) {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("color and position arrays must be of equal length");
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
65e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mType = TYPE_COLORS_AND_POSITIONS;
66af046ab637715e420f714ab48ca4788056311609Chris Craik        mX = centerX;
67af046ab637715e420f714ab48ca4788056311609Chris Craik        mY = centerY;
68e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mRadius = radius;
69e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mColors = colors;
70af046ab637715e420f714ab48ca4788056311609Chris Craik        mPositions = stops;
71af046ab637715e420f714ab48ca4788056311609Chris Craik        mTileMode = tileMode;
72af046ab637715e420f714ab48ca4788056311609Chris Craik        init(nativeCreate1(centerX, centerY, radius, colors, stops, tileMode.nativeInt));
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
758a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock    /** Create a shader that draws a radial gradient given the center and radius.
76af046ab637715e420f714ab48ca4788056311609Chris Craik        @param centerX     The x-coordinate of the center of the radius
77af046ab637715e420f714ab48ca4788056311609Chris Craik        @param centerY     The y-coordinate of the center of the radius
78af046ab637715e420f714ab48ca4788056311609Chris Craik        @param radius      Must be positive. The radius of the circle for this gradient
79af046ab637715e420f714ab48ca4788056311609Chris Craik        @param centerColor The color at the center of the circle.
80af046ab637715e420f714ab48ca4788056311609Chris Craik        @param edgeColor   The color at the edge of the circle.
81af046ab637715e420f714ab48ca4788056311609Chris Craik        @param tileMode    The Shader tiling mode
828a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock    */
83af046ab637715e420f714ab48ca4788056311609Chris Craik    public RadialGradient(float centerX, float centerY, float radius,
84af046ab637715e420f714ab48ca4788056311609Chris Craik            int centerColor, int edgeColor, @NonNull TileMode tileMode) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (radius <= 0) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("radius must be > 0");
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
88e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mType = TYPE_COLOR_CENTER_AND_COLOR_EDGE;
89af046ab637715e420f714ab48ca4788056311609Chris Craik        mX = centerX;
90af046ab637715e420f714ab48ca4788056311609Chris Craik        mY = centerY;
91e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mRadius = radius;
92af046ab637715e420f714ab48ca4788056311609Chris Craik        mCenterColor = centerColor;
93af046ab637715e420f714ab48ca4788056311609Chris Craik        mEdgeColor = edgeColor;
94af046ab637715e420f714ab48ca4788056311609Chris Craik        mTileMode = tileMode;
95af046ab637715e420f714ab48ca4788056311609Chris Craik        init(nativeCreate2(centerX, centerY, radius, centerColor, edgeColor, tileMode.nativeInt));
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
98e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
99e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * @hide
100e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
101e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    @Override
102e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    protected Shader copy() {
103e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        final RadialGradient copy;
104e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        switch (mType) {
105e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            case TYPE_COLORS_AND_POSITIONS:
1069622adf6e8028aebd57213371c4f2c6c26fc63e5Romain Guy                copy = new RadialGradient(mX, mY, mRadius, mColors.clone(),
1079622adf6e8028aebd57213371c4f2c6c26fc63e5Romain Guy                        mPositions != null ? mPositions.clone() : null, mTileMode);
108e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                break;
109e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            case TYPE_COLOR_CENTER_AND_COLOR_EDGE:
110af046ab637715e420f714ab48ca4788056311609Chris Craik                copy = new RadialGradient(mX, mY, mRadius, mCenterColor, mEdgeColor, mTileMode);
111e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                break;
112e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            default:
113e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                throw new IllegalArgumentException("RadialGradient should be created with either " +
114e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                        "colors and positions or center color and edge color");
115e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        }
116e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        copyLocalMatrix(copy);
117e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        return copy;
118e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    }
119e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
12036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreate1(float x, float y, float radius,
121ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy            int colors[], float positions[], int tileMode);
1228a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock    private static native long nativeCreate2(float x, float y, float radius,
123ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy            int color0, int color1, int tileMode);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
126