Home | History | Annotate | Download | only in graphics
      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 
     17 package android.graphics;
     18 
     19 
     20 import 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 */
     25 public 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     /** @hide */
     80     @Override
     81     protected void verifyNativeInstance() {
     82         if (mShaderA.getNativeInstance() != mNativeInstanceShaderA
     83                 || mShaderB.getNativeInstance() != mNativeInstanceShaderB) {
     84             // Child shader native instance has been updated,
     85             // so our cached native instance is no longer valid - discard it
     86             discardNativeInstance();
     87         }
     88     }
     89 
     90     /**
     91      * @hide
     92      */
     93     @Override
     94     protected Shader copy() {
     95         final ComposeShader copy = new ComposeShader(
     96                 mShaderA.copy(), mShaderB.copy(), mPorterDuffMode);
     97         copyLocalMatrix(copy);
     98         return copy;
     99     }
    100 
    101     private static native long nativeCreate(long nativeMatrix,
    102             long nativeShaderA, long nativeShaderB, int porterDuffMode);
    103 }
    104