19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shader is the based class for objects that return horizontal spans of colors
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * during drawing. A subclass of Shader is installed in a Paint calling
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * paint.setShader(shader). After that any object (other than a bitmap) that is
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * drawn with that paint will get its color(s) from the shader.
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Shader {
26d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    /**
27d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     * This is set by subclasses, but don't make it public.
28d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     */
29866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III    private long native_instance;
30866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III
31866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III    /**
32866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III     * Initialization step that should be called by subclasses in their
33866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III     * constructors. Calling again may result in memory leaks.
34866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III     * @hide
35866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III     */
36866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III    protected void init(long ni) {
37866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III        native_instance = ni;
38866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III    }
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40a9ebfa6bcce62d7fee69693fe3dee6027afd3f0eRomain Guy    private Matrix mLocalMatrix;
41a9ebfa6bcce62d7fee69693fe3dee6027afd3f0eRomain Guy
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum TileMode {
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * replicate the edge color if the shader draws outside of its
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * original bounds
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CLAMP   (0),
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * repeat the shader's image horizontally and vertically
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        REPEAT  (1),
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * repeat the shader's image horizontally and vertically, alternating
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * mirror images so that adjacent images always seam
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MIRROR  (2);
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TileMode(int nativeInt) {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.nativeInt = nativeInt;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int nativeInt;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return true if the shader has a non-identity local matrix.
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param localM If not null, it is set to the shader's local matrix.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the shader has a non-identity local matrix
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getLocalMatrix(Matrix localM) {
70a9ebfa6bcce62d7fee69693fe3dee6027afd3f0eRomain Guy        if (mLocalMatrix != null) {
71a9ebfa6bcce62d7fee69693fe3dee6027afd3f0eRomain Guy            localM.set(mLocalMatrix);
729454fe1080458812db76599dd02a8b91a2e1e8f4Romain Guy            return !mLocalMatrix.isIdentity();
73a9ebfa6bcce62d7fee69693fe3dee6027afd3f0eRomain Guy        }
74a9ebfa6bcce62d7fee69693fe3dee6027afd3f0eRomain Guy        return false;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the shader's local matrix. Passing null will reset the shader's
79ab87983a11e0bd2e08d752d86d5e945ea7d39a04Leon Scroggins III     * matrix to identity.
80ab87983a11e0bd2e08d752d86d5e945ea7d39a04Leon Scroggins III     *
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param localM The shader's new local matrix, or null to specify identity
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLocalMatrix(Matrix localM) {
84a9ebfa6bcce62d7fee69693fe3dee6027afd3f0eRomain Guy        mLocalMatrix = localM;
85dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_instance = nativeSetLocalMatrix(native_instance,
86dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                localM == null ? 0 : localM.native_instance);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
90f9764a4f532561f6e2e985ff3b25112f1132ce44Romain Guy        try {
91f9764a4f532561f6e2e985ff3b25112f1132ce44Romain Guy            super.finalize();
92f9764a4f532561f6e2e985ff3b25112f1132ce44Romain Guy        } finally {
9301edef10b9724fa5607d7918addc31a3b0c991dcJohn Reck            nativeDestructor(native_instance);
94ffa84e008c712ceffa09d6b89a49882c88b3cca5Hans Boehm            native_instance = 0;  // Other finalizers can still call us.
95f9764a4f532561f6e2e985ff3b25112f1132ce44Romain Guy        }
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
98e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
99e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * @hide
100e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
101e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    protected Shader copy() {
102e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        final Shader copy = new Shader();
103e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        copyLocalMatrix(copy);
104e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        return copy;
105e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    }
106e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
107e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
108e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * @hide
109e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
110e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    protected void copyLocalMatrix(Shader dest) {
111e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        if (mLocalMatrix != null) {
112e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            final Matrix lm = new Matrix();
113e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            getLocalMatrix(lm);
114e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            dest.setLocalMatrix(lm);
115e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        } else {
116e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            dest.setLocalMatrix(null);
117e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        }
118e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    }
119e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
120dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
121dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @hide
122dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
123dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    public long getNativeInstance() {
124866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III        return native_instance;
125866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III    }
126866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III
12701edef10b9724fa5607d7918addc31a3b0c991dcJohn Reck    private static native void nativeDestructor(long native_shader);
128dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger    private static native long nativeSetLocalMatrix(long native_shader, long matrix_instance);
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
130