Skip to content

Commit 29d0aa7

Browse files
Romain GuyAndroid (Google) Code Review
authored andcommitted
Merge "Compute GradientDrawable's opacity correctly" into jb-mr1-dev
2 parents ad79342 + e91aa0f commit 29d0aa7

File tree

3 files changed

+51
-17
lines changed

3 files changed

+51
-17
lines changed

graphics/java/android/graphics/drawable/Drawable.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import android.util.StateSet;
3838
import android.util.TypedValue;
3939
import android.util.Xml;
40-
import android.view.View;
4140

4241
import java.io.IOException;
4342
import java.io.InputStream;

graphics/java/android/graphics/drawable/DrawableContainer.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,6 @@ public abstract static class DrawableContainerState extends ConstantState {
444444
int mConstantMinimumWidth;
445445
int mConstantMinimumHeight;
446446

447-
boolean mHaveOpacity = false;
448447
int mOpacity;
449448

450449
boolean mHaveStateful = false;
@@ -493,7 +492,6 @@ public abstract static class DrawableContainerState extends ConstantState {
493492
mConstantWidth = orig.mConstantWidth;
494493
mConstantHeight = orig.mConstantHeight;
495494

496-
mHaveOpacity = orig.mHaveOpacity;
497495
mOpacity = orig.mOpacity;
498496
mHaveStateful = orig.mHaveStateful;
499497
mStateful = orig.mStateful;
@@ -528,7 +526,6 @@ public final int addChild(Drawable dr) {
528526
mDrawables[pos] = dr;
529527
mNumChildren++;
530528
mChildrenChangingConfigurations |= dr.getChangingConfigurations();
531-
mHaveOpacity = false;
532529
mHaveStateful = false;
533530

534531
mConstantPadding = null;
@@ -656,18 +653,13 @@ public final int getExitFadeDuration() {
656653
}
657654

658655
public final int getOpacity() {
659-
if (mHaveOpacity) {
660-
return mOpacity;
661-
}
662-
663656
final int N = getChildCount();
664657
final Drawable[] drawables = mDrawables;
665658
int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
666659
for (int i = 1; i < N; i++) {
667660
op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
668661
}
669662
mOpacity = op;
670-
mHaveOpacity = true;
671663
return op;
672664
}
673665

graphics/java/android/graphics/drawable/GradientDrawable.java

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,8 @@ public void draw(Canvas canvas) {
435435
final int currFillAlpha = modulateAlpha(prevFillAlpha);
436436
final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha);
437437

438-
final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint.getStrokeWidth() > 0;
438+
final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null &&
439+
mStrokePaint.getStrokeWidth() > 0;
439440
final boolean haveFill = currFillAlpha > 0;
440441
final GradientState st = mGradientState;
441442
/* we need a layer iff we're drawing both a fill and stroke, and the
@@ -603,9 +604,9 @@ private Path buildRing(GradientState st) {
603604

604605
/**
605606
* <p>Changes this drawbale to use a single color instead of a gradient.</p>
606-
* <p><strong>Note</strong>: changing orientation will affect all instances
607+
* <p><strong>Note</strong>: changing color will affect all instances
607608
* of a drawable loaded from a resource. It is recommended to invoke
608-
* {@link #mutate()} before changing the orientation.</p>
609+
* {@link #mutate()} before changing the color.</p>
609610
*
610611
* @param argb The color used to fill the shape
611612
*
@@ -649,7 +650,7 @@ public void setColorFilter(ColorFilter cf) {
649650

650651
@Override
651652
public int getOpacity() {
652-
return PixelFormat.TRANSLUCENT;
653+
return mGradientState.mOpaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
653654
}
654655

655656
@Override
@@ -1011,7 +1012,10 @@ public void inflate(Resources r, XmlPullParser parser,
10111012
} else {
10121013
Log.w("drawable", "Bad element under <shape>: " + name);
10131014
}
1015+
10141016
}
1017+
1018+
mGradientState.computeOpacity();
10151019
}
10161020

10171021
private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) {
@@ -1079,10 +1083,11 @@ final static class GradientState extends ConstantState {
10791083
private float mGradientRadius = 0.5f;
10801084
private boolean mUseLevel;
10811085
private boolean mUseLevelForShape;
1086+
private boolean mOpaque;
10821087

10831088
GradientState(Orientation orientation, int[] colors) {
10841089
mOrientation = orientation;
1085-
mColors = colors;
1090+
setColors(colors);
10861091
}
10871092

10881093
public GradientState(GradientState state) {
@@ -1120,6 +1125,7 @@ public GradientState(GradientState state) {
11201125
mGradientRadius = state.mGradientRadius;
11211126
mUseLevel = state.mUseLevel;
11221127
mUseLevelForShape = state.mUseLevelForShape;
1128+
mOpaque = state.mOpaque;
11231129
}
11241130

11251131
@Override
@@ -1139,6 +1145,7 @@ public int getChangingConfigurations() {
11391145

11401146
public void setShape(int shape) {
11411147
mShape = shape;
1148+
computeOpacity();
11421149
}
11431150

11441151
public void setGradientType(int gradient) {
@@ -1153,24 +1160,60 @@ public void setGradientCenter(float x, float y) {
11531160
public void setColors(int[] colors) {
11541161
mHasSolidColor = false;
11551162
mColors = colors;
1163+
computeOpacity();
11561164
}
11571165

11581166
public void setSolidColor(int argb) {
11591167
mHasSolidColor = true;
11601168
mSolidColor = argb;
11611169
mColors = null;
1170+
computeOpacity();
1171+
}
1172+
1173+
private void computeOpacity() {
1174+
if (mShape != RECTANGLE) {
1175+
mOpaque = false;
1176+
return;
1177+
}
1178+
1179+
if (mStrokeWidth > 0 && !isOpaque(mStrokeColor)) {
1180+
mOpaque = false;
1181+
return;
1182+
}
1183+
1184+
if (mHasSolidColor) {
1185+
mOpaque = isOpaque(mSolidColor);
1186+
return;
1187+
}
1188+
1189+
if (mColors != null) {
1190+
for (int i = 0; i < mColors.length; i++) {
1191+
if (!isOpaque(mColors[i])) {
1192+
mOpaque = false;
1193+
return;
1194+
}
1195+
}
1196+
}
1197+
1198+
mOpaque = true;
1199+
}
1200+
1201+
private static boolean isOpaque(int color) {
1202+
return ((color >> 24) & 0xff) == 0xff;
11621203
}
11631204

11641205
public void setStroke(int width, int color) {
11651206
mStrokeWidth = width;
11661207
mStrokeColor = color;
1208+
computeOpacity();
11671209
}
1168-
1210+
11691211
public void setStroke(int width, int color, float dashWidth, float dashGap) {
11701212
mStrokeWidth = width;
11711213
mStrokeColor = color;
11721214
mStrokeDashWidth = dashWidth;
11731215
mStrokeDashGap = dashGap;
1216+
computeOpacity();
11741217
}
11751218

11761219
public void setCornerRadius(float radius) {
@@ -1180,14 +1223,14 @@ public void setCornerRadius(float radius) {
11801223
mRadius = radius;
11811224
mRadiusArray = null;
11821225
}
1183-
1226+
11841227
public void setCornerRadii(float[] radii) {
11851228
mRadiusArray = radii;
11861229
if (radii == null) {
11871230
mRadius = 0;
11881231
}
11891232
}
1190-
1233+
11911234
public void setSize(int width, int height) {
11921235
mWidth = width;
11931236
mHeight = height;

0 commit comments

Comments
 (0)