Merge "Compute GradientDrawable's opacity correctly" into jb-mr1-dev

This commit is contained in:
Romain Guy
2012-09-18 15:39:29 -07:00
committed by Android (Google) Code Review
3 changed files with 51 additions and 17 deletions

View File

@@ -37,7 +37,6 @@ import android.util.DisplayMetrics;
import android.util.StateSet; import android.util.StateSet;
import android.util.TypedValue; import android.util.TypedValue;
import android.util.Xml; import android.util.Xml;
import android.view.View;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;

View File

@@ -444,7 +444,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
int mConstantMinimumWidth; int mConstantMinimumWidth;
int mConstantMinimumHeight; int mConstantMinimumHeight;
boolean mHaveOpacity = false;
int mOpacity; int mOpacity;
boolean mHaveStateful = false; boolean mHaveStateful = false;
@@ -493,7 +492,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mConstantWidth = orig.mConstantWidth; mConstantWidth = orig.mConstantWidth;
mConstantHeight = orig.mConstantHeight; mConstantHeight = orig.mConstantHeight;
mHaveOpacity = orig.mHaveOpacity;
mOpacity = orig.mOpacity; mOpacity = orig.mOpacity;
mHaveStateful = orig.mHaveStateful; mHaveStateful = orig.mHaveStateful;
mStateful = orig.mStateful; mStateful = orig.mStateful;
@@ -528,7 +526,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mDrawables[pos] = dr; mDrawables[pos] = dr;
mNumChildren++; mNumChildren++;
mChildrenChangingConfigurations |= dr.getChangingConfigurations(); mChildrenChangingConfigurations |= dr.getChangingConfigurations();
mHaveOpacity = false;
mHaveStateful = false; mHaveStateful = false;
mConstantPadding = null; mConstantPadding = null;
@@ -656,10 +653,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
} }
public final int getOpacity() { public final int getOpacity() {
if (mHaveOpacity) {
return mOpacity;
}
final int N = getChildCount(); final int N = getChildCount();
final Drawable[] drawables = mDrawables; final Drawable[] drawables = mDrawables;
int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
@@ -667,7 +660,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
} }
mOpacity = op; mOpacity = op;
mHaveOpacity = true;
return op; return op;
} }

View File

@@ -435,7 +435,8 @@ public class GradientDrawable extends Drawable {
final int currFillAlpha = modulateAlpha(prevFillAlpha); final int currFillAlpha = modulateAlpha(prevFillAlpha);
final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha); final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha);
final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint.getStrokeWidth() > 0; final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null &&
mStrokePaint.getStrokeWidth() > 0;
final boolean haveFill = currFillAlpha > 0; final boolean haveFill = currFillAlpha > 0;
final GradientState st = mGradientState; final GradientState st = mGradientState;
/* 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
@@ -603,9 +604,9 @@ public class GradientDrawable extends Drawable {
/** /**
* <p>Changes this drawbale to use a single color instead of a gradient.</p> * <p>Changes this drawbale to use a single color instead of a gradient.</p>
* <p><strong>Note</strong>: changing orientation will affect all instances * <p><strong>Note</strong>: changing color will affect all instances
* of a drawable loaded from a resource. It is recommended to invoke * of a drawable loaded from a resource. It is recommended to invoke
* {@link #mutate()} before changing the orientation.</p> * {@link #mutate()} before changing the color.</p>
* *
* @param argb The color used to fill the shape * @param argb The color used to fill the shape
* *
@@ -649,7 +650,7 @@ public class GradientDrawable extends Drawable {
@Override @Override
public int getOpacity() { public int getOpacity() {
return PixelFormat.TRANSLUCENT; return mGradientState.mOpaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
} }
@Override @Override
@@ -1011,7 +1012,10 @@ public class GradientDrawable extends Drawable {
} else { } else {
Log.w("drawable", "Bad element under <shape>: " + name); Log.w("drawable", "Bad element under <shape>: " + name);
} }
} }
mGradientState.computeOpacity();
} }
private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) { private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) {
@@ -1079,10 +1083,11 @@ public class GradientDrawable extends Drawable {
private float mGradientRadius = 0.5f; private float mGradientRadius = 0.5f;
private boolean mUseLevel; private boolean mUseLevel;
private boolean mUseLevelForShape; private boolean mUseLevelForShape;
private boolean mOpaque;
GradientState(Orientation orientation, int[] colors) { GradientState(Orientation orientation, int[] colors) {
mOrientation = orientation; mOrientation = orientation;
mColors = colors; setColors(colors);
} }
public GradientState(GradientState state) { public GradientState(GradientState state) {
@@ -1120,6 +1125,7 @@ public class GradientDrawable extends Drawable {
mGradientRadius = state.mGradientRadius; mGradientRadius = state.mGradientRadius;
mUseLevel = state.mUseLevel; mUseLevel = state.mUseLevel;
mUseLevelForShape = state.mUseLevelForShape; mUseLevelForShape = state.mUseLevelForShape;
mOpaque = state.mOpaque;
} }
@Override @Override
@@ -1139,6 +1145,7 @@ public class GradientDrawable extends Drawable {
public void setShape(int shape) { public void setShape(int shape) {
mShape = shape; mShape = shape;
computeOpacity();
} }
public void setGradientType(int gradient) { public void setGradientType(int gradient) {
@@ -1153,24 +1160,60 @@ public class GradientDrawable extends Drawable {
public void setColors(int[] colors) { public void setColors(int[] colors) {
mHasSolidColor = false; mHasSolidColor = false;
mColors = colors; mColors = colors;
computeOpacity();
} }
public void setSolidColor(int argb) { public void setSolidColor(int argb) {
mHasSolidColor = true; mHasSolidColor = true;
mSolidColor = argb; mSolidColor = argb;
mColors = null; mColors = null;
computeOpacity();
}
private void computeOpacity() {
if (mShape != RECTANGLE) {
mOpaque = false;
return;
}
if (mStrokeWidth > 0 && !isOpaque(mStrokeColor)) {
mOpaque = false;
return;
}
if (mHasSolidColor) {
mOpaque = isOpaque(mSolidColor);
return;
}
if (mColors != null) {
for (int i = 0; i < mColors.length; i++) {
if (!isOpaque(mColors[i])) {
mOpaque = false;
return;
}
}
}
mOpaque = true;
}
private static boolean isOpaque(int color) {
return ((color >> 24) & 0xff) == 0xff;
} }
public void setStroke(int width, int color) { public void setStroke(int width, int color) {
mStrokeWidth = width; mStrokeWidth = width;
mStrokeColor = color; mStrokeColor = color;
computeOpacity();
} }
public void setStroke(int width, int color, float dashWidth, float dashGap) { public void setStroke(int width, int color, float dashWidth, float dashGap) {
mStrokeWidth = width; mStrokeWidth = width;
mStrokeColor = color; mStrokeColor = color;
mStrokeDashWidth = dashWidth; mStrokeDashWidth = dashWidth;
mStrokeDashGap = dashGap; mStrokeDashGap = dashGap;
computeOpacity();
} }
public void setCornerRadius(float radius) { public void setCornerRadius(float radius) {
@@ -1180,14 +1223,14 @@ public class GradientDrawable extends Drawable {
mRadius = radius; mRadius = radius;
mRadiusArray = null; mRadiusArray = null;
} }
public void setCornerRadii(float[] radii) { public void setCornerRadii(float[] radii) {
mRadiusArray = radii; mRadiusArray = radii;
if (radii == null) { if (radii == null) {
mRadius = 0; mRadius = 0;
} }
} }
public void setSize(int width, int height) { public void setSize(int width, int height) {
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;