summaryrefslogtreecommitdiff
path: root/graphics/java
diff options
context:
space:
mode:
author Nader Jawad <njawad@google.com> 2019-03-06 17:29:22 -0800
committer Nader Jawad <njawad@google.com> 2019-03-26 16:44:10 -0700
commitdadf251a0d6fbd8a4bdca3b748154a10db35433b (patch)
treead5df3a2b1039a9500a1985b97550f495ab9d7be /graphics/java
parent04b8032de5bcdbb368fa98b04664542b0048ff16 (diff)
Added framework APIs to leverage new BlendMode API
Updated various framework APIs to leverage the new BlendMode API that parallels the corresponding porterduff mode equivalent. Added new Drawable#onApplyBlendMode API that provides a backward compatible solution for Drawable implementations that leverage the new BlendMode API as well as fall back on the traditional setTintMode(PorterDuff.Mode) API for instances where it is not implemented Bug:126726419 Test: Re-ran CTS graphics test cases Change-Id: I119a7f57dce0a095c0a73cf83dc50b82beff5e32
Diffstat (limited to 'graphics/java')
-rw-r--r--graphics/java/android/graphics/BaseCanvas.java2
-rw-r--r--graphics/java/android/graphics/BaseRecordingCanvas.java2
-rw-r--r--graphics/java/android/graphics/BlendMode.java58
-rw-r--r--graphics/java/android/graphics/ComposeShader.java22
-rw-r--r--graphics/java/android/graphics/PorterDuff.java3
-rw-r--r--graphics/java/android/graphics/PorterDuffXfermode.java5
-rw-r--r--graphics/java/android/graphics/Xfermode.java2
-rw-r--r--graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java6
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java6
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java39
-rw-r--r--graphics/java/android/graphics/drawable/ColorDrawable.java35
-rw-r--r--graphics/java/android/graphics/drawable/ColorStateListDrawable.java16
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java97
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java16
-rw-r--r--graphics/java/android/graphics/drawable/DrawableWrapper.java6
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java32
-rw-r--r--graphics/java/android/graphics/drawable/Icon.java35
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java6
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java34
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java35
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java47
21 files changed, 367 insertions, 137 deletions
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index fd3773588299..31906781159b 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -240,7 +240,7 @@ public abstract class BaseCanvas {
}
public void drawColor(@ColorInt int color) {
- nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+ nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode);
}
/**
diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java
index 3e117411db01..2afc3d27fa27 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -200,7 +200,7 @@ public class BaseRecordingCanvas extends Canvas {
@Override
public final void drawColor(@ColorInt int color) {
- nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+ nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode);
}
/**
diff --git a/graphics/java/android/graphics/BlendMode.java b/graphics/java/android/graphics/BlendMode.java
index 39392c89d170..0b267048d976 100644
--- a/graphics/java/android/graphics/BlendMode.java
+++ b/graphics/java/android/graphics/BlendMode.java
@@ -454,6 +454,64 @@ public enum BlendMode {
return null;
}
+ /**
+ * @hide
+ */
+ public static int toValue(BlendMode mode) {
+ return mode.getXfermode().porterDuffMode;
+ }
+
+ /**
+ * @hide
+ */
+ public static @Nullable PorterDuff.Mode blendModeToPorterDuffMode(@Nullable BlendMode mode) {
+ if (mode != null) {
+ switch (mode) {
+ case CLEAR:
+ return PorterDuff.Mode.CLEAR;
+ case SRC:
+ return PorterDuff.Mode.SRC;
+ case DST:
+ return PorterDuff.Mode.DST;
+ case SRC_OVER:
+ return PorterDuff.Mode.SRC_OVER;
+ case DST_OVER:
+ return PorterDuff.Mode.DST_OVER;
+ case SRC_IN:
+ return PorterDuff.Mode.SRC_IN;
+ case DST_IN:
+ return PorterDuff.Mode.DST_IN;
+ case SRC_OUT:
+ return PorterDuff.Mode.SRC_OUT;
+ case DST_OUT:
+ return PorterDuff.Mode.DST_OUT;
+ case SRC_ATOP:
+ return PorterDuff.Mode.SRC_ATOP;
+ case DST_ATOP:
+ return PorterDuff.Mode.DST_ATOP;
+ case XOR:
+ return PorterDuff.Mode.XOR;
+ case DARKEN:
+ return PorterDuff.Mode.DARKEN;
+ case LIGHTEN:
+ return PorterDuff.Mode.LIGHTEN;
+ // b/73224934 PorterDuff Multiply maps to Skia Modulate
+ case MODULATE:
+ return PorterDuff.Mode.MULTIPLY;
+ case SCREEN:
+ return PorterDuff.Mode.SCREEN;
+ case PLUS:
+ return PorterDuff.Mode.ADD;
+ case OVERLAY:
+ return PorterDuff.Mode.OVERLAY;
+ default:
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
@NonNull
private final Xfermode mXfermode;
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 189e1746e644..93ddb10d24bc 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -39,7 +39,10 @@ public class ComposeShader extends Shader {
* @param shaderB The colors from this shader are seen as the "src" by the mode
* @param mode The mode that combines the colors from the two shaders. If mode
* is null, then SRC_OVER is assumed.
+ *
+ * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead
*/
+ @Deprecated
public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
this(shaderA, shaderB, mode.porterDuffMode);
}
@@ -52,12 +55,29 @@ public class ComposeShader extends Shader {
* @param shaderA The colors from this shader are seen as the "dst" by the mode
* @param shaderB The colors from this shader are seen as the "src" by the mode
* @param mode The PorterDuff mode that combines the colors from the two shaders.
- */
+ *
+ * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead
+ */
+ @Deprecated
public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
@NonNull PorterDuff.Mode mode) {
this(shaderA, shaderB, mode.nativeInt);
}
+ /**
+ * Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
+ * When the mode is applied, it will be given the result from shader A as its
+ * "dst", and the result from shader B as its "src".
+ *
+ * @param shaderA The colors from this shader are seen as the "dst" by the mode
+ * @param shaderB The colors from this shader are seen as the "src" by the mode
+ * @param blendMode The blend mode that combines the colors from the two shaders.
+ */
+ public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
+ @NonNull BlendMode blendMode) {
+ this(shaderA, shaderB, blendMode.getXfermode().porterDuffMode);
+ }
+
private ComposeShader(Shader shaderA, Shader shaderB, int nativeMode) {
if (shaderA == null || shaderB == null) {
throw new IllegalArgumentException("Shader parameters must not be null");
diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index fba50430f2ef..459291b7565e 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -23,7 +23,10 @@ import android.annotation.UnsupportedAppUsage;
* that can be passed to {@link PorterDuffXfermode}, a specialized implementation
* of {@link Paint}'s {@link Paint#setXfermode(Xfermode) transfer mode}.
* All the available modes can be found in the {@link Mode} enum.</p>
+ *
+ * @deprecated Use {@link BlendMode} with {@link Paint#setBlendMode(BlendMode)} instead
*/
+@Deprecated
public class PorterDuff {
/**
* {@usesMathJax}
diff --git a/graphics/java/android/graphics/PorterDuffXfermode.java b/graphics/java/android/graphics/PorterDuffXfermode.java
index 84d953de91db..5b933c493162 100644
--- a/graphics/java/android/graphics/PorterDuffXfermode.java
+++ b/graphics/java/android/graphics/PorterDuffXfermode.java
@@ -21,6 +21,11 @@ package android.graphics;
* {@link Paint#setXfermode(Xfermode) transfer mode}. Refer to the
* documentation of the {@link PorterDuff.Mode} enum for more
* information on the available alpha compositing and blending modes.</p>
+ *
+ * @deprecated Consider using {@link BlendMode} instead as it supports a wider
+ * set of blend modes than those defined in {@link PorterDuff.Mode}
+ *
+ * @see Paint#setBlendMode(BlendMode)
*/
public class PorterDuffXfermode extends Xfermode {
/**
diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java
index 6f4adfde7ff9..41cf79ad49fd 100644
--- a/graphics/java/android/graphics/Xfermode.java
+++ b/graphics/java/android/graphics/Xfermode.java
@@ -31,7 +31,7 @@ import android.annotation.UnsupportedAppUsage;
* objects drawn with that paint have the xfermode applied.
*/
public class Xfermode {
- static final int DEFAULT = PorterDuff.Mode.SRC_OVER.nativeInt;
+ static final int DEFAULT = BlendMode.SRC_OVER.getXfermode().porterDuffMode;
@UnsupportedAppUsage
int porterDuffMode = DEFAULT;
}
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index cb12a7c6ba6b..7def322c1953 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -27,6 +27,7 @@ import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -35,7 +36,6 @@ import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Shader;
@@ -701,13 +701,13 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.N_CHILDREN;
for (int i = 0; i < N; i++) {
final Drawable dr = array[i].mDrawable;
if (dr != null) {
- dr.setTintMode(tintMode);
+ dr.setTintMode(blendMode);
}
}
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index d9dab98c2be1..f45bf9b783e8 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -33,12 +33,12 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderNode;
@@ -477,8 +477,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
}
@Override
- public void setTintMode(PorterDuff.Mode tintMode) {
- mAnimatedVectorState.mVectorDrawable.setTintMode(tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mAnimatedVectorState.mVectorDrawable.setTintMode(blendMode);
}
@Override
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 976190109e7c..6b30158a183a 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -25,6 +25,8 @@ import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ImageDecoder;
@@ -33,9 +35,7 @@ import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Xfermode;
@@ -90,7 +90,7 @@ public class BitmapDrawable extends Drawable {
@UnsupportedAppUsage
private BitmapState mBitmapState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeFilter;
@UnsupportedAppUsage
private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -527,8 +527,8 @@ public class BitmapDrawable extends Drawable {
}
final boolean clearColorFilter;
- if (mTintFilter != null && paint.getColorFilter() == null) {
- paint.setColorFilter(mTintFilter);
+ if (mBlendModeFilter != null && paint.getColorFilter() == null) {
+ paint.setColorFilter(mBlendModeFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
@@ -678,17 +678,19 @@ public class BitmapDrawable extends Drawable {
final BitmapState state = mBitmapState;
if (state.mTint != tint) {
state.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, tint,
+ mBitmapState.mBlendMode);
invalidateSelf();
}
}
@Override
- public void setTintMode(PorterDuff.Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final BitmapState state = mBitmapState;
- if (state.mTintMode != tintMode) {
- state.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, tintMode);
+ if (state.mBlendMode != blendMode) {
+ state.mBlendMode = blendMode;
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mBitmapState.mTint,
+ blendMode);
invalidateSelf();
}
}
@@ -706,7 +708,7 @@ public class BitmapDrawable extends Drawable {
*/
@UnsupportedAppUsage
public Mode getTintMode() {
- return mBitmapState.mTintMode;
+ return BlendMode.blendModeToPorterDuffMode(mBitmapState.mBlendMode);
}
/**
@@ -744,8 +746,9 @@ public class BitmapDrawable extends Drawable {
@Override
protected boolean onStateChange(int[] stateSet) {
final BitmapState state = mBitmapState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint,
+ state.mBlendMode);
return true;
}
return false;
@@ -864,7 +867,7 @@ public class BitmapDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.BitmapDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.BitmapDrawable_tint);
@@ -979,7 +982,8 @@ public class BitmapDrawable extends Drawable {
int[] mThemeAttrs = null;
Bitmap mBitmap = null;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
+
int mGravity = Gravity.FILL;
float mBaseAlpha = 1.0f;
Shader.TileMode mTileModeX = null;
@@ -1005,7 +1009,7 @@ public class BitmapDrawable extends Drawable {
BitmapState(BitmapState bitmapState) {
mBitmap = bitmapState.mBitmap;
mTint = bitmapState.mTint;
- mTintMode = bitmapState.mTintMode;
+ mBlendMode = bitmapState.mBlendMode;
mThemeAttrs = bitmapState.mThemeAttrs;
mChangingConfigurations = bitmapState.mChangingConfigurations;
mGravity = bitmapState.mGravity;
@@ -1065,7 +1069,8 @@ public class BitmapDrawable extends Drawable {
*/
private void updateLocalState(Resources res) {
mTargetDensity = resolveDensity(res, mBitmapState.mTargetDensity);
- mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, mBitmapState.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mBitmapState.mTint,
+ mBitmapState.mBlendMode);
computeBitmapSize();
}
}
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 3c449166d9d5..efa806afce70 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -26,13 +26,13 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.view.ViewDebug;
@@ -58,7 +58,7 @@ public class ColorDrawable extends Drawable {
@ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
private ColorState mColorState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeColorFilter;
private boolean mMutated;
@@ -111,9 +111,10 @@ public class ColorDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
final ColorFilter colorFilter = mPaint.getColorFilter();
- if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null || mTintFilter != null) {
+ if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null
+ || mBlendModeColorFilter != null) {
if (colorFilter == null) {
- mPaint.setColorFilter(mTintFilter);
+ mPaint.setColorFilter(mBlendModeColorFilter);
}
mPaint.setColor(mColorState.mUseColor);
@@ -208,22 +209,25 @@ public class ColorDrawable extends Drawable {
@Override
public void setTintList(ColorStateList tint) {
mColorState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mColorState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint,
+ mColorState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(Mode tintMode) {
- mColorState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mColorState.mBlendMode = blendMode;
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mColorState.mTint,
+ blendMode);
invalidateSelf();
}
@Override
protected boolean onStateChange(int[] stateSet) {
final ColorState state = mColorState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+ state.mBlendMode);
return true;
}
return false;
@@ -261,7 +265,7 @@ public class ColorDrawable extends Drawable {
@Override
public int getOpacity() {
- if (mTintFilter != null || mPaint.getColorFilter() != null) {
+ if (mBlendModeColorFilter != null || mPaint.getColorFilter() != null) {
return PixelFormat.TRANSLUCENT;
}
@@ -348,7 +352,7 @@ public class ColorDrawable extends Drawable {
int mUseColor; // basecolor modulated by setAlpha()
@Config int mChangingConfigurations;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
ColorState() {
// Empty constructor.
@@ -360,7 +364,7 @@ public class ColorDrawable extends Drawable {
mUseColor = state.mUseColor;
mChangingConfigurations = state.mChangingConfigurations;
mTint = state.mTint;
- mTintMode = state.mTintMode;
+ mBlendMode = state.mBlendMode;
}
@Override
@@ -398,6 +402,7 @@ public class ColorDrawable extends Drawable {
* after inflating or applying a theme.
*/
private void updateLocalState(Resources r) {
- mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, mColorState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mColorState.mTint,
+ mColorState.mBlendMode);
}
}
diff --git a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
index ee4d1e72c130..b94b11468371 100644
--- a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
@@ -21,10 +21,10 @@ import android.annotation.Nullable;
import android.content.pm.ActivityInfo;
import android.content.res.ColorStateList;
import android.content.res.Resources;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.util.MathUtils;
/**
@@ -114,9 +114,9 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
}
@Override
- public void setTintMode(@NonNull PorterDuff.Mode tintMode) {
- mState.mTintMode = tintMode;
- mColorDrawable.setTintMode(tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mState.mBlendMode = blendMode;
+ mColorDrawable.setTintMode(blendMode);
onStateChange(getState());
}
@@ -236,7 +236,7 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
ColorStateList mColor = null;
ColorStateList mTint = null;
int mAlpha = -1;
- PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
@ActivityInfo.Config int mChangingConfigurations = 0;
ColorStateListDrawableState() {
@@ -246,7 +246,7 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
mColor = state.mColor;
mTint = state.mTint;
mAlpha = state.mAlpha;
- mTintMode = state.mTintMode;
+ mBlendMode = state.mBlendMode;
mChangingConfigurations = state.mChangingConfigurations;
}
@@ -292,8 +292,8 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
mColorDrawable.setTintList(mState.mTint);
}
- if (mState.mTintMode != DEFAULT_TINT_MODE) {
- mColorDrawable.setTintMode(mState.mTintMode);
+ if (mState.mBlendMode != DEFAULT_BLEND_MODE) {
+ mColorDrawable.setTintMode(mState.mBlendMode);
}
}
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 49d353057d59..e4142a933f0f 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -30,6 +30,8 @@ import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -182,6 +184,7 @@ public abstract class Drawable {
private static final Rect ZERO_BOUNDS_RECT = new Rect();
static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN;
+ static final BlendMode DEFAULT_BLEND_MODE = BlendMode.SRC_IN;
private int[] mStateSet = StateSet.WILD_CARD;
private int mLevel = 0;
@@ -210,6 +213,24 @@ public abstract class Drawable {
protected int mSrcDensityOverride = 0;
/**
+ * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and
+ * setTintMode(BlendMode) as each default implementation invokes the other in order to
+ * support new use cases that utilize the new blending modes as well as support the legacy
+ * use cases. This flag tracks that {@link #setTintMode(BlendMode)} is only invoked once
+ * per invocation.
+ */
+ private boolean mSetBlendModeInvoked = false;
+
+ /**
+ * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and
+ * setTintMode(BlendMode) as each default implementation invokes the other in order to
+ * support new use cases that utilize the new blending modes as well as support the legacy
+ * use cases. This flag tracks that {@link #setTintMode(Mode)} is only invoked once
+ * per invocation;
+ */
+ private boolean mSetTintModeInvoked = false;
+
+ /**
* Draw in its bounds (set via setBounds) respecting optional effects such
* as alpha (set via setAlpha) and color filter (set via setColorFilter).
*
@@ -630,6 +651,7 @@ public abstract class Drawable {
* @param tintColor Color to use for tinting this drawable
* @see #setTintList(ColorStateList)
* @see #setTintMode(PorterDuff.Mode)
+ * @see #setTintMode(BlendMode)
*/
public void setTint(@ColorInt int tintColor) {
setTintList(ColorStateList.valueOf(tintColor));
@@ -651,6 +673,7 @@ public abstract class Drawable {
* {@code null} to clear the tint
* @see #setTint(int)
* @see #setTintMode(PorterDuff.Mode)
+ * @see #setTintMode(BlendMode)
*/
public void setTintList(@Nullable ColorStateList tint) {}
@@ -668,8 +691,45 @@ public abstract class Drawable {
* @param tintMode A Porter-Duff blending mode
* @see #setTint(int)
* @see #setTintList(ColorStateList)
+ *
+ * @deprecated use {@link #setTintMode(BlendMode)} instead
+ */
+ @Deprecated
+ public void setTintMode(@NonNull PorterDuff.Mode tintMode) {
+ if (!mSetTintModeInvoked) {
+ mSetTintModeInvoked = true;
+ BlendMode mode = BlendMode.fromValue(tintMode.nativeInt);
+ if (mode != null) {
+ setTintMode(mode);
+ }
+ mSetTintModeInvoked = false;
+ }
+ }
+
+ /**
+ * Specifies a tint blending mode for this drawable.
+ * <p>
+ * Defines how this drawable's tint color should be blended into the drawable
+ * before it is drawn to screen. Default tint mode is {@link BlendMode#SRC_IN}.
+ * </p>
+ * <p class="note"><strong>Note:</strong> Setting a color filter via
+ * {@link #setColorFilter(ColorFilter)}
+ * </p>
+ *
+ * @param blendMode
+ * @see #setTint(int)
+ * @see #setTintList(ColorStateList)
*/
- public void setTintMode(@NonNull PorterDuff.Mode tintMode) {}
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ if (!mSetBlendModeInvoked) {
+ mSetBlendModeInvoked = true;
+ PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode);
+ if (mode != null) {
+ setTintMode(mode);
+ }
+ mSetBlendModeInvoked = false;
+ }
+ }
/**
* Returns the current color filter, or {@code null} if none set.
@@ -1540,6 +1600,20 @@ public abstract class Drawable {
return tintFilter;
}
+ @Nullable BlendModeColorFilter updateBlendModeFilter(@Nullable BlendModeColorFilter blendFilter,
+ @Nullable ColorStateList tint, @Nullable BlendMode blendMode) {
+ if (tint == null || blendMode == null) {
+ return null;
+ }
+
+ final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
+ if (blendFilter == null || blendFilter.getColor() != color
+ || blendFilter.getMode() != blendMode) {
+ return new BlendModeColorFilter(color, blendMode);
+ }
+ return blendFilter;
+ }
+
/**
* Obtains styled attributes from the theme, if available, or unstyled
* resources if the theme is null.
@@ -1642,5 +1716,26 @@ public abstract class Drawable {
default: return defaultMode;
}
}
+
+ /**
+ * Parses a {@link android.graphics.BlendMode} from a tintMode
+ * attribute's enum value.
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public static BlendMode parseBlendMode(int value, BlendMode defaultMode) {
+ switch (value) {
+ case 3: return BlendMode.SRC_OVER;
+ case 5: return BlendMode.SRC_IN;
+ case 9: return BlendMode.SRC_ATOP;
+ // b/73224934 PorterDuff Multiply maps to Skia Modulate so actually
+ // return BlendMode.MODULATE here
+ case 14: return BlendMode.MODULATE;
+ case 15: return BlendMode.SCREEN;
+ case 16: return BlendMode.PLUS;
+ default: return defaultMode;
+ }
+ }
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 77e77c49973c..3e0881aef9ed 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -22,12 +22,12 @@ import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.os.Build;
import android.os.SystemClock;
@@ -196,14 +196,14 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
mDrawableContainerState.mHasTintMode = true;
- if (mDrawableContainerState.mTintMode != tintMode) {
- mDrawableContainerState.mTintMode = tintMode;
+ if (mDrawableContainerState.mBlendMode != blendMode) {
+ mDrawableContainerState.mBlendMode = blendMode;
if (mCurrDrawable != null) {
- mCurrDrawable.setTintMode(tintMode);
+ mCurrDrawable.setTintMode(blendMode);
}
}
}
@@ -544,7 +544,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
d.setTintList(mDrawableContainerState.mTintList);
}
if (mDrawableContainerState.mHasTintMode) {
- d.setTintMode(mDrawableContainerState.mTintMode);
+ d.setTintMode(mDrawableContainerState.mBlendMode);
}
}
@@ -730,7 +730,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
boolean mHasColorFilter;
ColorStateList mTintList;
- Mode mTintMode;
+ BlendMode mBlendMode;
boolean mHasTintList;
boolean mHasTintMode;
@@ -762,7 +762,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mColorFilter = orig.mColorFilter;
mHasColorFilter = orig.mHasColorFilter;
mTintList = orig.mTintList;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
mHasTintList = orig.mHasTintList;
mHasTintMode = orig.mHasTintMode;
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 70c90eb05b17..d81401d451ca 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -24,12 +24,12 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Xfermode;
import android.util.AttributeSet;
@@ -324,9 +324,9 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb
}
@Override
- public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
if (mDrawable != null) {
- mDrawable.setTintMode(tintMode);
+ mDrawable.setTintMode(blendMode);
}
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index e58e80225292..cdb3441d5225 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -28,6 +28,8 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -38,8 +40,6 @@ import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -169,7 +169,7 @@ public class GradientDrawable extends Drawable {
@UnsupportedAppUsage
private Paint mStrokePaint; // optional, set by the caller
private ColorFilter mColorFilter; // optional, set by the caller
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeColorFilter;
private int mAlpha = 0xFF; // modified by the caller
private final Path mPath = new Path();
@@ -731,7 +731,7 @@ public class GradientDrawable extends Drawable {
mStrokePaint.getStrokeWidth() > 0;
final boolean haveFill = currFillAlpha > 0;
final GradientState st = mGradientState;
- final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter;
+ final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mBlendModeColorFilter;
/* we need a layer iff we're drawing both a fill and stroke, and the
stroke is non-opaque, and our shapetype actually supports
@@ -1130,8 +1130,9 @@ public class GradientDrawable extends Drawable {
}
}
- if (s.mTint != null && s.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode);
+ if (s.mTint != null && s.mBlendMode != null) {
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, s.mTint,
+ s.mBlendMode);
invalidateSelf = true;
}
@@ -1204,14 +1205,16 @@ public class GradientDrawable extends Drawable {
@Override
public void setTintList(@Nullable ColorStateList tint) {
mGradientState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode);
+ mBlendModeColorFilter =
+ updateBlendModeFilter(mBlendModeColorFilter, tint, mGradientState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
- mGradientState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mGradientState.mBlendMode = blendMode;
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mGradientState.mTint,
+ blendMode);
invalidateSelf();
}
@@ -1465,7 +1468,7 @@ public class GradientDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint);
@@ -2010,7 +2013,7 @@ public class GradientDrawable extends Drawable {
boolean mOpaqueOverShape;
ColorStateList mTint = null;
- PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
int mDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -2068,7 +2071,7 @@ public class GradientDrawable extends Drawable {
mOpaqueOverBounds = orig.mOpaqueOverBounds;
mOpaqueOverShape = orig.mOpaqueOverShape;
mTint = orig.mTint;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
mThemeAttrs = orig.mThemeAttrs;
mAttrSize = orig.mAttrSize;
mAttrGradient = orig.mAttrGradient;
@@ -2355,7 +2358,8 @@ public class GradientDrawable extends Drawable {
}
}
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+ state.mBlendMode);
mGradientIsDirty = true;
state.computeOpacity();
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 71dd7a2f4800..5fd18a1431e0 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -30,6 +30,7 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.BlendMode;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.AsyncTask;
@@ -105,8 +106,8 @@ public final class Icon implements Parcelable {
private final int mType;
private ColorStateList mTintList;
- static final PorterDuff.Mode DEFAULT_TINT_MODE = Drawable.DEFAULT_TINT_MODE; // SRC_IN
- private PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+ static final BlendMode DEFAULT_BLEND_MODE = Drawable.DEFAULT_BLEND_MODE; // SRC_IN
+ private BlendMode mBlendMode = Drawable.DEFAULT_BLEND_MODE;
// To avoid adding unnecessary overhead, we have a few basic objects that get repurposed
// based on the value of mType.
@@ -320,10 +321,10 @@ public final class Icon implements Parcelable {
*/
public Drawable loadDrawable(Context context) {
final Drawable result = loadDrawableInner(context);
- if (result != null && (mTintList != null || mTintMode != DEFAULT_TINT_MODE)) {
+ if (result != null && (mTintList != null || mBlendMode != DEFAULT_BLEND_MODE)) {
result.mutate();
result.setTintList(mTintList);
- result.setTintMode(mTintMode);
+ result.setTintMode(mBlendMode);
}
return result;
}
@@ -695,16 +696,30 @@ public final class Icon implements Parcelable {
*
* @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null
* @return this same object, for use in chained construction
+ *
+ * @deprecated use {@link #setTintMode(BlendMode)} instead
+ */
+ @Deprecated
+ public @NonNull Icon setTintMode(@NonNull PorterDuff.Mode mode) {
+ mBlendMode = BlendMode.fromValue(mode.nativeInt);
+ return this;
+ }
+
+ /**
+ * Store a blending mode to use whenever this Icon is drawn.
+ *
+ * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null
+ * @return this same object, for use in chained construction
*/
- public Icon setTintMode(PorterDuff.Mode mode) {
- mTintMode = mode;
+ public @NonNull Icon setTintMode(@NonNull BlendMode mode) {
+ mBlendMode = mode;
return this;
}
/** @hide */
@UnsupportedAppUsage
public boolean hasTint() {
- return (mTintList != null) || (mTintMode != DEFAULT_TINT_MODE);
+ return (mTintList != null) || (mBlendMode != DEFAULT_BLEND_MODE);
}
/**
@@ -757,7 +772,7 @@ public final class Icon implements Parcelable {
sep = "|";
}
}
- if (mTintMode != DEFAULT_TINT_MODE) sb.append(" mode=").append(mTintMode);
+ if (mBlendMode != DEFAULT_BLEND_MODE) sb.append(" mode=").append(mBlendMode);
sb.append(")");
return sb.toString();
}
@@ -807,7 +822,7 @@ public final class Icon implements Parcelable {
if (in.readInt() == 1) {
mTintList = ColorStateList.CREATOR.createFromParcel(in);
}
- mTintMode = PorterDuff.intToMode(in.readInt());
+ mBlendMode = BlendMode.fromValue(in.readInt());
}
@Override
@@ -837,7 +852,7 @@ public final class Icon implements Parcelable {
dest.writeInt(1);
mTintList.writeToParcel(dest, flags);
}
- dest.writeInt(PorterDuff.modeToInt(mTintMode));
+ dest.writeInt(BlendMode.toValue(mBlendMode));
}
public static final @android.annotation.NonNull Parcelable.Creator<Icon> CREATOR
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index b4392c8d023f..e2c84927b578 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -24,11 +24,11 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -1397,13 +1397,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNumChildren;
for (int i = 0; i < N; i++) {
final Drawable dr = array[i].mDrawable;
if (dr != null) {
- dr.setTintMode(tintMode);
+ dr.setTintMode(blendMode);
}
}
}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index b53477137331..4972e6a82b7d 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -25,6 +25,8 @@ import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ImageDecoder;
@@ -33,9 +35,6 @@ import android.graphics.NinePatch;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
@@ -73,7 +72,7 @@ public class NinePatchDrawable extends Drawable {
@UnsupportedAppUsage
private NinePatchState mNinePatchState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeFilter;
private Rect mPadding;
private Insets mOpticalInsets = Insets.NONE;
private Rect mOutlineInsets;
@@ -198,8 +197,8 @@ public class NinePatchDrawable extends Drawable {
int restoreToCount = -1;
final boolean clearColorFilter;
- if (mTintFilter != null && getPaint().getColorFilter() == null) {
- mPaint.setColorFilter(mTintFilter);
+ if (mBlendModeFilter != null && getPaint().getColorFilter() == null) {
+ mPaint.setColorFilter(mBlendModeFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
@@ -344,14 +343,16 @@ public class NinePatchDrawable extends Drawable {
@Override
public void setTintList(@Nullable ColorStateList tint) {
mNinePatchState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mNinePatchState.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, tint,
+ mNinePatchState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
- mNinePatchState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mNinePatchState.mTint, tintMode);
+ public void setTintMode(@Nullable BlendMode blendMode) {
+ mNinePatchState.mBlendMode = blendMode;
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mNinePatchState.mTint,
+ blendMode);
invalidateSelf();
}
@@ -467,7 +468,7 @@ public class NinePatchDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.NinePatchDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.NinePatchDrawable_tint);
@@ -566,8 +567,9 @@ public class NinePatchDrawable extends Drawable {
@Override
protected boolean onStateChange(int[] stateSet) {
final NinePatchState state = mNinePatchState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint,
+ state.mBlendMode);
return true;
}
@@ -593,7 +595,7 @@ public class NinePatchDrawable extends Drawable {
@UnsupportedAppUsage
NinePatch mNinePatch = null;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
Rect mPadding = null;
Insets mOpticalInsets = Insets.NONE;
float mBaseAlpha = 1.0f;
@@ -628,7 +630,7 @@ public class NinePatchDrawable extends Drawable {
mChangingConfigurations = orig.mChangingConfigurations;
mNinePatch = orig.mNinePatch;
mTint = orig.mTint;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
mPadding = orig.mPadding;
mOpticalInsets = orig.mOpticalInsets;
mBaseAlpha = orig.mBaseAlpha;
@@ -751,7 +753,7 @@ public class NinePatchDrawable extends Drawable {
} else {
mTargetDensity = Drawable.resolveDensity(res, mTargetDensity);
}
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint, state.mBlendMode);
computeBitmapSize();
}
}
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 7bfb4c38d6c8..b5fe7f9e432d 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -24,14 +24,13 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Xfermode;
@@ -75,7 +74,7 @@ import java.io.IOException;
*/
public class ShapeDrawable extends Drawable {
private @NonNull ShapeState mShapeState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeColorFilter;
private boolean mMutated;
/**
@@ -238,8 +237,8 @@ public class ShapeDrawable extends Drawable {
// only draw shape if it may affect output
if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadowLayer()) {
final boolean clearColorFilter;
- if (mTintFilter != null && paint.getColorFilter() == null) {
- paint.setColorFilter(mTintFilter);
+ if (mBlendModeColorFilter != null && paint.getColorFilter() == null) {
+ paint.setColorFilter(mBlendModeColorFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
@@ -292,14 +291,16 @@ public class ShapeDrawable extends Drawable {
@Override
public void setTintList(ColorStateList tint) {
mShapeState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mShapeState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint,
+ mShapeState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(PorterDuff.Mode tintMode) {
- mShapeState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mShapeState.mBlendMode = blendMode;
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mShapeState.mTint,
+ blendMode);
invalidateSelf();
}
@@ -352,8 +353,9 @@ public class ShapeDrawable extends Drawable {
@Override
protected boolean onStateChange(int[] stateSet) {
final ShapeState state = mShapeState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+ state.mBlendMode);
return true;
}
return false;
@@ -475,7 +477,7 @@ public class ShapeDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.ShapeDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.ShapeDrawable_tint);
@@ -540,7 +542,7 @@ public class ShapeDrawable extends Drawable {
int[] mThemeAttrs;
Shape mShape;
ColorStateList mTint;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
Rect mPadding;
int mIntrinsicWidth;
int mIntrinsicHeight;
@@ -573,7 +575,7 @@ public class ShapeDrawable extends Drawable {
}
}
mTint = orig.mTint;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
if (orig.mPadding != null) {
mPadding = new Rect(orig.mPadding);
}
@@ -625,7 +627,8 @@ public class ShapeDrawable extends Drawable {
* after inflating or applying a theme.
*/
private void updateLocalState() {
- mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, mShapeState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mShapeState.mTint,
+ mShapeState.mBlendMode);
}
/**
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 7325b857f02c..43772ec20cf3 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -24,11 +24,13 @@ import android.content.res.GradientColor;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
@@ -324,6 +326,8 @@ public class VectorDrawable extends Drawable {
@UnsupportedAppUsage
private PorterDuffColorFilter mTintFilter;
+
+ private BlendModeColorFilter mBlendModeColorFilter;
private ColorFilter mColorFilter;
private boolean mMutated;
@@ -371,7 +375,7 @@ public class VectorDrawable extends Drawable {
mDpiScaledDirty = true;
}
- mTintFilter = updateTintFilter(mTintFilter, mVectorState.mTint, mVectorState.mTintMode);
+ updateColorFilters(mVectorState.mBlendMode, mVectorState.mTint);
}
@Override
@@ -413,7 +417,8 @@ public class VectorDrawable extends Drawable {
}
// Color filters always override tint filters.
- final ColorFilter colorFilter = (mColorFilter == null ? mTintFilter : mColorFilter);
+ final ColorFilter colorFilter = (mColorFilter == null ? mBlendModeColorFilter :
+ mColorFilter);
final long colorFilterNativeInstance = colorFilter == null ? 0 :
colorFilter.getNativeInstance();
boolean canReuseCache = mVectorState.canReuseCache();
@@ -475,17 +480,19 @@ public class VectorDrawable extends Drawable {
final VectorDrawableState state = mVectorState;
if (state.mTint != tint) {
state.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode);
+
+ updateColorFilters(mVectorState.mBlendMode, tint);
invalidateSelf();
}
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final VectorDrawableState state = mVectorState;
- if (state.mTintMode != tintMode) {
- state.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode);
+ if (state.mBlendMode != blendMode) {
+ state.mBlendMode = blendMode;
+
+ updateColorFilters(state.mBlendMode, state.mTint);
invalidateSelf();
}
}
@@ -515,14 +522,22 @@ public class VectorDrawable extends Drawable {
changed = true;
state.mCacheDirty = true;
}
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ BlendMode blendMode = state.mBlendMode;
+ ColorStateList tint = state.mTint;
+ updateColorFilters(blendMode, tint);
changed = true;
}
return changed;
}
+ private void updateColorFilters(@Nullable BlendMode blendMode, ColorStateList tint) {
+ PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode);
+ mTintFilter = updateTintFilter(mTintFilter, tint, mode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint, blendMode);
+ }
+
@Override
public int getOpacity() {
// We can't tell whether the drawable is fully opaque unless we examine all the pixels,
@@ -737,7 +752,7 @@ public class VectorDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint);
@@ -911,7 +926,7 @@ public class VectorDrawable extends Drawable {
int[] mThemeAttrs;
@Config int mChangingConfigurations;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
boolean mAutoMirrored;
int mBaseWidth = 0;
@@ -929,7 +944,7 @@ public class VectorDrawable extends Drawable {
// Fields for cache
int[] mCachedThemeAttrs;
ColorStateList mCachedTint;
- Mode mCachedTintMode;
+ BlendMode mCachedBlendMode;
boolean mCachedAutoMirrored;
boolean mCacheDirty;
@@ -970,7 +985,7 @@ public class VectorDrawable extends Drawable {
mThemeAttrs = copy.mThemeAttrs;
mChangingConfigurations = copy.mChangingConfigurations;
mTint = copy.mTint;
- mTintMode = copy.mTintMode;
+ mBlendMode = copy.mBlendMode;
mAutoMirrored = copy.mAutoMirrored;
mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
createNativeTreeFromCopy(copy, mRootGroup);
@@ -1026,7 +1041,7 @@ public class VectorDrawable extends Drawable {
if (!mCacheDirty
&& mCachedThemeAttrs == mThemeAttrs
&& mCachedTint == mTint
- && mCachedTintMode == mTintMode
+ && mCachedBlendMode == mBlendMode
&& mCachedAutoMirrored == mAutoMirrored) {
return true;
}
@@ -1039,7 +1054,7 @@ public class VectorDrawable extends Drawable {
// likely hit cache miss more, but practically not much difference.
mCachedThemeAttrs = mThemeAttrs;
mCachedTint = mTint;
- mCachedTintMode = mTintMode;
+ mCachedBlendMode = mBlendMode;
mCachedAutoMirrored = mAutoMirrored;
mCacheDirty = false;
}