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 
26 public class LinearGradient extends Shader {
27     @UnsupportedAppUsage
28     private float mX0;
29     @UnsupportedAppUsage
30     private float mY0;
31     @UnsupportedAppUsage
32     private float mX1;
33     @UnsupportedAppUsage
34     private float mY1;
35     @UnsupportedAppUsage
36     private float[] mPositions;
37     @UnsupportedAppUsage
38     private TileMode mTileMode;
39 
40     // @ColorInts are replaced by @ColorLongs, but these remain due to @UnsupportedAppUsage.
41     @UnsupportedAppUsage
42     @ColorInt
43     private int[] mColors;
44     @UnsupportedAppUsage
45     @ColorInt
46     private int mColor0;
47     @UnsupportedAppUsage
48     @ColorInt
49     private int mColor1;
50 
51     @ColorLong
52     private final long[] mColorLongs;
53 
54 
55     /**
56      * Create a shader that draws a linear gradient along a line.
57      *
58      * @param x0           The x-coordinate for the start of the gradient line
59      * @param y0           The y-coordinate for the start of the gradient line
60      * @param x1           The x-coordinate for the end of the gradient line
61      * @param y1           The y-coordinate for the end of the gradient line
62      * @param colors       The sRGB colors to be distributed along the gradient line
63      * @param positions    May be null. The relative positions [0..1] of
64      *                     each corresponding color in the colors array. If this is null,
65      *                     the the colors are distributed evenly along the gradient line.
66      * @param tile         The Shader tiling mode
67      */
LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors, @Nullable float[] positions, @NonNull TileMode tile)68     public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors,
69             @Nullable float[] positions, @NonNull TileMode tile) {
70         this(x0, y0, x1, y1, convertColors(colors), positions, tile,
71                 ColorSpace.get(ColorSpace.Named.SRGB));
72     }
73 
74     /**
75      * Create a shader that draws a linear gradient along a line.
76      *
77      * @param x0           The x-coordinate for the start of the gradient line
78      * @param y0           The y-coordinate for the start of the gradient line
79      * @param x1           The x-coordinate for the end of the gradient line
80      * @param y1           The y-coordinate for the end of the gradient line
81      * @param colors       The colors to be distributed along the gradient line
82      * @param positions    May be null. The relative positions [0..1] of
83      *                     each corresponding color in the colors array. If this is null,
84      *                     the the colors are distributed evenly along the gradient line.
85      * @param tile         The Shader tiling mode
86      *
87      * @throws IllegalArgumentException if there are less than two colors, the colors do
88      *      not share the same {@link ColorSpace} or do not use a valid one, or {@code positions}
89      *      is not {@code null} and has a different length from {@code colors}.
90      */
LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorLong long[] colors, @Nullable float[] positions, @NonNull TileMode tile)91     public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorLong long[] colors,
92             @Nullable float[] positions, @NonNull TileMode tile) {
93         this(x0, y0, x1, y1, colors.clone(), positions, tile, detectColorSpace(colors));
94     }
95 
96     /**
97      * Base constructor. Assumes @param colors is a copy that this object can hold onto,
98      * and all colors share @param colorSpace.
99      */
LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorLong long[] colors, @Nullable float[] positions, @NonNull TileMode tile, @NonNull ColorSpace colorSpace)100     private LinearGradient(float x0, float y0, float x1, float y1,
101             @NonNull @ColorLong long[] colors, @Nullable float[] positions, @NonNull TileMode tile,
102             @NonNull ColorSpace colorSpace) {
103         super(colorSpace);
104 
105         if (positions != null && colors.length != positions.length) {
106             throw new IllegalArgumentException("color and position arrays must be of equal length");
107         }
108         mX0 = x0;
109         mY0 = y0;
110         mX1 = x1;
111         mY1 = y1;
112         mColorLongs = colors;
113         mPositions = positions != null ? positions.clone() : null;
114         mTileMode = tile;
115     }
116 
117     /**
118      * Create a shader that draws a linear gradient along a line.
119      *
120      * @param x0       The x-coordinate for the start of the gradient line
121      * @param y0       The y-coordinate for the start of the gradient line
122      * @param x1       The x-coordinate for the end of the gradient line
123      * @param y1       The y-coordinate for the end of the gradient line
124      * @param color0   The sRGB color at the start of the gradient line.
125      * @param color1   The sRGB color at the end of the gradient line.
126      * @param tile     The Shader tiling mode
127      */
LinearGradient(float x0, float y0, float x1, float y1, @ColorInt int color0, @ColorInt int color1, @NonNull TileMode tile)128     public LinearGradient(float x0, float y0, float x1, float y1,
129             @ColorInt int color0, @ColorInt int color1,
130             @NonNull TileMode tile) {
131         this(x0, y0, x1, y1, Color.pack(color0), Color.pack(color1), tile);
132     }
133 
134     /**
135      * Create a shader that draws a linear gradient along a line.
136      *
137      * @param x0       The x-coordinate for the start of the gradient line
138      * @param y0       The y-coordinate for the start of the gradient line
139      * @param x1       The x-coordinate for the end of the gradient line
140      * @param y1       The y-coordinate for the end of the gradient line
141      * @param color0   The color at the start of the gradient line.
142      * @param color1   The color at the end of the gradient line.
143      * @param tile     The Shader tiling mode
144      *
145      * @throws IllegalArgumentException if the colors do
146      *      not share the same {@link ColorSpace} or do not use a valid one.
147      */
LinearGradient(float x0, float y0, float x1, float y1, @ColorLong long color0, @ColorLong long color1, @NonNull TileMode tile)148     public LinearGradient(float x0, float y0, float x1, float y1,
149             @ColorLong long color0, @ColorLong long color1,
150             @NonNull TileMode tile) {
151         this(x0, y0, x1, y1, new long[] {color0, color1}, null, tile);
152     }
153 
154     @Override
createNativeInstance(long nativeMatrix)155     long createNativeInstance(long nativeMatrix) {
156         return nativeCreate(nativeMatrix, mX0, mY0, mX1, mY1,
157                 mColorLongs, mPositions, mTileMode.nativeInt,
158                 colorSpace().getNativeInstance());
159     }
160 
nativeCreate(long matrix, float x0, float y0, float x1, float y1, long[] colors, float[] positions, int tileMode, long colorSpaceHandle)161     private native long nativeCreate(long matrix, float x0, float y0, float x1, float y1,
162             long[] colors, float[] positions, int tileMode, long colorSpaceHandle);
163 }
164