Shader.java revision b581e6704fc1478bc1dda517502abd3eab2558d6
1/* 2 * Copyright (C) 2006 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 17package android.graphics; 18 19import android.annotation.NonNull; 20import android.annotation.Nullable; 21 22/** 23 * Shader is the based class for objects that return horizontal spans of colors 24 * during drawing. A subclass of Shader is installed in a Paint calling 25 * paint.setShader(shader). After that any object (other than a bitmap) that is 26 * drawn with that paint will get its color(s) from the shader. 27 */ 28public class Shader { 29 /** 30 * @deprecated Use subclass constructors directly instead. 31 */ 32 @Deprecated 33 public Shader() {} 34 35 /** 36 * Current native shader instance. Created and updated lazily when {@link #getNativeInstance()} 37 * is called - otherwise may be out of date with java setters/properties. 38 */ 39 private long mNativeInstance; 40 41 private Matrix mLocalMatrix; 42 43 public enum TileMode { 44 /** 45 * replicate the edge color if the shader draws outside of its 46 * original bounds 47 */ 48 CLAMP (0), 49 /** 50 * repeat the shader's image horizontally and vertically 51 */ 52 REPEAT (1), 53 /** 54 * repeat the shader's image horizontally and vertically, alternating 55 * mirror images so that adjacent images always seam 56 */ 57 MIRROR (2); 58 59 TileMode(int nativeInt) { 60 this.nativeInt = nativeInt; 61 } 62 final int nativeInt; 63 } 64 65 /** 66 * Return true if the shader has a non-identity local matrix. 67 * @param localM Set to the local matrix of the shader, if the shader's matrix is non-null. 68 * @return true if the shader has a non-identity local matrix 69 */ 70 public boolean getLocalMatrix(@NonNull Matrix localM) { 71 if (mLocalMatrix != null) { 72 localM.set(mLocalMatrix); 73 return true; 74 } 75 return false; 76 } 77 78 /** 79 * Set the shader's local matrix. Passing null will reset the shader's 80 * matrix to identity. 81 * 82 * @param localM The shader's new local matrix, or null to specify identity 83 */ 84 public void setLocalMatrix(@Nullable Matrix localM) { 85 if (localM == null || localM.isIdentity()) { 86 if (mLocalMatrix != null) { 87 mLocalMatrix = null; 88 discardNativeInstance(); 89 } 90 } else { 91 if (mLocalMatrix == null) { 92 mLocalMatrix = new Matrix(localM); 93 discardNativeInstance(); 94 } else if (!mLocalMatrix.equals(localM)) { 95 mLocalMatrix.set(localM); 96 discardNativeInstance(); 97 } 98 } 99 } 100 101 long createNativeInstance(long nativeMatrix) { 102 return 0; 103 } 104 105 void discardNativeInstance() { 106 nativeSafeUnref(mNativeInstance); 107 mNativeInstance = 0; 108 } 109 110 /** 111 * Callback for subclasses to call {@link #discardNativeInstance()} if the most recently 112 * constructed native instance is no longer valid. 113 */ 114 void verifyNativeInstance() { 115 } 116 117 @Override 118 protected void finalize() throws Throwable { 119 try { 120 nativeSafeUnref(mNativeInstance); 121 mNativeInstance = -1; 122 } finally { 123 super.finalize(); 124 } 125 } 126 127 /** 128 * @hide 129 */ 130 protected Shader copy() { 131 final Shader copy = new Shader(); 132 copyLocalMatrix(copy); 133 return copy; 134 } 135 136 /** 137 * @hide 138 */ 139 protected void copyLocalMatrix(Shader dest) { 140 dest.mLocalMatrix.set(mLocalMatrix); 141 } 142 143 /** 144 * @hide 145 */ 146 public long getNativeInstance() { 147 if (mNativeInstance == -1) { 148 throw new IllegalStateException("attempting to use a finalized Shader"); 149 } 150 151 // verify mNativeInstance is valid 152 verifyNativeInstance(); 153 154 if (mNativeInstance == 0) { 155 mNativeInstance = createNativeInstance(mLocalMatrix == null 156 ? 0 : mLocalMatrix.native_instance); 157 } 158 return mNativeInstance; 159 } 160 161 private static native void nativeSafeUnref(long nativeInstance); 162} 163