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/** A subclass of shader that returns the composition of two other shaders, combined by 20 an {@link android.graphics.Xfermode} subclass. 21*/ 22public class ComposeShader extends Shader { 23 24 private static final int TYPE_XFERMODE = 1; 25 private static final int TYPE_PORTERDUFFMODE = 2; 26 27 /** 28 * Type of the ComposeShader: can be either TYPE_XFERMODE or TYPE_PORTERDUFFMODE 29 */ 30 private int mType; 31 32 private Xfermode mXferMode; 33 private PorterDuff.Mode mPorterDuffMode; 34 35 /** 36 * Hold onto the shaders to avoid GC. 37 */ 38 @SuppressWarnings({"UnusedDeclaration"}) 39 private final Shader mShaderA; 40 @SuppressWarnings({"UnusedDeclaration"}) 41 private final Shader mShaderB; 42 43 /** Create a new compose shader, given shaders A, B, and a combining mode. 44 When the mode is applied, it will be given the result from shader A as its 45 "dst", and the result from shader B as its "src". 46 @param shaderA The colors from this shader are seen as the "dst" by the mode 47 @param shaderB The colors from this shader are seen as the "src" by the mode 48 @param mode The mode that combines the colors from the two shaders. If mode 49 is null, then SRC_OVER is assumed. 50 */ 51 public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) { 52 mType = TYPE_XFERMODE; 53 mShaderA = shaderA; 54 mShaderB = shaderB; 55 mXferMode = mode; 56 native_instance = nativeCreate1(shaderA.native_instance, shaderB.native_instance, 57 (mode != null) ? mode.native_instance : 0); 58 if (mode instanceof PorterDuffXfermode) { 59 PorterDuff.Mode pdMode = ((PorterDuffXfermode) mode).mode; 60 native_shader = nativePostCreate2(native_instance, shaderA.native_shader, 61 shaderB.native_shader, pdMode != null ? pdMode.nativeInt : 0); 62 } else { 63 native_shader = nativePostCreate1(native_instance, shaderA.native_shader, 64 shaderB.native_shader, mode != null ? mode.native_instance : 0); 65 } 66 } 67 68 /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode. 69 When the mode is applied, it will be given the result from shader A as its 70 "dst", and the result from shader B as its "src". 71 @param shaderA The colors from this shader are seen as the "dst" by the mode 72 @param shaderB The colors from this shader are seen as the "src" by the mode 73 @param mode The PorterDuff mode that combines the colors from the two shaders. 74 */ 75 public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) { 76 mType = TYPE_PORTERDUFFMODE; 77 mShaderA = shaderA; 78 mShaderB = shaderB; 79 mPorterDuffMode = mode; 80 native_instance = nativeCreate2(shaderA.native_instance, shaderB.native_instance, 81 mode.nativeInt); 82 native_shader = nativePostCreate2(native_instance, shaderA.native_shader, 83 shaderB.native_shader, mode.nativeInt); 84 } 85 86 /** 87 * @hide 88 */ 89 @Override 90 protected Shader copy() { 91 final ComposeShader copy; 92 switch (mType) { 93 case TYPE_XFERMODE: 94 copy = new ComposeShader(mShaderA.copy(), mShaderB.copy(), mXferMode); 95 break; 96 case TYPE_PORTERDUFFMODE: 97 copy = new ComposeShader(mShaderA.copy(), mShaderB.copy(), mPorterDuffMode); 98 break; 99 default: 100 throw new IllegalArgumentException( 101 "ComposeShader should be created with either Xfermode or PorterDuffMode"); 102 } 103 copyLocalMatrix(copy); 104 return copy; 105 } 106 107 private static native int nativeCreate1(int native_shaderA, int native_shaderB, 108 int native_mode); 109 private static native int nativeCreate2(int native_shaderA, int native_shaderB, 110 int porterDuffMode); 111 private static native int nativePostCreate1(int native_shader, int native_skiaShaderA, 112 int native_skiaShaderB, int native_mode); 113 private static native int nativePostCreate2(int native_shader, int native_skiaShaderA, 114 int native_skiaShaderB, int porterDuffMode); 115} 116