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