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