Loading core/res/res/values/attrs.xml +6 −0 Original line number Diff line number Diff line Loading @@ -4869,6 +4869,12 @@ <attr name="thickness" format="dimension" /> <!-- Indicates whether the drawable's level affects the way the gradient is drawn. --> <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> <!-- Used to specify the size of the shape for GradientDrawable. --> Loading graphics/java/android/graphics/drawable/GradientDrawable.java +50 −8 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ 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; Loading Loading @@ -134,6 +136,7 @@ public class GradientDrawable extends Drawable { private Rect mPadding; private Paint mStrokePaint; // 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 final Path mPath = new Path(); Loading Loading @@ -523,13 +526,15 @@ public class GradientDrawable extends Drawable { mStrokePaint.getStrokeWidth() > 0; final boolean haveFill = currFillAlpha > 0; 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 stroke is non-opaque, and our shapetype actually supports fill+stroke. Otherwise we can just draw the stroke (if any) on top of the fill (if any) without worrying about blending artifacts. */ 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 allows us to apply paint effects like alpha and colorfilter to Loading @@ -544,7 +549,7 @@ public class GradientDrawable extends Drawable { } mLayerPaint.setDither(st.mDither); mLayerPaint.setAlpha(mAlpha); mLayerPaint.setColorFilter(mColorFilter); mLayerPaint.setColorFilter(colorFilter); float rad = mStrokePaint.getStrokeWidth(); canvas.saveLayer(mRect.left - rad, mRect.top - rad, Loading @@ -561,14 +566,14 @@ public class GradientDrawable extends Drawable { */ mFillPaint.setAlpha(currFillAlpha); mFillPaint.setDither(st.mDither); mFillPaint.setColorFilter(mColorFilter); if (mColorFilter != null && st.mColorStateList == null) { mFillPaint.setColorFilter(colorFilter); if (colorFilter != null && st.mColorStateList == null) { mFillPaint.setColor(mAlpha << 24); } if (haveStroke) { mStrokePaint.setAlpha(currStrokeAlpha); mStrokePaint.setDither(st.mDither); mStrokePaint.setColorFilter(mColorFilter); mStrokePaint.setColorFilter(colorFilter); } } Loading @@ -593,7 +598,7 @@ public class GradientDrawable extends Drawable { canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); } } else { if (mFillPaint.getColor() != 0 || mColorFilter != null || if (mFillPaint.getColor() != 0 || colorFilter != null || mFillPaint.getShader() != null) { canvas.drawRect(mRect, mFillPaint); } Loading Loading @@ -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) { invalidateSelf(); return true; Loading @@ -781,7 +791,8 @@ public class GradientDrawable extends Drawable { final GradientState s = mGradientState; return super.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 Loading Loading @@ -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 public int getOpacity() { return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ? Loading Loading @@ -1045,6 +1070,18 @@ public class GradientDrawable extends Drawable { state.mUseLevelForShape = a.getBoolean( 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 Loading Loading @@ -1522,6 +1559,9 @@ public class GradientDrawable extends Drawable { private boolean mOpaqueOverBounds; private boolean mOpaqueOverShape; ColorStateList mTint = null; PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; int[] mThemeAttrs; int[] mAttrSize; int[] mAttrGradient; Loading Loading @@ -1574,6 +1614,8 @@ public class GradientDrawable extends Drawable { mUseLevelForShape = state.mUseLevelForShape; mOpaqueOverBounds = state.mOpaqueOverBounds; mOpaqueOverShape = state.mOpaqueOverShape; mTint = state.mTint; mTintMode = state.mTintMode; mThemeAttrs = state.mThemeAttrs; mAttrSize = state.mAttrSize; mAttrGradient = state.mAttrGradient; Loading Loading
core/res/res/values/attrs.xml +6 −0 Original line number Diff line number Diff line Loading @@ -4869,6 +4869,12 @@ <attr name="thickness" format="dimension" /> <!-- Indicates whether the drawable's level affects the way the gradient is drawn. --> <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> <!-- Used to specify the size of the shape for GradientDrawable. --> Loading
graphics/java/android/graphics/drawable/GradientDrawable.java +50 −8 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ 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; Loading Loading @@ -134,6 +136,7 @@ public class GradientDrawable extends Drawable { private Rect mPadding; private Paint mStrokePaint; // 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 final Path mPath = new Path(); Loading Loading @@ -523,13 +526,15 @@ public class GradientDrawable extends Drawable { mStrokePaint.getStrokeWidth() > 0; final boolean haveFill = currFillAlpha > 0; 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 stroke is non-opaque, and our shapetype actually supports fill+stroke. Otherwise we can just draw the stroke (if any) on top of the fill (if any) without worrying about blending artifacts. */ 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 allows us to apply paint effects like alpha and colorfilter to Loading @@ -544,7 +549,7 @@ public class GradientDrawable extends Drawable { } mLayerPaint.setDither(st.mDither); mLayerPaint.setAlpha(mAlpha); mLayerPaint.setColorFilter(mColorFilter); mLayerPaint.setColorFilter(colorFilter); float rad = mStrokePaint.getStrokeWidth(); canvas.saveLayer(mRect.left - rad, mRect.top - rad, Loading @@ -561,14 +566,14 @@ public class GradientDrawable extends Drawable { */ mFillPaint.setAlpha(currFillAlpha); mFillPaint.setDither(st.mDither); mFillPaint.setColorFilter(mColorFilter); if (mColorFilter != null && st.mColorStateList == null) { mFillPaint.setColorFilter(colorFilter); if (colorFilter != null && st.mColorStateList == null) { mFillPaint.setColor(mAlpha << 24); } if (haveStroke) { mStrokePaint.setAlpha(currStrokeAlpha); mStrokePaint.setDither(st.mDither); mStrokePaint.setColorFilter(mColorFilter); mStrokePaint.setColorFilter(colorFilter); } } Loading @@ -593,7 +598,7 @@ public class GradientDrawable extends Drawable { canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); } } else { if (mFillPaint.getColor() != 0 || mColorFilter != null || if (mFillPaint.getColor() != 0 || colorFilter != null || mFillPaint.getShader() != null) { canvas.drawRect(mRect, mFillPaint); } Loading Loading @@ -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) { invalidateSelf(); return true; Loading @@ -781,7 +791,8 @@ public class GradientDrawable extends Drawable { final GradientState s = mGradientState; return super.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 Loading Loading @@ -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 public int getOpacity() { return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ? Loading Loading @@ -1045,6 +1070,18 @@ public class GradientDrawable extends Drawable { state.mUseLevelForShape = a.getBoolean( 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 Loading Loading @@ -1522,6 +1559,9 @@ public class GradientDrawable extends Drawable { private boolean mOpaqueOverBounds; private boolean mOpaqueOverShape; ColorStateList mTint = null; PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; int[] mThemeAttrs; int[] mAttrSize; int[] mAttrGradient; Loading Loading @@ -1574,6 +1614,8 @@ public class GradientDrawable extends Drawable { mUseLevelForShape = state.mUseLevelForShape; mOpaqueOverBounds = state.mOpaqueOverBounds; mOpaqueOverShape = state.mOpaqueOverShape; mTint = state.mTint; mTintMode = state.mTintMode; mThemeAttrs = state.mThemeAttrs; mAttrSize = state.mAttrSize; mAttrGradient = state.mAttrGradient; Loading