am d9a2b99d: am 42e96769: Merge "Add support for tint and tintMode to GradientDrawable" into lmp-mr1-dev

* commit 'd9a2b99de201c89b1b6c58eae213bb15bef58168':
  Add support for tint and tintMode to GradientDrawable
This commit is contained in:
Alan Viverette
2014-10-14 17:50:34 +00:00
committed by Android Git Automerger
2 changed files with 56 additions and 8 deletions

View File

@@ -4869,6 +4869,12 @@
<attr name="thickness" format="dimension" /> <attr name="thickness" format="dimension" />
<!-- Indicates whether the drawable's level affects the way the gradient is drawn. --> <!-- Indicates whether the drawable's level affects the way the gradient is drawn. -->
<attr name="useLevel" /> <attr name="useLevel" />
<!-- If set, specifies the color to apply to the drawable as a tint. By default,
no tint is applied. May be a color state list. -->
<attr name="tint" />
<!-- When a tint color is set, specifies its Porter-Duff blending mode. The
default value is src_in, which treats the drawable as an alpha mask. -->
<attr name="tintMode" />
</declare-styleable> </declare-styleable>
<!-- Used to specify the size of the shape for GradientDrawable. --> <!-- Used to specify the size of the shape for GradientDrawable. -->

View File

@@ -29,6 +29,8 @@ import android.graphics.Outline;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RadialGradient; import android.graphics.RadialGradient;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
@@ -134,6 +136,7 @@ public class GradientDrawable extends Drawable {
private Rect mPadding; private Rect mPadding;
private Paint mStrokePaint; // optional, set by the caller private Paint mStrokePaint; // optional, set by the caller
private ColorFilter mColorFilter; // optional, set by the caller private ColorFilter mColorFilter; // optional, set by the caller
private PorterDuffColorFilter mTintFilter;
private int mAlpha = 0xFF; // modified by the caller private int mAlpha = 0xFF; // modified by the caller
private final Path mPath = new Path(); private final Path mPath = new Path();
@@ -523,13 +526,15 @@ public class GradientDrawable extends Drawable {
mStrokePaint.getStrokeWidth() > 0; mStrokePaint.getStrokeWidth() > 0;
final boolean haveFill = currFillAlpha > 0; final boolean haveFill = currFillAlpha > 0;
final GradientState st = mGradientState; final GradientState st = mGradientState;
final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter;
/* we need a layer iff we're drawing both a fill and stroke, and the /* we need a layer iff we're drawing both a fill and stroke, and the
stroke is non-opaque, and our shapetype actually supports stroke is non-opaque, and our shapetype actually supports
fill+stroke. Otherwise we can just draw the stroke (if any) on top fill+stroke. Otherwise we can just draw the stroke (if any) on top
of the fill (if any) without worrying about blending artifacts. of the fill (if any) without worrying about blending artifacts.
*/ */
final boolean useLayer = haveStroke && haveFill && st.mShape != LINE && final boolean useLayer = haveStroke && haveFill && st.mShape != LINE &&
currStrokeAlpha < 255 && (mAlpha < 255 || mColorFilter != null); currStrokeAlpha < 255 && (mAlpha < 255 || colorFilter != null);
/* Drawing with a layer is slower than direct drawing, but it /* Drawing with a layer is slower than direct drawing, but it
allows us to apply paint effects like alpha and colorfilter to allows us to apply paint effects like alpha and colorfilter to
@@ -544,7 +549,7 @@ public class GradientDrawable extends Drawable {
} }
mLayerPaint.setDither(st.mDither); mLayerPaint.setDither(st.mDither);
mLayerPaint.setAlpha(mAlpha); mLayerPaint.setAlpha(mAlpha);
mLayerPaint.setColorFilter(mColorFilter); mLayerPaint.setColorFilter(colorFilter);
float rad = mStrokePaint.getStrokeWidth(); float rad = mStrokePaint.getStrokeWidth();
canvas.saveLayer(mRect.left - rad, mRect.top - rad, canvas.saveLayer(mRect.left - rad, mRect.top - rad,
@@ -561,14 +566,14 @@ public class GradientDrawable extends Drawable {
*/ */
mFillPaint.setAlpha(currFillAlpha); mFillPaint.setAlpha(currFillAlpha);
mFillPaint.setDither(st.mDither); mFillPaint.setDither(st.mDither);
mFillPaint.setColorFilter(mColorFilter); mFillPaint.setColorFilter(colorFilter);
if (mColorFilter != null && st.mColorStateList == null) { if (colorFilter != null && st.mColorStateList == null) {
mFillPaint.setColor(mAlpha << 24); mFillPaint.setColor(mAlpha << 24);
} }
if (haveStroke) { if (haveStroke) {
mStrokePaint.setAlpha(currStrokeAlpha); mStrokePaint.setAlpha(currStrokeAlpha);
mStrokePaint.setDither(st.mDither); mStrokePaint.setDither(st.mDither);
mStrokePaint.setColorFilter(mColorFilter); mStrokePaint.setColorFilter(colorFilter);
} }
} }
@@ -593,7 +598,7 @@ public class GradientDrawable extends Drawable {
canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); canvas.drawRoundRect(mRect, rad, rad, mStrokePaint);
} }
} else { } else {
if (mFillPaint.getColor() != 0 || mColorFilter != null || if (mFillPaint.getColor() != 0 || colorFilter != null ||
mFillPaint.getShader() != null) { mFillPaint.getShader() != null) {
canvas.drawRect(mRect, mFillPaint); canvas.drawRect(mRect, mFillPaint);
} }
@@ -768,6 +773,11 @@ public class GradientDrawable extends Drawable {
} }
} }
if (s.mTint != null && s.mTintMode != null) {
mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode);
invalidateSelf = true;
}
if (invalidateSelf) { if (invalidateSelf) {
invalidateSelf(); invalidateSelf();
return true; return true;
@@ -781,7 +791,8 @@ public class GradientDrawable extends Drawable {
final GradientState s = mGradientState; final GradientState s = mGradientState;
return super.isStateful() return super.isStateful()
|| (s.mColorStateList != null && s.mColorStateList.isStateful()) || (s.mColorStateList != null && s.mColorStateList.isStateful())
|| (s.mStrokeColorStateList != null && s.mStrokeColorStateList.isStateful()); || (s.mStrokeColorStateList != null && s.mStrokeColorStateList.isStateful())
|| (s.mTint != null && s.mTint.isStateful());
} }
@Override @Override
@@ -823,6 +834,20 @@ public class GradientDrawable extends Drawable {
} }
} }
@Override
public void setTintList(ColorStateList tint) {
mGradientState.mTint = tint;
mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode);
invalidateSelf();
}
@Override
public void setTintMode(PorterDuff.Mode tintMode) {
mGradientState.mTintMode = tintMode;
mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode);
invalidateSelf();
}
@Override @Override
public int getOpacity() { public int getOpacity() {
return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ? return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ?
@@ -1045,6 +1070,18 @@ public class GradientDrawable extends Drawable {
state.mUseLevelForShape = a.getBoolean( state.mUseLevelForShape = a.getBoolean(
R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape); R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape);
} }
final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1);
if (tintMode != -1) {
state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint);
if (tint != null) {
state.mTint = tint;
}
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
} }
@Override @Override
@@ -1522,6 +1559,9 @@ public class GradientDrawable extends Drawable {
private boolean mOpaqueOverBounds; private boolean mOpaqueOverBounds;
private boolean mOpaqueOverShape; private boolean mOpaqueOverShape;
ColorStateList mTint = null;
PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
int[] mThemeAttrs; int[] mThemeAttrs;
int[] mAttrSize; int[] mAttrSize;
int[] mAttrGradient; int[] mAttrGradient;
@@ -1574,6 +1614,8 @@ public class GradientDrawable extends Drawable {
mUseLevelForShape = state.mUseLevelForShape; mUseLevelForShape = state.mUseLevelForShape;
mOpaqueOverBounds = state.mOpaqueOverBounds; mOpaqueOverBounds = state.mOpaqueOverBounds;
mOpaqueOverShape = state.mOpaqueOverShape; mOpaqueOverShape = state.mOpaqueOverShape;
mTint = state.mTint;
mTintMode = state.mTintMode;
mThemeAttrs = state.mThemeAttrs; mThemeAttrs = state.mThemeAttrs;
mAttrSize = state.mAttrSize; mAttrSize = state.mAttrSize;
mAttrGradient = state.mAttrGradient; mAttrGradient = state.mAttrGradient;