19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 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
19e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio/** A subclass of shader that returns the composition of two other shaders, combined by
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    an {@link android.graphics.Xfermode} subclass.
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ComposeShader extends Shader {
23e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
24e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private static final int TYPE_XFERMODE = 1;
25e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private static final int TYPE_PORTERDUFFMODE = 2;
26e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
27e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
28e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * Type of the ComposeShader: can be either TYPE_XFERMODE or TYPE_PORTERDUFFMODE
29e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
30e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private int mType;
31e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
32e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private Xfermode mXferMode;
33e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    private PorterDuff.Mode mPorterDuffMode;
34e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
358918190a198f5a0c602dd5d126e5fab8e537fda0Romain Guy    /**
368918190a198f5a0c602dd5d126e5fab8e537fda0Romain Guy     * Hold onto the shaders to avoid GC.
378918190a198f5a0c602dd5d126e5fab8e537fda0Romain Guy     */
388918190a198f5a0c602dd5d126e5fab8e537fda0Romain Guy    @SuppressWarnings({"UnusedDeclaration"})
39de0547c07a65b59d5330588cdd8b1e410a613e9cRomain Guy    private final Shader mShaderA;
408918190a198f5a0c602dd5d126e5fab8e537fda0Romain Guy    @SuppressWarnings({"UnusedDeclaration"})
41de0547c07a65b59d5330588cdd8b1e410a613e9cRomain Guy    private final Shader mShaderB;
42de0547c07a65b59d5330588cdd8b1e410a613e9cRomain Guy
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Create a new compose shader, given shaders A, B, and a combining mode.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        When the mode is applied, it will be given the result from shader A as its
452970c499388b4dcd1232cd622a9b80b395eeb2b4Chet Haase        "dst", and the result from shader B as its "src".
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @param shaderA  The colors from this shader are seen as the "dst" by the mode
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @param shaderB  The colors from this shader are seen as the "src" by the mode
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @param mode     The mode that combines the colors from the two shaders. If mode
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        is null, then SRC_OVER is assumed.
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) {
52e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mType = TYPE_XFERMODE;
53de0547c07a65b59d5330588cdd8b1e410a613e9cRomain Guy        mShaderA = shaderA;
54de0547c07a65b59d5330588cdd8b1e410a613e9cRomain Guy        mShaderB = shaderB;
55e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mXferMode = mode;
56866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III        init(nativeCreate1(shaderA.getNativeInstance(), shaderB.getNativeInstance(),
57866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III                (mode != null) ? mode.native_instance : 0));
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        When the mode is applied, it will be given the result from shader A as its
622970c499388b4dcd1232cd622a9b80b395eeb2b4Chet Haase        "dst", and the result from shader B as its "src".
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @param shaderA  The colors from this shader are seen as the "dst" by the mode
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @param shaderB  The colors from this shader are seen as the "src" by the mode
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @param mode     The PorterDuff mode that combines the colors from the two shaders.
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) {
68e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mType = TYPE_PORTERDUFFMODE;
69de0547c07a65b59d5330588cdd8b1e410a613e9cRomain Guy        mShaderA = shaderA;
70de0547c07a65b59d5330588cdd8b1e410a613e9cRomain Guy        mShaderB = shaderB;
71e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        mPorterDuffMode = mode;
72866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III        init(nativeCreate2(shaderA.getNativeInstance(), shaderB.getNativeInstance(),
73866cf65cc3c53f67836c9157d5c661adfdbd25e1Leon Scroggins III                mode.nativeInt));
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
76e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    /**
77e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     * @hide
78e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio     */
79e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    @Override
80e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    protected Shader copy() {
81e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        final ComposeShader copy;
82e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        switch (mType) {
83e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            case TYPE_XFERMODE:
84e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                copy = new ComposeShader(mShaderA.copy(), mShaderB.copy(), mXferMode);
85e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                break;
86e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            case TYPE_PORTERDUFFMODE:
87e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                copy = new ComposeShader(mShaderA.copy(), mShaderB.copy(), mPorterDuffMode);
88e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                break;
89e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio            default:
90e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                throw new IllegalArgumentException(
91e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio                        "ComposeShader should be created with either Xfermode or PorterDuffMode");
92e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        }
93e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        copyLocalMatrix(copy);
94e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio        return copy;
95e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio    }
96e3c526f4f603e83c5fa8b9e399506b085f5648b7Fabrice Di Meglio
9736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreate1(long native_shaderA, long native_shaderB,
9836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            long native_mode);
9936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreate2(long native_shaderA, long native_shaderB,
10006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy            int porterDuffMode);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
102