• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.graphics;
18 
19 import android.annotation.ColorInt;
20 import android.annotation.ColorLong;
21 import android.annotation.FloatRange;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.compat.annotation.UnsupportedAppUsage;
25 import android.os.Build;
26 
27 @android.ravenwood.annotation.RavenwoodKeepWholeClass
28 public class RadialGradient extends Shader {
29     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
30     private float mX;
31     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
32     private float mY;
33     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
34     private float mRadius;
35     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
36     private float[] mPositions;
37     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
38     private TileMode mTileMode;
39 
40     private final float mFocalX;
41     private final float mFocalY;
42     private final float mFocalRadius;
43 
44     // @ColorInts are replaced by @ColorLongs, but these remain due to @UnsupportedAppUsage.
45     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
46     @ColorInt
47     private int[] mColors;
48     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
49     @ColorInt
50     private int mCenterColor;
51     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
52     @ColorInt
53     private int mEdgeColor;
54 
55     @ColorLong
56     private final long[] mColorLongs;
57 
58     /**
59      * Create a shader that draws a radial gradient given the center and radius.
60      *
61      * @param centerX  The x-coordinate of the center of the radius
62      * @param centerY  The y-coordinate of the center of the radius
63      * @param radius   Must be positive. The radius of the circle for this gradient.
64      * @param colors   The sRGB colors to be distributed between the center and edge of the circle
65      * @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
66      *                 <code>1.0f</code>. The relative position of each corresponding color in
67      *                 the colors array. If <code>null</code>, colors are distributed evenly
68      *                 between the center and edge of the circle.
69      * @param tileMode The Shader tiling mode
70      */
RadialGradient(float centerX, float centerY, float radius, @NonNull @ColorInt int[] colors, @Nullable float[] stops, @NonNull TileMode tileMode)71     public RadialGradient(float centerX, float centerY, float radius,
72             @NonNull @ColorInt int[] colors, @Nullable float[] stops,
73             @NonNull TileMode tileMode) {
74         this(centerX, centerY, 0f, centerX, centerY, radius, convertColors(colors),
75                 stops, tileMode, ColorSpace.get(ColorSpace.Named.SRGB));
76     }
77 
78     /**
79      * Create a shader that draws a radial gradient given the center and radius.
80      *
81      * @param centerX  The x-coordinate of the center of the radius
82      * @param centerY  The y-coordinate of the center of the radius
83      * @param radius   Must be positive. The radius of the circle for this gradient.
84      * @param colors   The colors to be distributed between the center and edge of the circle
85      * @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
86      *                 <code>1.0f</code>. The relative position of each corresponding color in
87      *                 the colors array. If <code>null</code>, colors are distributed evenly
88      *                 between the center and edge of the circle.
89      * @param tileMode The Shader tiling mode
90      *
91      * @throws IllegalArgumentException if there are less than two colors, the colors do
92      *      not share the same {@link ColorSpace} or do not use a valid one, or {@code stops}
93      *      is not {@code null} and has a different length from {@code colors}.
94      */
RadialGradient(float centerX, float centerY, float radius, @NonNull @ColorLong long[] colors, @Nullable float[] stops, @NonNull TileMode tileMode)95     public RadialGradient(float centerX, float centerY, float radius,
96             @NonNull @ColorLong long[] colors, @Nullable float[] stops,
97             @NonNull TileMode tileMode) {
98         this(centerX, centerY, 0f, centerX, centerY, radius, colors.clone(), stops,
99                 tileMode, detectColorSpace(colors));
100     }
101 
102     /**
103      * Create a shader that draws a radial gradient given the start and end points as well as
104      * starting and ending radii. The starting point is often referred to as the focal center and
105      * represents the starting circle of the radial gradient.
106      *
107      * @param startX   The x-coordinate of the center of the starting circle of the radial gradient,
108      *                often referred to as the focal point.
109      * @param startY   The y-coordinate of the center of the starting circle of the radial gradient,
110      *                 often referred to as the focal point.
111      * @param startRadius The radius of the starting circle of the radial gradient, often referred
112      *                    to as the focal radius. Must be greater than or equal to zero.
113      * @param endX  The x-coordinate of the center of the radius for the end circle of the
114      *                 radial gradient
115      * @param endY  The y-coordinate of the center of the radius for the end circle of the
116      *                 radial gradient
117      * @param endRadius   The radius of the ending circle for this gradient. This must be strictly
118      *                    greater than zero. A radius value equal to zero is not allowed.
119      * @param colors   The colors to be distributed between the center and edge of the circle
120      * @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
121      *                 <code>1.0f</code>. The relative position of each corresponding color in
122      *                 the colors array. If <code>null</code>, colors are distributed evenly
123      *                 between the center and edge of the circle.
124      * @param tileMode The Shader tiling mode
125      *
126      * @throws IllegalArgumentException In one of the following circumstances:
127      *      <ul>
128      *          <li>There are less than two colors</li>
129      *          <li>The colors do not share the same {@link ColorSpace}</li>
130      *          <li>The colors do not use a valid {@link ColorSpace}</li>
131      *          <li>
132      *              The {@code stops} parameter is not {@code null} and has a different length from
133      *              {@code colors}.
134      *          </li>
135      *          <li>The {@code startRadius} is negative</li>
136      *          <li>The {@code endRadius} is less than or equal to zero</li>
137      *       </ul>
138      */
RadialGradient(float startX, float startY, @FloatRange(from = 0.0f) float startRadius, float endX, float endY, @FloatRange(from = 0.0f, fromInclusive = false) float endRadius, @NonNull @ColorLong long[] colors, @Nullable float[] stops, @NonNull TileMode tileMode)139     public RadialGradient(float startX, float startY, @FloatRange(from = 0.0f) float startRadius,
140             float endX, float endY, @FloatRange(from = 0.0f, fromInclusive = false) float endRadius,
141             @NonNull @ColorLong long[] colors, @Nullable float[] stops,
142             @NonNull TileMode tileMode) {
143         this(startX, startY, startRadius, endX, endY, endRadius, colors.clone(), stops, tileMode,
144                 detectColorSpace(colors));
145     }
146 
147     /**
148      * Base constructor. Assumes @param colors is a copy that this object can hold onto,
149      * and all colors share @param colorSpace.
150      */
RadialGradient(float startX, float startY, float startRadius, float endX, float endY, float endRadius, @NonNull @ColorLong long[] colors, @Nullable float[] stops, @NonNull TileMode tileMode, ColorSpace colorSpace )151     private RadialGradient(float startX, float startY, float startRadius, float endX, float endY,
152             float endRadius, @NonNull @ColorLong long[] colors, @Nullable float[] stops,
153             @NonNull TileMode tileMode, ColorSpace colorSpace
154     ) {
155         super(colorSpace);
156         // A focal or starting radius of zero with a focal point that matches the center is
157         // identical to a regular radial gradient
158         if (startRadius < 0) {
159             throw new IllegalArgumentException("starting/focal radius must be >= 0");
160         }
161 
162         if (endRadius <= 0) {
163             throw new IllegalArgumentException("ending radius must be > 0");
164         }
165 
166         if (stops != null && colors.length != stops.length) {
167             throw new IllegalArgumentException("color and position arrays must be of equal length");
168         }
169         mX = endX;
170         mY = endY;
171         mRadius = endRadius;
172         mFocalX = startX;
173         mFocalY = startY;
174         mFocalRadius = startRadius;
175         mColorLongs = colors;
176         mPositions = stops != null ? stops.clone() : null;
177         mTileMode = tileMode;
178     }
179 
180     /**
181      * Create a shader that draws a radial gradient given the center and radius.
182      *
183      * @param centerX     The x-coordinate of the center of the radius
184      * @param centerY     The y-coordinate of the center of the radius
185      * @param radius      Must be positive. The radius of the circle for this gradient
186      * @param centerColor The sRGB color at the center of the circle.
187      * @param edgeColor   The sRGB color at the edge of the circle.
188      * @param tileMode    The Shader tiling mode
189      */
RadialGradient(float centerX, float centerY, float radius, @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode)190     public RadialGradient(float centerX, float centerY, float radius,
191             @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode) {
192         this(centerX, centerY, radius, Color.pack(centerColor), Color.pack(edgeColor), tileMode);
193     }
194 
195     /**
196      * Create a shader that draws a radial gradient given the center and radius.
197      *
198      * @param centerX     The x-coordinate of the center of the radius
199      * @param centerY     The y-coordinate of the center of the radius
200      * @param radius      Must be positive. The radius of the circle for this gradient
201      * @param centerColor The color at the center of the circle.
202      * @param edgeColor   The color at the edge of the circle.
203      * @param tileMode    The Shader tiling mode
204      *
205      * @throws IllegalArgumentException if the colors do
206      *      not share the same {@link ColorSpace} or do not use a valid one.
207      */
RadialGradient(float centerX, float centerY, float radius, @ColorLong long centerColor, @ColorLong long edgeColor, @NonNull TileMode tileMode)208     public RadialGradient(float centerX, float centerY, float radius,
209             @ColorLong long centerColor, @ColorLong long edgeColor, @NonNull TileMode tileMode) {
210         this(centerX, centerY, radius, new long[] {centerColor, edgeColor}, null, tileMode);
211     }
212 
213     /** @hide */
214     @Override
createNativeInstance(long nativeMatrix, boolean filterFromPaint)215     protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) {
216         return nativeCreate(nativeMatrix, mFocalX, mFocalY, mFocalRadius, mX, mY, mRadius,
217                 mColorLongs, mPositions, mTileMode.nativeInt, colorSpace().getNativeInstance());
218     }
219 
nativeCreate(long matrix, float startX, float startY, float startRadius, float endX, float endY, float endRadius, @ColorLong long[] colors, float[] positions, int tileMode, long colorSpaceHandle)220     private static native long nativeCreate(long matrix, float startX, float startY,
221             float startRadius, float endX, float endY, float endRadius, @ColorLong long[] colors,
222             float[] positions, int tileMode, long colorSpaceHandle);
223 }
224 
225