ComposeShader.java revision f6b0e60bd07436edb033ffe975030b7c1ee91626
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
17package android.graphics;
18
19
20import android.annotation.NonNull;
21
22/** A subclass of shader that returns the composition of two other shaders, combined by
23    an {@link android.graphics.Xfermode} subclass.
24*/
25public class ComposeShader extends Shader {
26
27    Shader mShaderA;
28    private long mNativeInstanceShaderA;
29    Shader mShaderB;
30    private long mNativeInstanceShaderB;
31    private int mPorterDuffMode;
32
33    /**
34     * Create a new compose shader, given shaders A, B, and a combining mode.
35     * When the mode is applied, it will be given the result from shader A as its
36     * "dst", and the result from shader B as its "src".
37     *
38     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
39     * @param shaderB  The colors from this shader are seen as the "src" by the mode
40     * @param mode     The mode that combines the colors from the two shaders. If mode
41     *                 is null, then SRC_OVER is assumed.
42    */
43    public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
44        this(shaderA, shaderB, mode.porterDuffMode);
45    }
46
47    /**
48     * Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
49     * When the mode is applied, it will be given the result from shader A as its
50     * "dst", and the result from shader B as its "src".
51     *
52     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
53     * @param shaderB  The colors from this shader are seen as the "src" by the mode
54     * @param mode     The PorterDuff mode that combines the colors from the two shaders.
55    */
56    public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
57            @NonNull PorterDuff.Mode mode) {
58        this(shaderA, shaderB, mode.nativeInt);
59    }
60
61    private ComposeShader(Shader shaderA, Shader shaderB, int nativeMode) {
62        if (shaderA == null || shaderB == null) {
63            throw new IllegalArgumentException("Shader parameters must not be null");
64        }
65
66        mShaderA = shaderA;
67        mShaderB = shaderB;
68        mPorterDuffMode = nativeMode;
69    }
70
71    @Override
72    long createNativeInstance(long nativeMatrix) {
73        mNativeInstanceShaderA = mShaderA.getNativeInstance();
74        mNativeInstanceShaderB = mShaderB.getNativeInstance();
75        return nativeCreate(nativeMatrix,
76                mShaderA.getNativeInstance(), mShaderB.getNativeInstance(), mPorterDuffMode);
77    }
78
79    @Override
80    void verifyNativeInstance() {
81        if (mShaderA.getNativeInstance() != mNativeInstanceShaderA
82                || mShaderB.getNativeInstance() != mNativeInstanceShaderB) {
83            // Child shader native instance has been updated,
84            // so our cached native instance is no longer valid - discard it
85            discardNativeInstance();
86        }
87    }
88
89    /**
90     * @hide
91     */
92    @Override
93    protected Shader copy() {
94        final ComposeShader copy = new ComposeShader(
95                mShaderA.copy(), mShaderB.copy(), mPorterDuffMode);
96        copyLocalMatrix(copy);
97        return copy;
98    }
99
100    private static native long nativeCreate(long nativeMatrix,
101            long nativeShaderA, long nativeShaderB, int porterDuffMode);
102}
103