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;
21b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craikimport android.annotation.ColorInt;
22af046ab637715e420f714ab48ca4788056311609Chris Craik
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RadialGradient extends Shader {
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private static final int TYPE_COLORS_AND_POSITIONS = 1;
26e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private static final int TYPE_COLOR_CENTER_AND_COLOR_EDGE = 2;
27e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
28e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
29e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * Type of the RadialGradient: can be either TYPE_COLORS_AND_POSITIONS or
30e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * TYPE_COLOR_CENTER_AND_COLOR_EDGE.
31e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
32e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private int mType;
33e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
34e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float mX;
35e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float mY;
36e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float mRadius;
37e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private int[] mColors;
38e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private float[] mPositions;
39af046ab637715e420f714ab48ca4788056311609Chris Craik    private int mCenterColor;
40af046ab637715e420f714ab48ca4788056311609Chris Craik    private int mEdgeColor;
41e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
42e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private TileMode mTileMode;
43e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
44b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik    /**
45b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * Create a shader that draws a radial gradient given the center and radius.
46b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     *
47b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param centerX  The x-coordinate of the center of the radius
48b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param centerY  The y-coordinate of the center of the radius
49b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param radius   Must be positive. The radius of the circle for this gradient.
50b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param colors   The colors to be distributed between the center and edge of the circle
51b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
52b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     *                 <code>1.0f</code>. The relative position of each corresponding color in
53b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     *                 the colors array. If <code>null</code>, colors are distributed evenly
54b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     *                 between the center and edge of the circle.
55b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param tileMode The Shader tiling mode
56b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     */
57af046ab637715e420f714ab48ca4788056311609Chris Craik    public RadialGradient(float centerX, float centerY, float radius,
58b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik            @NonNull @ColorInt int colors[], @Nullable float stops[],
59b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik            @NonNull TileMode tileMode) {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (radius <= 0) {
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("radius must be > 0");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (colors.length < 2) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("needs >= 2 number of colors");
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
66af046ab637715e420f714ab48ca4788056311609Chris Craik        if (stops != null && colors.length != stops.length) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("color and position arrays must be of equal length");
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
69e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mType = TYPE_COLORS_AND_POSITIONS;
70af046ab637715e420f714ab48ca4788056311609Chris Craik        mX = centerX;
71af046ab637715e420f714ab48ca4788056311609Chris Craik        mY = centerY;
72e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mRadius = radius;
73b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik        mColors = colors.clone();
74b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik        mPositions = stops != null ? stops.clone() : null;
75af046ab637715e420f714ab48ca4788056311609Chris Craik        mTileMode = tileMode;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
78b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik    /**
798a6ad4a89d1b9ed61d3ec6f5bc12d479bc8d9f3bChris Craik     * Create a shader that draws a radial gradient given the center and radius.
80b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     *
81b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param centerX     The x-coordinate of the center of the radius
82b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param centerY     The y-coordinate of the center of the radius
83b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param radius      Must be positive. The radius of the circle for this gradient
84b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param centerColor The color at the center of the circle.
85b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param edgeColor   The color at the edge of the circle.
86b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     * @param tileMode    The Shader tiling mode
87b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik     */
888a6ad4a89d1b9ed61d3ec6f5bc12d479bc8d9f3bChris Craik    public RadialGradient(float centerX, float centerY, float radius,
89b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik            @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode) {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (radius <= 0) {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("radius must be > 0");
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
93e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mType = TYPE_COLOR_CENTER_AND_COLOR_EDGE;
94af046ab637715e420f714ab48ca4788056311609Chris Craik        mX = centerX;
95af046ab637715e420f714ab48ca4788056311609Chris Craik        mY = centerY;
96e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mRadius = radius;
97af046ab637715e420f714ab48ca4788056311609Chris Craik        mCenterColor = centerColor;
98af046ab637715e420f714ab48ca4788056311609Chris Craik        mEdgeColor = edgeColor;
99af046ab637715e420f714ab48ca4788056311609Chris Craik        mTileMode = tileMode;
100b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik    }
101b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik
102b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik    @Override
103b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik    long createNativeInstance(long nativeMatrix) {
104b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik        if (mType == TYPE_COLORS_AND_POSITIONS) {
105b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik            return nativeCreate1(nativeMatrix, mX, mY, mRadius,
106b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik                    mColors, mPositions, mTileMode.nativeInt);
107b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik        } else { // TYPE_COLOR_CENTER_AND_COLOR_EDGE
108b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik            return nativeCreate2(nativeMatrix, mX, mY, mRadius,
109b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik                    mCenterColor, mEdgeColor, mTileMode.nativeInt);
110b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik        }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
113e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
114e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * @hide
115e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
116e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    @Override
117e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    protected Shader copy() {
118e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        final RadialGradient copy;
119b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik        if (mType == TYPE_COLORS_AND_POSITIONS) {
120b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik            copy = new RadialGradient(mX, mY, mRadius, mColors.clone(),
121b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik                    mPositions != null ? mPositions.clone() : null, mTileMode);
122b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik        } else { // TYPE_COLOR_CENTER_AND_COLOR_EDGE
123b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik            copy = new RadialGradient(mX, mY, mRadius, mCenterColor, mEdgeColor, mTileMode);
124e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        }
125e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        copyLocalMatrix(copy);
126e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        return copy;
127e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    }
128e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
129b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik    private static native long nativeCreate1(long matrix, float x, float y, float radius,
130ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy            int colors[], float positions[], int tileMode);
131b581e6704fc1478bc1dda517502abd3eab2558d6Chris Craik    private static native long nativeCreate2(long matrix, float x, float y, float radius,
132ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy            int color0, int color1, int tileMode);
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
135