summaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'graphics')
-rw-r--r--graphics/java/android/graphics/Canvas.java13
-rw-r--r--graphics/java/android/graphics/Paint.java26
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java9
-rw-r--r--graphics/java/android/graphics/drawable/ColorDrawable.java5
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java6
-rw-r--r--graphics/java/android/graphics/drawable/DrawableWrapper.java5
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java158
-rw-r--r--graphics/java/android/graphics/drawable/InsetDrawable.java14
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java245
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java7
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java8
-rw-r--r--graphics/java/android/graphics/drawable/RotateDrawable.java3
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java14
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java50
-rw-r--r--graphics/java/android/graphics/pdf/PdfRenderer.java4
17 files changed, 371 insertions, 200 deletions
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 150f195..48afcbf 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -45,6 +45,8 @@ import javax.microedition.khronos.opengles.GL;
* Canvas and Drawables</a> developer guide.</p></div>
*/
public class Canvas {
+ /** @hide */
+ public static boolean sCompatibilityRestore = false;
/**
* Should only be assigned in constructors (or setBitmap if software canvas),
@@ -557,7 +559,8 @@ public class Canvas {
* an error to call restore() more times than save() was called.
*/
public void restore() {
- native_restore(mNativeCanvasWrapper);
+ boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated();
+ native_restore(mNativeCanvasWrapper, throwOnUnderflow);
}
/**
@@ -582,7 +585,8 @@ public class Canvas {
* @param saveCount The save level to restore to.
*/
public void restoreToCount(int saveCount) {
- native_restoreToCount(mNativeCanvasWrapper, saveCount);
+ boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated();
+ native_restoreToCount(mNativeCanvasWrapper, saveCount, throwOnUnderflow);
}
/**
@@ -1988,9 +1992,10 @@ public class Canvas {
private static native int native_saveLayerAlpha(long nativeCanvas, float l,
float t, float r, float b,
int alpha, int layerFlags);
- private static native void native_restore(long canvasHandle);
+ private static native void native_restore(long canvasHandle, boolean tolerateUnderflow);
private static native void native_restoreToCount(long canvasHandle,
- int saveCount);
+ int saveCount,
+ boolean tolerateUnderflow);
private static native int native_getSaveCount(long canvasHandle);
private static native void native_translate(long canvasHandle,
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 1da198c..cd5f59d 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -2120,9 +2120,9 @@ public class Paint {
int contextLen = contextEnd - contextStart;
char[] buf = TemporaryBuffer.obtain(contextLen);
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
- int result = getTextRunCursor(buf, 0, contextLen, dir, offset - contextStart, cursorOpt);
+ int relPos = getTextRunCursor(buf, 0, contextLen, dir, offset - contextStart, cursorOpt);
TemporaryBuffer.recycle(buf);
- return result;
+ return (relPos == -1) ? -1 : relPos + contextStart;
}
/**
@@ -2249,6 +2249,26 @@ public class Paint {
bounds);
}
+ /**
+ * Determine whether the typeface set on the paint has a glyph supporting the string. The
+ * simplest case is when the string contains a single character, in which this method
+ * determines whether the font has the character. In the case of multiple characters, the
+ * method returns true if there is a single glyph representing the ligature. For example, if
+ * the input is a pair of regional indicator symbols, determine whether there is an emoji flag
+ * for the pair.
+ *
+ * Finally, if the string contains a variation selector, the method only returns true if
+ * the fonts contains a glyph specific to that variation.
+ *
+ * Checking is done on the entire fallback chain, not just the immediate font referenced.
+ *
+ * @param string the string to test whether there is glyph support
+ * @return true if the typeface has a glyph for the string
+ */
+ public boolean hasGlyph(String string) {
+ return native_hasGlyph(mNativePaint, mNativeTypeface, mBidiFlags, string);
+ }
+
@Override
protected void finalize() throws Throwable {
try {
@@ -2334,4 +2354,6 @@ public class Paint {
String settings);
private static native int native_getHyphenEdit(long native_object);
private static native void native_setHyphenEdit(long native_object, int hyphen);
+ private static native boolean native_hasGlyph(long native_object, long native_typeface,
+ int bidiFlags, String string);
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index a56e87e..28c26ff 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -173,7 +173,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations() | mAnimatedVectorState.mChangingConfigurations;
+ return super.getChangingConfigurations() | mAnimatedVectorState.getChangingConfigurations();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index dc10a81..6fe6b56 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -454,7 +454,7 @@ public class BitmapDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations() | mBitmapState.mChangingConfigurations;
+ return super.getChangingConfigurations() | mBitmapState.getChangingConfigurations();
}
private boolean needMirroring() {
@@ -834,7 +834,7 @@ public class BitmapDrawable extends Drawable {
// Apply theme to contained color state list.
if (state.mTint != null && state.mTint.canApplyTheme()) {
- state.mTint.applyTheme(t);
+ state.mTint = state.mTint.obtainForTheme(t);
}
// Update local properties.
@@ -882,7 +882,7 @@ public class BitmapDrawable extends Drawable {
@Override
public final ConstantState getConstantState() {
- mBitmapState.mChangingConfigurations = getChangingConfigurations();
+ mBitmapState.mChangingConfigurations |= getChangingConfigurations();
return mBitmapState;
}
@@ -950,7 +950,8 @@ public class BitmapDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations
+ | (mTint != null ? mTint.getChangingConfigurations() : 0);
}
}
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index f75ab36..8e91621 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -276,7 +276,7 @@ public class ColorDrawable extends Drawable {
}
if (state.mTint != null && state.mTint.canApplyTheme()) {
- state.mTint.applyTheme(t);
+ state.mTint = state.mTint.obtainForTheme(t);
}
updateLocalState(t.getResources());
@@ -327,7 +327,8 @@ public class ColorDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations
+ | (mTint != null ? mTint.getChangingConfigurations() : 0);
}
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index e8b8c77..22ff3e7 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -572,7 +572,7 @@ public abstract class Drawable {
* 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 PorterDuff.Mode#MULTIPLY}.
+ * before it is drawn to screen. Default tint mode is {@link PorterDuff.Mode#SRC_IN}.
* </p>
* <p class="note"><strong>Note:</strong> Setting a color filter via
* {@link #setColorFilter(ColorFilter)} or
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index ddcb48b..b03fe3a 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -87,8 +87,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations()
- | mDrawableContainerState.mChangingConfigurations
- | mDrawableContainerState.mChildrenChangingConfigurations;
+ | mDrawableContainerState.getChangingConfigurations();
}
private boolean needsMirroring() {
@@ -865,6 +864,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
for (int i = 0; i < N; i++) {
if (drawables[i] != null && drawables[i].canApplyTheme()) {
drawables[i].applyTheme(theme);
+
+ // Update cached mask of child changing configurations.
+ mChildrenChangingConfigurations |= drawables[i].getChangingConfigurations();
}
}
}
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 1d6c60f..0da4275 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -180,8 +180,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations()
- | (mState != null ? mState.mChangingConfigurations : 0)
- | mDrawable.getChangingConfigurations();
+ | (mState != null ? mState.getChangingConfigurations() : 0);
}
@Override
@@ -433,7 +432,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations | mDrawableState.getChangingConfigurations();
}
public boolean canConstantState() {
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index eff152c..4c2817c 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -491,19 +491,21 @@ public class GradientDrawable extends Drawable {
}
/**
- * <p>Sets the colors used to draw the gradient. Each color is specified as an
- * ARGB integer and the array must contain at least 2 colors.</p>
- * <p><strong>Note</strong>: changing colors will affect all instances
- * of a drawable loaded from a resource. It is recommended to invoke
- * {@link #mutate()} before changing the colors.</p>
- *
- * @param colors 2 or more ARGB colors
+ * Sets the colors used to draw the gradient.
+ * <p>
+ * Each color is specified as an ARGB integer and the array must contain at
+ * least 2 colors.
+ * <p>
+ * <strong>Note</strong>: changing colors will affect all instances of a
+ * drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing the colors.
*
+ * @param colors an array containing 2 or more ARGB colors
* @see #mutate()
* @see #setColor(int)
*/
public void setColors(@ColorInt int[] colors) {
- mGradientState.setColors(colors);
+ mGradientState.setGradientColors(colors);
mGradientIsDirty = true;
invalidateSelf();
}
@@ -568,7 +570,7 @@ public class GradientDrawable extends Drawable {
mFillPaint.setAlpha(currFillAlpha);
mFillPaint.setDither(st.mDither);
mFillPaint.setColorFilter(colorFilter);
- if (colorFilter != null && st.mColorStateList == null) {
+ if (colorFilter != null && st.mSolidColors == null) {
mFillPaint.setColor(mAlpha << 24);
}
if (haveStroke) {
@@ -715,7 +717,7 @@ public class GradientDrawable extends Drawable {
* @see #setColors(int[])
*/
public void setColor(@ColorInt int argb) {
- mGradientState.setColorStateList(ColorStateList.valueOf(argb));
+ mGradientState.setSolidColors(ColorStateList.valueOf(argb));
mFillPaint.setColor(argb);
invalidateSelf();
}
@@ -734,7 +736,7 @@ public class GradientDrawable extends Drawable {
* @see #mutate()
*/
public void setColor(ColorStateList colorStateList) {
- mGradientState.setColorStateList(colorStateList);
+ mGradientState.setSolidColors(colorStateList);
final int color;
if (colorStateList == null) {
color = Color.TRANSPARENT;
@@ -751,9 +753,9 @@ public class GradientDrawable extends Drawable {
boolean invalidateSelf = false;
final GradientState s = mGradientState;
- final ColorStateList stateList = s.mColorStateList;
- if (stateList != null) {
- final int newColor = stateList.getColorForState(stateSet, 0);
+ final ColorStateList solidColors = s.mSolidColors;
+ if (solidColors != null) {
+ final int newColor = solidColors.getColorForState(stateSet, 0);
final int oldColor = mFillPaint.getColor();
if (oldColor != newColor) {
mFillPaint.setColor(newColor);
@@ -763,12 +765,12 @@ public class GradientDrawable extends Drawable {
final Paint strokePaint = mStrokePaint;
if (strokePaint != null) {
- final ColorStateList strokeStateList = s.mStrokeColorStateList;
- if (strokeStateList != null) {
- final int newStrokeColor = strokeStateList.getColorForState(stateSet, 0);
- final int oldStrokeColor = strokePaint.getColor();
- if (oldStrokeColor != newStrokeColor) {
- strokePaint.setColor(newStrokeColor);
+ final ColorStateList strokeColors = s.mStrokeColors;
+ if (strokeColors != null) {
+ final int newColor = strokeColors.getColorForState(stateSet, 0);
+ final int oldColor = strokePaint.getColor();
+ if (oldColor != newColor) {
+ strokePaint.setColor(newColor);
invalidateSelf = true;
}
}
@@ -791,14 +793,14 @@ public class GradientDrawable extends Drawable {
public boolean isStateful() {
final GradientState s = mGradientState;
return super.isStateful()
- || (s.mColorStateList != null && s.mColorStateList.isStateful())
- || (s.mStrokeColorStateList != null && s.mStrokeColorStateList.isStateful())
+ || (s.mSolidColors != null && s.mSolidColors.isStateful())
+ || (s.mStrokeColors != null && s.mStrokeColors.isStateful())
|| (s.mTint != null && s.mTint.isStateful());
}
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations() | mGradientState.mChangingConfigurations;
+ return super.getChangingConfigurations() | mGradientState.getChangingConfigurations();
}
@Override
@@ -899,10 +901,10 @@ public class GradientDrawable extends Drawable {
mRect.set(bounds.left + inset, bounds.top + inset,
bounds.right - inset, bounds.bottom - inset);
- final int[] colors = st.mColors;
- if (colors != null) {
- RectF r = mRect;
- float x0, x1, y0, y1;
+ final int[] gradientColors = st.mGradientColors;
+ if (gradientColors != null) {
+ final RectF r = mRect;
+ final float x0, x1, y0, y1;
if (st.mGradient == LINEAR_GRADIENT) {
final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f;
@@ -942,7 +944,7 @@ public class GradientDrawable extends Drawable {
}
mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1,
- colors, st.mPositions, Shader.TileMode.CLAMP));
+ gradientColors, st.mPositions, Shader.TileMode.CLAMP));
} else if (st.mGradient == RADIAL_GRADIENT) {
x0 = r.left + (r.right - r.left) * st.mCenterX;
y0 = r.top + (r.bottom - r.top) * st.mCenterY;
@@ -971,22 +973,22 @@ public class GradientDrawable extends Drawable {
}
mFillPaint.setShader(new RadialGradient(
- x0, y0, radius, colors, null, Shader.TileMode.CLAMP));
+ x0, y0, radius, gradientColors, null, Shader.TileMode.CLAMP));
} else if (st.mGradient == SWEEP_GRADIENT) {
x0 = r.left + (r.right - r.left) * st.mCenterX;
y0 = r.top + (r.bottom - r.top) * st.mCenterY;
- int[] tempColors = colors;
+ int[] tempColors = gradientColors;
float[] tempPositions = null;
if (st.mUseLevel) {
tempColors = st.mTempColors;
- final int length = colors.length;
+ final int length = gradientColors.length;
if (tempColors == null || tempColors.length != length + 1) {
tempColors = st.mTempColors = new int[length + 1];
}
- System.arraycopy(colors, 0, tempColors, 0, length);
- tempColors[length] = colors[length - 1];
+ System.arraycopy(gradientColors, 0, tempColors, 0, length);
+ tempColors[length] = gradientColors[length - 1];
tempPositions = st.mTempPositions;
final float fraction = 1.0f / (length - 1);
@@ -1006,7 +1008,7 @@ public class GradientDrawable extends Drawable {
// If we don't have a solid color, the alpha channel must be
// maxed out so that alpha modulation works correctly.
- if (st.mColorStateList == null) {
+ if (st.mSolidColors == null) {
mFillPaint.setColor(Color.BLACK);
}
}
@@ -1044,15 +1046,15 @@ public class GradientDrawable extends Drawable {
}
if (state.mTint != null && state.mTint.canApplyTheme()) {
- state.mTint.applyTheme(t);
+ state.mTint = state.mTint.obtainForTheme(t);
}
- if (state.mColorStateList != null && state.mColorStateList.canApplyTheme()) {
- state.mColorStateList.applyTheme(t);
+ if (state.mSolidColors != null && state.mSolidColors.canApplyTheme()) {
+ state.mSolidColors = state.mSolidColors.obtainForTheme(t);
}
- if (state.mStrokeColorStateList != null && state.mStrokeColorStateList.canApplyTheme()) {
- state.mStrokeColorStateList.applyTheme(t);
+ if (state.mStrokeColors != null && state.mStrokeColors.canApplyTheme()) {
+ state.mStrokeColors = state.mStrokeColors.obtainForTheme(t);
}
applyThemeChildElements(t);
@@ -1288,7 +1290,7 @@ public class GradientDrawable extends Drawable {
ColorStateList colorStateList = a.getColorStateList(
R.styleable.GradientDrawableStroke_color);
if (colorStateList == null) {
- colorStateList = st.mStrokeColorStateList;
+ colorStateList = st.mStrokeColors;
}
if (dashWidth != 0.0f) {
@@ -1346,10 +1348,10 @@ public class GradientDrawable extends Drawable {
R.styleable.GradientDrawableGradient_endColor, 0);
if (hasCenterColor) {
- st.mColors = new int[3];
- st.mColors[0] = startColor;
- st.mColors[1] = centerColor;
- st.mColors[2] = endColor;
+ st.mGradientColors = new int[3];
+ st.mGradientColors[0] = startColor;
+ st.mGradientColors[1] = centerColor;
+ st.mGradientColors[2] = endColor;
st.mPositions = new float[3];
st.mPositions[0] = 0.0f;
@@ -1357,9 +1359,9 @@ public class GradientDrawable extends Drawable {
st.mPositions[1] = st.mCenterX != 0.5f ? st.mCenterX : st.mCenterY;
st.mPositions[2] = 1f;
} else {
- st.mColors = new int[2];
- st.mColors[0] = startColor;
- st.mColors[1] = endColor;
+ st.mGradientColors = new int[2];
+ st.mGradientColors[0] = startColor;
+ st.mGradientColors[1] = endColor;
}
if (st.mGradient == LINEAR_GRADIENT) {
@@ -1552,9 +1554,9 @@ public class GradientDrawable extends Drawable {
public int mGradient = LINEAR_GRADIENT;
public int mAngle = 0;
public Orientation mOrientation;
- public ColorStateList mColorStateList;
- public ColorStateList mStrokeColorStateList;
- public int[] mColors;
+ public ColorStateList mSolidColors;
+ public ColorStateList mStrokeColors;
+ public int[] mGradientColors;
public int[] mTempColors; // no need to copy
public float[] mTempPositions; // no need to copy
public float[] mPositions;
@@ -1593,9 +1595,9 @@ public class GradientDrawable extends Drawable {
int[] mAttrCorners;
int[] mAttrPadding;
- public GradientState(Orientation orientation, int[] colors) {
+ public GradientState(Orientation orientation, int[] gradientColors) {
mOrientation = orientation;
- setColors(colors);
+ setGradientColors(gradientColors);
}
public GradientState(GradientState state) {
@@ -1604,14 +1606,14 @@ public class GradientDrawable extends Drawable {
mGradient = state.mGradient;
mAngle = state.mAngle;
mOrientation = state.mOrientation;
- mColorStateList = state.mColorStateList;
- if (state.mColors != null) {
- mColors = state.mColors.clone();
+ mSolidColors = state.mSolidColors;
+ if (state.mGradientColors != null) {
+ mGradientColors = state.mGradientColors.clone();
}
if (state.mPositions != null) {
mPositions = state.mPositions.clone();
}
- mStrokeColorStateList = state.mStrokeColorStateList;
+ mStrokeColors = state.mStrokeColors;
mStrokeWidth = state.mStrokeWidth;
mStrokeDashWidth = state.mStrokeDashWidth;
mStrokeDashGap = state.mStrokeDashGap;
@@ -1655,8 +1657,8 @@ public class GradientDrawable extends Drawable {
|| mAttrSolid != null || mAttrStroke != null
|| mAttrCorners != null || mAttrPadding != null
|| (mTint != null && mTint.canApplyTheme())
- || (mStrokeColorStateList != null && mStrokeColorStateList.canApplyTheme())
- || (mColorStateList != null && mColorStateList.canApplyTheme())
+ || (mStrokeColors != null && mStrokeColors.canApplyTheme())
+ || (mSolidColors != null && mSolidColors.canApplyTheme())
|| super.canApplyTheme();
}
@@ -1672,7 +1674,10 @@ public class GradientDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations
+ | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0)
+ | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0)
+ | (mTint != null ? mTint.getChangingConfigurations() : 0);
}
public void setShape(int shape) {
@@ -1689,15 +1694,15 @@ public class GradientDrawable extends Drawable {
mCenterY = y;
}
- public void setColors(int[] colors) {
- mColors = colors;
- mColorStateList = null;
+ public void setGradientColors(int[] colors) {
+ mGradientColors = colors;
+ mSolidColors = null;
computeOpacity();
}
- public void setColorStateList(ColorStateList colorStateList) {
- mColors = null;
- mColorStateList = colorStateList;
+ public void setSolidColors(ColorStateList colors) {
+ mGradientColors = null;
+ mSolidColors = colors;
computeOpacity();
}
@@ -1705,16 +1710,16 @@ public class GradientDrawable extends Drawable {
mOpaqueOverBounds = false;
mOpaqueOverShape = false;
- if (mColors != null) {
- for (int i = 0; i < mColors.length; i++) {
- if (!isOpaque(mColors[i])) {
+ if (mGradientColors != null) {
+ for (int i = 0; i < mGradientColors.length; i++) {
+ if (!isOpaque(mGradientColors[i])) {
return;
}
}
}
// An unfilled shape is not opaque over bounds or shape
- if (mColors == null && mColorStateList == null) {
+ if (mGradientColors == null && mSolidColors == null) {
return;
}
@@ -1726,10 +1731,9 @@ public class GradientDrawable extends Drawable {
&& mRadiusArray == null;
}
- public void setStroke(
- int width, ColorStateList colorStateList, float dashWidth, float dashGap) {
+ public void setStroke(int width, ColorStateList colors, float dashWidth, float dashGap) {
mStrokeWidth = width;
- mStrokeColorStateList = colorStateList;
+ mStrokeColors = colors;
mStrokeDashWidth = dashWidth;
mStrokeDashGap = dashGap;
computeOpacity();
@@ -1781,11 +1785,11 @@ public class GradientDrawable extends Drawable {
private void updateLocalState(Resources res) {
final GradientState state = mGradientState;
- if (state.mColorStateList != null) {
+ if (state.mSolidColors != null) {
final int[] currentState = getState();
- final int stateColor = state.mColorStateList.getColorForState(currentState, 0);
+ final int stateColor = state.mSolidColors.getColorForState(currentState, 0);
mFillPaint.setColor(stateColor);
- } else if (state.mColors == null) {
+ } else if (state.mGradientColors == null) {
// If we don't have a solid color and we don't have a gradient,
// the app is stroking the shape, set the color to the default
// value of state.mSolidColor
@@ -1802,9 +1806,9 @@ public class GradientDrawable extends Drawable {
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setStrokeWidth(state.mStrokeWidth);
- if (state.mStrokeColorStateList != null) {
+ if (state.mStrokeColors != null) {
final int[] currentState = getState();
- final int strokeStateColor = state.mStrokeColorStateList.getColorForState(
+ final int strokeStateColor = state.mStrokeColors.getColorForState(
currentState, 0);
mStrokePaint.setColor(strokeStateColor);
}
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 97f7105..e1ebdbb 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -242,26 +242,12 @@ public class InsetDrawable extends DrawableWrapper {
}
@Override
- public ConstantState getConstantState() {
- if (mState.canConstantState()) {
- mState.mChangingConfigurations = getChangingConfigurations();
- return mState;
- }
- return null;
- }
-
- @Override
DrawableWrapperState mutateConstantState() {
mState = new InsetState(mState);
return mState;
}
static final class InsetState extends DrawableWrapper.DrawableWrapperState {
- int[] mThemeAttrs;
- int mChangingConfigurations;
-
- ConstantState mDrawableState;
-
int mInsetLeft = 0;
int mInsetTop = 0;
int mInsetRight = 0;
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 30fbe16..8468d9e 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -163,7 +163,6 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
inflateLayers(r, parser, attrs, theme);
ensurePadding();
- onStateChange(getState());
}
/**
@@ -211,7 +210,11 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
updateLayerFromTypedArray(layer, a);
a.recycle();
- if (layer.mDrawable == null) {
+ // If the layer doesn't have a drawable or unresolved theme
+ // attribute for a drawable, attempt to parse one from the child
+ // element.
+ if (layer.mDrawable == null && (layer.mThemeAttrs == null ||
+ layer.mThemeAttrs[R.styleable.LayerDrawableItem_drawable] == 0)) {
while ((type = parser.next()) == XmlPullParser.TEXT) {
}
if (type != XmlPullParser.START_TAG) {
@@ -294,13 +297,15 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
final Drawable d = layer.mDrawable;
- if (d.canApplyTheme()) {
+ if (d != null && d.canApplyTheme()) {
d.applyTheme(t);
+
+ // Update cached mask of child changing configurations.
+ state.mChildrenChangingConfigurations |= d.getChangingConfigurations();
}
}
ensurePadding();
- onStateChange(getState());
}
@Override
@@ -876,15 +881,16 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.draw(canvas);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.draw(canvas);
+ }
}
}
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mLayerState.mChangingConfigurations
- | mLayerState.mChildrenChangingConfigurations;
+ return super.getChangingConfigurations() | mLayerState.getChangingConfigurations();
}
@Override
@@ -943,13 +949,15 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
*/
@Override
public void getOutline(@NonNull Outline outline) {
- final LayerState state = mLayerState;
- final ChildDrawable[] children = state.mChildren;
- final int N = state.mNum;
+ final ChildDrawable[] array = mLayerState.mChildren;
+ final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- children[i].mDrawable.getOutline(outline);
- if (!outline.isEmpty()) {
- return;
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.getOutline(outline);
+ if (!outline.isEmpty()) {
+ return;
+ }
}
}
}
@@ -959,7 +967,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setHotspot(x, y);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setHotspot(x, y);
+ }
}
}
@@ -968,7 +979,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setHotspotBounds(left, top, right, bottom);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setHotspotBounds(left, top, right, bottom);
+ }
}
if (mHotspotBounds == null) {
@@ -993,7 +1007,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setVisible(visible, restart);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setVisible(visible, restart);
+ }
}
return changed;
@@ -1004,17 +1021,18 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setDither(dither);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setDither(dither);
+ }
}
}
@Override
public boolean getDither() {
- final ChildDrawable[] array = mLayerState.mChildren;
- if (mLayerState.mNum > 0) {
- // All layers should have the same dither set on them - just return
- // the first one
- return array[0].mDrawable.getDither();
+ final Drawable dr = getFirstNonNullDrawable();
+ if (dr != null) {
+ return dr.getDither();
} else {
return super.getDither();
}
@@ -1025,17 +1043,18 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setAlpha(alpha);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setAlpha(alpha);
+ }
}
}
@Override
public int getAlpha() {
- final ChildDrawable[] array = mLayerState.mChildren;
- if (mLayerState.mNum > 0) {
- // All layers should have the same alpha set on them - just return
- // the first one
- return array[0].mDrawable.getAlpha();
+ final Drawable dr = getFirstNonNullDrawable();
+ if (dr != null) {
+ return dr.getAlpha();
} else {
return super.getAlpha();
}
@@ -1046,7 +1065,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setColorFilter(colorFilter);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setColorFilter(colorFilter);
+ }
}
}
@@ -1055,7 +1077,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setTintList(tint);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setTintList(tint);
+ }
}
}
@@ -1064,8 +1089,23 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setTintMode(tintMode);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setTintMode(tintMode);
+ }
+ }
+ }
+
+ private Drawable getFirstNonNullDrawable() {
+ final ChildDrawable[] array = mLayerState.mChildren;
+ final int N = mLayerState.mNum;
+ for (int i = 0; i < N; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ return dr;
+ }
}
+ return null;
}
/**
@@ -1098,7 +1138,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setAutoMirrored(mirrored);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setAutoMirrored(mirrored);
+ }
}
}
@@ -1119,9 +1162,9 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- final ChildDrawable r = array[i];
- if (r.mDrawable.isStateful() && r.mDrawable.setState(state)) {
- refreshChildPadding(i, r);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.isStateful() && dr.setState(state)) {
+ refreshChildPadding(i, array[i]);
changed = true;
}
}
@@ -1140,9 +1183,9 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- final ChildDrawable r = array[i];
- if (r.mDrawable.setLevel(level)) {
- refreshChildPadding(i, r);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.setLevel(level)) {
+ refreshChildPadding(i, array[i]);
changed = true;
}
}
@@ -1173,6 +1216,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
for (int i = 0; i < N; i++) {
final ChildDrawable r = array[i];
final Drawable d = r.mDrawable;
+ if (d == null) {
+ continue;
+ }
+
final Rect container = mTmpContainer;
container.set(d.getBounds());
@@ -1254,6 +1301,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
final ChildDrawable r = array[i];
+ if (r.mDrawable == null) {
+ continue;
+ }
+
final int minWidth = r.mWidth < 0 ? r.mDrawable.getIntrinsicWidth() : r.mWidth;
final int w = minWidth + r.mInsetL + r.mInsetR + padL + padR;
if (w > width) {
@@ -1280,6 +1331,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
final ChildDrawable r = array[i];
+ if (r.mDrawable == null) {
+ continue;
+ }
+
final int minHeight = r.mHeight < 0 ? r.mDrawable.getIntrinsicHeight() : r.mHeight;
final int h = minHeight + r.mInsetT + r.mInsetB + padT + padB;
if (h > height) {
@@ -1301,15 +1356,17 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
* @return true if the child's padding has changed
*/
private boolean refreshChildPadding(int i, ChildDrawable r) {
- final Rect rect = mTmpRect;
- r.mDrawable.getPadding(rect);
- if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
- rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
- mPaddingL[i] = rect.left;
- mPaddingT[i] = rect.top;
- mPaddingR[i] = rect.right;
- mPaddingB[i] = rect.bottom;
- return true;
+ if (r.mDrawable != null) {
+ final Rect rect = mTmpRect;
+ r.mDrawable.getPadding(rect);
+ if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
+ rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
+ mPaddingL[i] = rect.left;
+ mPaddingT[i] = rect.top;
+ mPaddingR[i] = rect.right;
+ mPaddingB[i] = rect.bottom;
+ return true;
+ }
}
return false;
}
@@ -1345,7 +1402,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.mutate();
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.mutate();
+ }
}
mMutated = true;
}
@@ -1357,10 +1417,14 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
*/
public void clearMutated() {
super.clearMutated();
+
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.clearMutated();
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.clearMutated();
+ }
}
mMutated = false;
}
@@ -1368,11 +1432,16 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
@Override
public boolean onLayoutDirectionChange(int layoutDirection) {
boolean changed = false;
+
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- changed |= array[i].mDrawable.setLayoutDirection(layoutDirection);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ changed |= dr.setLayoutDirection(layoutDirection);
+ }
}
+
updateLayerBounds(getBounds());
return changed;
}
@@ -1393,15 +1462,24 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
ChildDrawable(ChildDrawable orig, LayerDrawable owner, Resources res) {
- if (res != null) {
- mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
+ final Drawable dr = orig.mDrawable;
+ final Drawable clone;
+ if (dr != null) {
+ final ConstantState cs = dr.getConstantState();
+ if (res != null) {
+ clone = cs.newDrawable(res);
+ } else {
+ clone = cs.newDrawable();
+ }
+ clone.setCallback(owner);
+ clone.setLayoutDirection(dr.getLayoutDirection());
+ clone.setBounds(dr.getBounds());
+ clone.setLevel(dr.getLevel());
} else {
- mDrawable = orig.mDrawable.getConstantState().newDrawable();
+ clone = null;
}
- mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
- mDrawable.setBounds(orig.mDrawable.getBounds());
- mDrawable.setLevel(orig.mDrawable.getLevel());
+
+ mDrawable = clone;
mThemeAttrs = orig.mThemeAttrs;
mInsetL = orig.mInsetL;
mInsetT = orig.mInsetT;
@@ -1414,6 +1492,11 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
mGravity = orig.mGravity;
mId = orig.mId;
}
+
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null
+ || (mDrawable != null && mDrawable.canApplyTheme());
+ }
}
static class LayerState extends ConstantState {
@@ -1473,7 +1556,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mNum;
for (int i = 0; i < N; i++) {
final ChildDrawable layer = array[i];
- if (layer.mThemeAttrs != null || layer.mDrawable.canApplyTheme()) {
+ if (layer.canApplyTheme()) {
return true;
}
}
@@ -1493,7 +1576,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations
+ | mChildrenChangingConfigurations;
}
public final int getOpacity() {
@@ -1503,9 +1587,29 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mChildren;
final int N = mNum;
- int op = N > 0 ? array[0].mDrawable.getOpacity() : PixelFormat.TRANSPARENT;
- for (int i = 1; i < N; i++) {
- op = Drawable.resolveOpacity(op, array[i].mDrawable.getOpacity());
+
+ // Seek to the first non-null drawable.
+ int firstIndex = -1;
+ for (int i = 0; i < N; i++) {
+ if (array[i].mDrawable != null) {
+ firstIndex = i;
+ break;
+ }
+ }
+
+ int op;
+ if (firstIndex >= 0) {
+ op = array[firstIndex].mDrawable.getOpacity();
+ } else {
+ op = PixelFormat.TRANSPARENT;
+ }
+
+ // Merge all remaining non-null drawables.
+ for (int i = firstIndex + 1; i < N; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ op = Drawable.resolveOpacity(op, dr.getOpacity());
+ }
}
mOpacity = op;
@@ -1522,7 +1626,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mNum;
boolean isStateful = false;
for (int i = 0; i < N; i++) {
- if (array[i].mDrawable.isStateful()) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.isStateful()) {
isStateful = true;
break;
}
@@ -1537,7 +1642,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mChildren;
final int N = mNum;
for (int i = 0; i < N; i++) {
- if (array[i].mDrawable.getConstantState() == null) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.getConstantState() == null) {
return false;
}
}
@@ -1557,9 +1663,12 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mNum;
int pixelCount = 0;
for (int i = 0; i < N; i++) {
- final ConstantState state = array[i].mDrawable.getConstantState();
- if (state != null) {
- pixelCount += state.addAtlasableBitmaps(atlasList);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ final ConstantState state = dr.getConstantState();
+ if (state != null) {
+ pixelCount += state.addAtlasableBitmaps(atlasList);
+ }
}
}
return pixelCount;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 487162e..9bf33cf 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -266,7 +266,7 @@ public class NinePatchDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations() | mNinePatchState.mChangingConfigurations;
+ return super.getChangingConfigurations() | mNinePatchState.getChangingConfigurations();
}
@Override
@@ -498,7 +498,7 @@ public class NinePatchDrawable extends Drawable {
}
if (state.mTint != null && state.mTint.canApplyTheme()) {
- state.mTint.applyTheme(t);
+ state.mTint = state.mTint.obtainForTheme(t);
}
updateLocalState(t.getResources());
@@ -680,7 +680,8 @@ public class NinePatchDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations
+ | (mTint != null ? mTint.getChangingConfigurations() : 0);
}
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 23f93fd..6731a17 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -479,7 +479,7 @@ public class RippleDrawable extends LayerDrawable {
}
if (state.mColor != null && state.mColor.canApplyTheme()) {
- state.mColor.applyTheme(t);
+ state.mColor = state.mColor.obtainForTheme(t);
}
updateLocalState();
@@ -955,6 +955,12 @@ public class RippleDrawable extends LayerDrawable {
public Drawable newDrawable(Resources res) {
return new RippleDrawable(this, res);
}
+
+ @Override
+ public int getChangingConfigurations() {
+ return super.getChangingConfigurations()
+ | (mColor != null ? mColor.getChangingConfigurations() : 0);
+ }
}
private RippleDrawable(RippleState state, Resources res) {
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 15e16f1..036a078 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -89,9 +89,6 @@ public class RotateDrawable extends DrawableWrapper {
final RotateState state = mState;
- // Account for any configuration changes.
- state.mChangingConfigurations |= a.getChangingConfigurations();
-
// Extract the theme attributes, if any.
state.mThemeAttrs = a.extractThemeAttrs();
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index fc88c15..334b3bd 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -53,9 +53,9 @@ import java.io.IOException;
* For more information about how to use ShapeDrawable, read the <a
* href="{@docRoot}guide/topics/graphics/2d-graphics.html#shape-drawable">
* Canvas and Drawables</a> document. For more information about defining a
- * ShapeDrawable in XML, read the <a href="{@docRoot}
- * guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
- * document.
+ * ShapeDrawable in XML, read the
+ * <a href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">
+ * Drawable Resources</a> document.
* </p>
* </div>
*
@@ -261,8 +261,7 @@ public class ShapeDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mShapeState.mChangingConfigurations;
+ return super.getChangingConfigurations() | mShapeState.getChangingConfigurations();
}
/**
@@ -427,7 +426,7 @@ public class ShapeDrawable extends Drawable {
// Apply theme to contained color state list.
if (state.mTint != null && state.mTint.canApplyTheme()) {
- state.mTint.applyTheme(t);
+ state.mTint = state.mTint.obtainForTheme(t);
}
// Update local properties.
@@ -578,7 +577,8 @@ public class ShapeDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations
+ | (mTint != null ? mTint.getChangingConfigurations() : 0);
}
}
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index b827682..f4df14e 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -36,6 +36,7 @@ import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.LayoutDirection;
import android.util.Log;
+import android.util.MathUtils;
import android.util.PathParser;
import android.util.Xml;
@@ -389,7 +390,7 @@ public class VectorDrawable extends Drawable {
// Apply theme to contained color state list.
if (state.mTint != null && state.mTint.canApplyTheme()) {
- state.mTint.applyTheme(t);
+ state.mTint = state.mTint.obtainForTheme(t);
}
final VPathRenderer path = state.mVPathRenderer;
@@ -625,7 +626,7 @@ public class VectorDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations() | mVectorState.mChangingConfigurations;
+ return super.getChangingConfigurations() | mVectorState.getChangingConfigurations();
}
void setAllowCaching(boolean allowCaching) {
@@ -784,7 +785,8 @@ public class VectorDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations;
+ return mChangingConfigurations
+ | (mTint != null ? mTint.getChangingConfigurations() : 0);
}
}
@@ -955,10 +957,16 @@ public class VectorDrawable extends Drawable {
final float scaleX = w / mViewportWidth;
final float scaleY = h / mViewportHeight;
final float minScale = Math.min(scaleX, scaleY);
+ final Matrix groupStackedMatrix = vGroup.mStackedMatrix;
- mFinalPathMatrix.set(vGroup.mStackedMatrix);
+ mFinalPathMatrix.set(groupStackedMatrix);
mFinalPathMatrix.postScale(scaleX, scaleY);
+ final float matrixScale = getMatrixScale(groupStackedMatrix);
+ if (matrixScale == 0) {
+ // When either x or y is scaled to 0, we don't need to draw anything.
+ return;
+ }
vPath.toPath(mPath);
final Path path = mPath;
@@ -966,7 +974,7 @@ public class VectorDrawable extends Drawable {
if (vPath.isClipPath()) {
mRenderPath.addPath(path, mFinalPathMatrix);
- canvas.clipPath(mRenderPath, Region.Op.REPLACE);
+ canvas.clipPath(mRenderPath);
} else {
VFullPath fullPath = (VFullPath) vPath;
if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
@@ -1024,11 +1032,41 @@ public class VectorDrawable extends Drawable {
strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, fullPath.mStrokeAlpha));
strokePaint.setColorFilter(filter);
- strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale);
+ final float finalStrokeScale = minScale * matrixScale;
+ strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale);
canvas.drawPath(mRenderPath, strokePaint);
}
}
}
+
+ private float getMatrixScale(Matrix groupStackedMatrix) {
+ // Given unit vectors A = (0, 1) and B = (1, 0).
+ // After matrix mapping, we got A' and B'. Let theta = the angel b/t A' and B'.
+ // Therefore, the final scale we want is min(|A'| * sin(theta), |B'| * sin(theta)),
+ // which is (|A'| * |B'| * sin(theta)) / max (|A'|, |B'|);
+ // If max (|A'|, |B'|) = 0, that means either x or y has a scale of 0.
+ //
+ // For non-skew case, which is most of the cases, matrix scale is computing exactly the
+ // scale on x and y axis, and take the minimal of these two.
+ // For skew case, an unit square will mapped to a parallelogram. And this function will
+ // return the minimal height of the 2 bases.
+ float[] unitVectors = new float[] {0, 1, 1, 0};
+ groupStackedMatrix.mapVectors(unitVectors);
+ float scaleX = MathUtils.mag(unitVectors[0], unitVectors[1]);
+ float scaleY = MathUtils.mag(unitVectors[2], unitVectors[3]);
+ float crossProduct = MathUtils.cross(unitVectors[0], unitVectors[1],
+ unitVectors[2], unitVectors[3]);
+ float maxScale = MathUtils.max(scaleX, scaleY);
+
+ float matrixScale = 0;
+ if (maxScale > 0) {
+ matrixScale = MathUtils.abs(crossProduct) / maxScale;
+ }
+ if (DBG_VECTOR_DRAWABLE) {
+ Log.d(LOGTAG, "Scale x " + scaleX + " y " + scaleY + " final " + matrixScale);
+ }
+ return matrixScale;
+ }
}
private static class VGroup {
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index b32dcc6..feb8052 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -380,7 +380,7 @@ public final class PdfRenderer implements AutoCloseable {
final long transformPtr = (transform != null) ? transform.native_instance : 0;
- nativeRenderPage(mNativeDocument, mNativePage, destination.getSkBitmap(), contentLeft,
+ nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
contentTop, contentRight, contentBottom, transformPtr, renderMode);
}
@@ -425,7 +425,7 @@ public final class PdfRenderer implements AutoCloseable {
private static native void nativeClose(long documentPtr);
private static native int nativeGetPageCount(long documentPtr);
private static native boolean nativeScaleForPrinting(long documentPtr);
- private static native void nativeRenderPage(long documentPtr, long pagePtr, long destPtr,
+ private static native void nativeRenderPage(long documentPtr, long pagePtr, Bitmap dest,
int destLeft, int destTop, int destRight, int destBottom, long matrixPtr, int renderMode);
private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex,
Point outSize);