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.NonNull;
22 import android.annotation.Nullable;
23 import android.compat.annotation.UnsupportedAppUsage;
24 
25 public class SweepGradient extends Shader {
26     @UnsupportedAppUsage
27     private float mCx;
28     @UnsupportedAppUsage
29     private float mCy;
30     @UnsupportedAppUsage
31     private float[] mPositions;
32 
33     // @ColorInts are replaced by @ColorLongs, but these remain due to @UnsupportedAppUsage.
34     @UnsupportedAppUsage
35     @ColorInt
36     private int[] mColors;
37     @UnsupportedAppUsage
38     @ColorInt
39     private int mColor0;
40     @UnsupportedAppUsage
41     @ColorInt
42     private int mColor1;
43 
44     @ColorLong
45     private final long[] mColorLongs;
46 
47     /**
48      * A Shader that draws a sweep gradient around a center point.
49      *
50      * @param cx       The x-coordinate of the center
51      * @param cy       The y-coordinate of the center
52      * @param colors   The sRGB colors to be distributed between around the center.
53      *                 There must be at least 2 colors in the array.
54      * @param positions May be NULL. The relative position of
55      *                 each corresponding color in the colors array, beginning
56      *                 with 0 and ending with 1.0. If the values are not
57      *                 monotonic, the drawing may produce unexpected results.
58      *                 If positions is NULL, then the colors are automatically
59      *                 spaced evenly.
60      */
SweepGradient(float cx, float cy, @NonNull @ColorInt int[] colors, @Nullable float[] positions)61     public SweepGradient(float cx, float cy, @NonNull @ColorInt int[] colors,
62             @Nullable float[] positions) {
63         this(cx, cy, convertColors(colors), positions, ColorSpace.get(ColorSpace.Named.SRGB));
64     }
65 
66     /**
67      * A Shader that draws a sweep gradient around a center point.
68      *
69      * @param cx       The x-coordinate of the center
70      * @param cy       The y-coordinate of the center
71      * @param colors   The colors to be distributed between around the center.
72      *                 There must be at least 2 colors in the array.
73      * @param positions May be NULL. The relative position of
74      *                 each corresponding color in the colors array, beginning
75      *                 with 0 and ending with 1.0. If the values are not
76      *                 monotonic, the drawing may produce unexpected results.
77      *                 If positions is NULL, then the colors are automatically
78      *                 spaced evenly.
79      * @throws IllegalArgumentException if there are less than two colors, the colors do
80      *      not share the same {@link ColorSpace} or do not use a valid one, or {@code positions}
81      *      is not {@code null} and has a different length from {@code colors}.
82      */
SweepGradient(float cx, float cy, @NonNull @ColorLong long[] colors, @Nullable float[] positions)83     public SweepGradient(float cx, float cy, @NonNull @ColorLong long[] colors,
84             @Nullable float[] positions) {
85         this(cx, cy, colors.clone(), positions, detectColorSpace(colors));
86     }
87 
88     /**
89      * Base constructor. Assumes @param colors is a copy that this object can hold onto,
90      * and all colors share @param colorSpace.
91      */
SweepGradient(float cx, float cy, @NonNull @ColorLong long[] colors, @Nullable float[] positions, ColorSpace colorSpace)92     private SweepGradient(float cx, float cy, @NonNull @ColorLong long[] colors,
93             @Nullable float[] positions, ColorSpace colorSpace) {
94         super(colorSpace);
95 
96         if (positions != null && colors.length != positions.length) {
97             throw new IllegalArgumentException(
98                     "color and position arrays must be of equal length");
99         }
100         mCx = cx;
101         mCy = cy;
102         mColorLongs = colors;
103         mPositions = positions != null ? positions.clone() : null;
104     }
105 
106     /**
107      * A Shader that draws a sweep gradient around a center point.
108      *
109      * @param cx       The x-coordinate of the center
110      * @param cy       The y-coordinate of the center
111      * @param color0   The sRGB color to use at the start of the sweep
112      * @param color1   The sRGB color to use at the end of the sweep
113      */
SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1)114     public SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1) {
115         this(cx, cy, Color.pack(color0), Color.pack(color1));
116     }
117 
118     /**
119      * A Shader that draws a sweep gradient around a center point.
120      *
121      * @param cx       The x-coordinate of the center
122      * @param cy       The y-coordinate of the center
123      * @param color0   The color to use at the start of the sweep
124      * @param color1   The color to use at the end of the sweep
125      *
126      * @throws IllegalArgumentException if the colors do
127      *      not share the same {@link ColorSpace} or do not use a valid one.
128      */
SweepGradient(float cx, float cy, @ColorLong long color0, @ColorLong long color1)129     public SweepGradient(float cx, float cy, @ColorLong long color0, @ColorLong long color1) {
130         this(cx, cy, new long[] {color0, color1}, null);
131     }
132 
133     @Override
createNativeInstance(long nativeMatrix)134     long createNativeInstance(long nativeMatrix) {
135         return nativeCreate(nativeMatrix, mCx, mCy, mColorLongs, mPositions,
136                 colorSpace().getNativeInstance());
137     }
138 
nativeCreate(long matrix, float x, float y, long[] colors, float[] positions, long colorSpaceHandle)139     private static native long nativeCreate(long matrix, float x, float y,
140             long[] colors, float[] positions, long colorSpaceHandle);
141 }
142 
143