diff options
Diffstat (limited to 'graphics')
21 files changed, 335 insertions, 174 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 3f79c2d..1892dcb 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -1537,7 +1537,7 @@ public final class Bitmap implements Parcelable { */ public Bitmap extractAlpha(Paint paint, int[] offsetXY) { checkRecycled("Can't extractAlpha on a recycled bitmap"); - long nativePaint = paint != null ? paint.mNativePaint : 0; + long nativePaint = paint != null ? paint.getNativeInstance() : 0; Bitmap bm = nativeExtractAlpha(mNativeBitmap, nativePaint, offsetXY); if (bm == null) { throw new RuntimeException("Failed to extractAlpha on Bitmap"); diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index b0580d5..e4c2f0e 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -44,8 +44,12 @@ import javax.microedition.khronos.opengles.GL; */ public class Canvas { - // assigned in constructors or setBitmap, freed in finalizer - private long mNativeCanvasWrapper; + /** + * Should only be assigned in constructors (or setBitmap if software canvas), + * freed in finalizer. + * @hide + */ + protected long mNativeCanvasWrapper; /** @hide */ public long getNativeCanvasWrapper() { @@ -475,7 +479,7 @@ public class Canvas { public int saveLayer(float left, float top, float right, float bottom, @Nullable Paint paint, @Saveflags int saveFlags) { return native_saveLayer(mNativeCanvasWrapper, left, top, right, bottom, - paint != null ? paint.mNativePaint : 0, + paint != null ? paint.getNativeInstance() : 0, saveFlags); } @@ -1031,7 +1035,7 @@ public class Canvas { * @param paint The paint used to draw onto the canvas */ public void drawPaint(@NonNull Paint paint) { - native_drawPaint(mNativeCanvasWrapper, paint.mNativePaint); + native_drawPaint(mNativeCanvasWrapper, paint.getNativeInstance()); } /** @@ -1051,7 +1055,7 @@ public class Canvas { * @param paint The paint used to draw the points */ public void drawPoints(float[] pts, int offset, int count, @NonNull Paint paint) { - native_drawPoints(mNativeCanvasWrapper, pts, offset, count, paint.mNativePaint); + native_drawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance()); } /** @@ -1065,7 +1069,7 @@ public class Canvas { * Helper for drawPoints() for drawing a single point. */ public void drawPoint(float x, float y, @NonNull Paint paint) { - native_drawPoint(mNativeCanvasWrapper, x, y, paint.mNativePaint); + native_drawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance()); } /** @@ -1082,7 +1086,7 @@ public class Canvas { */ public void drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint) { - native_drawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.mNativePaint); + native_drawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance()); } /** @@ -1101,7 +1105,7 @@ public class Canvas { * @param paint The paint used to draw the points */ public void drawLines(float[] pts, int offset, int count, Paint paint) { - native_drawLines(mNativeCanvasWrapper, pts, offset, count, paint.mNativePaint); + native_drawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance()); } public void drawLines(@NonNull float[] pts, @NonNull Paint paint) { @@ -1117,7 +1121,7 @@ public class Canvas { */ public void drawRect(@NonNull RectF rect, @NonNull Paint paint) { native_drawRect(mNativeCanvasWrapper, - rect.left, rect.top, rect.right, rect.bottom, paint.mNativePaint); + rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance()); } /** @@ -1143,7 +1147,7 @@ public class Canvas { * @param paint The paint used to draw the rect */ public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) { - native_drawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.mNativePaint); + native_drawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance()); } /** @@ -1164,7 +1168,7 @@ public class Canvas { * filled or framed based on the Style in the paint. */ public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) { - native_drawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.mNativePaint); + native_drawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance()); } /** @@ -1178,7 +1182,7 @@ public class Canvas { * @param paint The paint used to draw the circle */ public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) { - native_drawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.mNativePaint); + native_drawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance()); } /** @@ -1234,7 +1238,7 @@ public class Canvas { public void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint) { native_drawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle, - useCenter, paint.mNativePaint); + useCenter, paint.getNativeInstance()); } /** @@ -1260,7 +1264,7 @@ public class Canvas { */ public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, @NonNull Paint paint) { - native_drawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, paint.mNativePaint); + native_drawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, paint.getNativeInstance()); } /** @@ -1271,7 +1275,7 @@ public class Canvas { * @param paint The paint used to draw the path */ public void drawPath(@NonNull Path path, @NonNull Paint paint) { - native_drawPath(mNativeCanvasWrapper, path.ni(), paint.mNativePaint); + native_drawPath(mNativeCanvasWrapper, path.ni(), paint.getNativeInstance()); } /** @@ -1336,7 +1340,7 @@ public class Canvas { public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) { throwIfCannotDraw(bitmap); native_drawBitmap(mNativeCanvasWrapper, bitmap.ni(), left, top, - paint != null ? paint.mNativePaint : 0, mDensity, mScreenDensity, bitmap.mDensity); + paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity); } /** @@ -1367,7 +1371,7 @@ public class Canvas { throw new NullPointerException(); } throwIfCannotDraw(bitmap); - final long nativePaint = paint == null ? 0 : paint.mNativePaint; + final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); float left, top, right, bottom; if (src == null) { @@ -1414,7 +1418,7 @@ public class Canvas { throw new NullPointerException(); } throwIfCannotDraw(bitmap); - final long nativePaint = paint == null ? 0 : paint.mNativePaint; + final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); int left, top, right, bottom; if (src == null) { @@ -1482,7 +1486,7 @@ public class Canvas { } // punch down to native for the actual draw native_drawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha, - paint != null ? paint.mNativePaint : 0); + paint != null ? paint.getNativeInstance() : 0); } /** @@ -1510,7 +1514,7 @@ public class Canvas { */ public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) { nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.ni(), matrix.ni(), - paint != null ? paint.mNativePaint : 0); + paint != null ? paint.getNativeInstance() : 0); } /** @@ -1566,7 +1570,7 @@ public class Canvas { } nativeDrawBitmapMesh(mNativeCanvasWrapper, bitmap.ni(), meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, - paint != null ? paint.mNativePaint : 0); + paint != null ? paint.getNativeInstance() : 0); } public enum VertexMode { @@ -1619,6 +1623,9 @@ public class Canvas { int colorOffset, @Nullable short[] indices, int indexOffset, int indexCount, @NonNull Paint paint) { checkRange(verts.length, vertOffset, vertexCount); + if (isHardwareAccelerated()) { + return; + } if (texs != null) { checkRange(texs.length, texOffset, vertexCount); } @@ -1630,7 +1637,7 @@ public class Canvas { } nativeDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts, vertOffset, texs, texOffset, colors, colorOffset, - indices, indexOffset, indexCount, paint.mNativePaint); + indices, indexOffset, indexCount, paint.getNativeInstance()); } /** @@ -1639,7 +1646,7 @@ public class Canvas { * * @param text The text to be drawn * @param x The x-coordinate of the origin of the text being drawn - * @param y The y-coordinate of the origin of the text being drawn + * @param y The y-coordinate of the baseline of the text being drawn * @param paint The paint used for the text (e.g. color, size, style) */ public void drawText(@NonNull char[] text, int index, int count, float x, float y, @@ -1649,7 +1656,7 @@ public class Canvas { throw new IndexOutOfBoundsException(); } native_drawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags, - paint.mNativePaint, paint.mNativeTypeface); + paint.getNativeInstance(), paint.mNativeTypeface); } /** @@ -1658,12 +1665,12 @@ public class Canvas { * * @param text The text to be drawn * @param x The x-coordinate of the origin of the text being drawn - * @param y The y-coordinate of the origin of the text being drawn + * @param y The y-coordinate of the baseline of the text being drawn * @param paint The paint used for the text (e.g. color, size, style) */ public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) { native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags, - paint.mNativePaint, paint.mNativeTypeface); + paint.getNativeInstance(), paint.mNativeTypeface); } /** @@ -1674,7 +1681,7 @@ public class Canvas { * @param start The index of the first character in text to draw * @param end (end - 1) is the index of the last character in text to draw * @param x The x-coordinate of the origin of the text being drawn - * @param y The y-coordinate of the origin of the text being drawn + * @param y The y-coordinate of the baseline of the text being drawn * @param paint The paint used for the text (e.g. color, size, style) */ public void drawText(@NonNull String text, int start, int end, float x, float y, @@ -1683,7 +1690,7 @@ public class Canvas { throw new IndexOutOfBoundsException(); } native_drawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags, - paint.mNativePaint, paint.mNativeTypeface); + paint.getNativeInstance(), paint.mNativeTypeface); } /** @@ -1707,7 +1714,7 @@ public class Canvas { if (text instanceof String || text instanceof SpannedString || text instanceof SpannableString) { native_drawText(mNativeCanvasWrapper, text.toString(), start, end, x, y, - paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); + paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); } else if (text instanceof GraphicsOperations) { ((GraphicsOperations) text).drawText(this, start, end, x, y, paint); @@ -1715,7 +1722,7 @@ public class Canvas { char[] buf = TemporaryBuffer.obtain(end - start); TextUtils.getChars(text, start, end, buf, 0); native_drawText(mNativeCanvasWrapper, buf, 0, end - start, x, y, - paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); + paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); TemporaryBuffer.recycle(buf); } } @@ -1754,7 +1761,7 @@ public class Canvas { } native_drawTextRun(mNativeCanvasWrapper, text, index, count, - contextIndex, contextCount, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface); + contextIndex, contextCount, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface); } /** @@ -1790,7 +1797,7 @@ public class Canvas { if (text instanceof String || text instanceof SpannedString || text instanceof SpannableString) { native_drawTextRun(mNativeCanvasWrapper, text.toString(), start, end, - contextStart, contextEnd, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface); + contextStart, contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface); } else if (text instanceof GraphicsOperations) { ((GraphicsOperations) text).drawTextRun(this, start, end, contextStart, contextEnd, x, y, isRtl, paint); @@ -1800,7 +1807,7 @@ public class Canvas { char[] buf = TemporaryBuffer.obtain(contextLen); TextUtils.getChars(text, contextStart, contextEnd, buf, 0); native_drawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len, - 0, contextLen, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface); + 0, contextLen, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface); TemporaryBuffer.recycle(buf); } } @@ -1868,7 +1875,7 @@ public class Canvas { } native_drawTextOnPath(mNativeCanvasWrapper, text, index, count, path.ni(), hOffset, vOffset, - paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); + paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); } /** @@ -1888,7 +1895,7 @@ public class Canvas { float vOffset, @NonNull Paint paint) { if (text.length() > 0) { native_drawTextOnPath(mNativeCanvasWrapper, text, path.ni(), hOffset, vOffset, - paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); + paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); } } diff --git a/graphics/java/android/graphics/CanvasProperty.java b/graphics/java/android/graphics/CanvasProperty.java index be86060..ea3886c 100644 --- a/graphics/java/android/graphics/CanvasProperty.java +++ b/graphics/java/android/graphics/CanvasProperty.java @@ -31,7 +31,7 @@ public final class CanvasProperty<T> { } public static CanvasProperty<Paint> createPaint(Paint initialValue) { - return new CanvasProperty<Paint>(nCreatePaint(initialValue.mNativePaint)); + return new CanvasProperty<Paint>(nCreatePaint(initialValue.getNativeInstance())); } private CanvasProperty(long nativeContainer) { diff --git a/graphics/java/android/graphics/DrawFilter.java b/graphics/java/android/graphics/DrawFilter.java index ed38f37..aaefce9 100644 --- a/graphics/java/android/graphics/DrawFilter.java +++ b/graphics/java/android/graphics/DrawFilter.java @@ -24,8 +24,11 @@ package android.graphics; */ public class DrawFilter { - // this is set by subclasses, but don't make it public - /* package */ long mNativeInt; // pointer to native object + /** + * this is set by subclasses + * @hide + */ + public long mNativeInt; protected void finalize() throws Throwable { try { diff --git a/graphics/java/android/graphics/LayerRasterizer.java b/graphics/java/android/graphics/LayerRasterizer.java index e7a24a4..b692ecf 100644 --- a/graphics/java/android/graphics/LayerRasterizer.java +++ b/graphics/java/android/graphics/LayerRasterizer.java @@ -28,11 +28,11 @@ public class LayerRasterizer extends Rasterizer { object itself, so it may be reused without danger of side-effects. */ public void addLayer(Paint paint, float dx, float dy) { - nativeAddLayer(native_instance, paint.mNativePaint, dx, dy); + nativeAddLayer(native_instance, paint.getNativeInstance(), dx, dy); } public void addLayer(Paint paint) { - nativeAddLayer(native_instance, paint.mNativePaint, 0, 0); + nativeAddLayer(native_instance, paint.getNativeInstance(), 0, 0); } private static native long nativeConstructor(); diff --git a/graphics/java/android/graphics/Movie.java b/graphics/java/android/graphics/Movie.java index b0a4553..ecb4255 100644 --- a/graphics/java/android/graphics/Movie.java +++ b/graphics/java/android/graphics/Movie.java @@ -35,12 +35,17 @@ public class Movie { public native boolean isOpaque(); public native int duration(); - public native boolean setTime(int relativeMilliseconds); + public native boolean setTime(int relativeMilliseconds); + + private native void nDraw(long nativeCanvas, float x, float y, long paintHandle); + + public void draw(Canvas canvas, float x, float y, Paint paint) { + nDraw(canvas.getNativeCanvasWrapper(), x, y, + paint != null ? paint.getNativeInstance() : 0); + } - public native void draw(Canvas canvas, float x, float y, Paint paint); - public void draw(Canvas canvas, float x, float y) { - draw(canvas, x, y, null); + nDraw(canvas.getNativeCanvasWrapper(), x, y, 0); } public static Movie decodeStream(InputStream is) { diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java index 6f42046..ebc86aa 100644 --- a/graphics/java/android/graphics/NinePatch.java +++ b/graphics/java/android/graphics/NinePatch.java @@ -200,12 +200,12 @@ public class NinePatch { void drawSoftware(Canvas canvas, RectF location, Paint paint) { nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap.ni(), mNativeChunk, - paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity); + paint != null ? paint.getNativeInstance() : 0, canvas.mDensity, mBitmap.mDensity); } void drawSoftware(Canvas canvas, Rect location, Paint paint) { nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap.ni(), mNativeChunk, - paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity); + paint != null ? paint.getNativeInstance() : 0, canvas.mDensity, mBitmap.mDensity); } /** diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 652fe64..91c8dba 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -29,10 +29,9 @@ import java.util.Locale; */ public class Paint { - /** - * @hide - */ - public long mNativePaint; + private long mNativePaint; + private long mNativeShader = 0; + /** * @hide */ @@ -445,7 +444,7 @@ public class Paint { * new paint. */ public Paint(Paint paint) { - mNativePaint = native_initWithPaint(paint.mNativePaint); + mNativePaint = native_initWithPaint(paint.getNativeInstance()); setClassVariablesFrom(paint); } @@ -464,6 +463,7 @@ public class Paint { mPathEffect = null; mRasterizer = null; mShader = null; + mNativeShader = 0; mTypeface = null; mNativeTypeface = 0; mXfermode = null; @@ -500,11 +500,8 @@ public class Paint { mMaskFilter = paint.mMaskFilter; mPathEffect = paint.mPathEffect; mRasterizer = paint.mRasterizer; - if (paint.mShader != null) { - mShader = paint.mShader.copy(); - } else { - mShader = null; - } + mShader = paint.mShader; + mNativeShader = paint.mNativeShader; mTypeface = paint.mTypeface; mNativeTypeface = paint.mNativeTypeface; mXfermode = paint.mXfermode; @@ -531,6 +528,20 @@ public class Paint { } /** + * Return the pointer to the native object while ensuring that any + * mutable objects that are attached to the paint are also up-to-date. + * + * @hide + */ + public long getNativeInstance() { + if (mShader != null && mShader.getNativeInstance() != mNativeShader) { + mNativeShader = mShader.getNativeInstance(); + native_setShader(mNativePaint, mNativeShader); + } + return mNativePaint; + } + + /** * Return the bidi flags on the paint. * * @return the bidi flags on the paint @@ -920,10 +931,7 @@ public class Paint { * @return shader */ public Shader setShader(Shader shader) { - long shaderNative = 0; - if (shader != null) - shaderNative = shader.getNativeInstance(); - native_setShader(mNativePaint, shaderNative); + // Defer setting the shader natively until getNativeInstance() is called mShader = shader; return shader; } diff --git a/graphics/java/android/graphics/PaintFlagsDrawFilter.java b/graphics/java/android/graphics/PaintFlagsDrawFilter.java index 65a6218..2326611 100644 --- a/graphics/java/android/graphics/PaintFlagsDrawFilter.java +++ b/graphics/java/android/graphics/PaintFlagsDrawFilter.java @@ -17,11 +17,6 @@ package android.graphics; public class PaintFlagsDrawFilter extends DrawFilter { - /** @hide **/ - public final int clearBits; - /** @hide **/ - public final int setBits; - /** * Subclass of DrawFilter that affects every paint by first clearing * the specified clearBits in the paint's flags, and then setting the @@ -31,8 +26,6 @@ public class PaintFlagsDrawFilter extends DrawFilter { * @param setBits These bits will be set in the paint's flags */ public PaintFlagsDrawFilter(int clearBits, int setBits) { - this.clearBits = clearBits; - this.setBits = setBits; // our native constructor can return 0, if the specified bits // are effectively a no-op mNativeInt = nativeConstructor(clearBits, setBits); diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java index 6934955..a96d2cb 100644 --- a/graphics/java/android/graphics/Shader.java +++ b/graphics/java/android/graphics/Shader.java @@ -82,7 +82,8 @@ public class Shader { */ public void setLocalMatrix(Matrix localM) { mLocalMatrix = localM; - nativeSetLocalMatrix(native_instance, localM == null ? 0 : localM.native_instance); + native_instance = nativeSetLocalMatrix(native_instance, + localM == null ? 0 : localM.native_instance); } protected void finalize() throws Throwable { @@ -120,5 +121,5 @@ public class Shader { } private static native void nativeDestructor(long native_shader); - private static native void nativeSetLocalMatrix(long native_shader, long matrix_instance); + private static native long nativeSetLocalMatrix(long native_shader, long matrix_instance); } diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 9be296a..945ae2e 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -357,6 +357,11 @@ public class BitmapDrawable extends Drawable { invalidateSelf(); } + @Override + public boolean getDither() { + return mBitmapState.mPaint.isDither(); + } + /** * Indicates the repeat behavior of this drawable on the X axis. * @@ -705,8 +710,8 @@ public class BitmapDrawable extends Drawable { @Override public boolean isStateful() { - final BitmapState s = mBitmapState; - return super.isStateful() || (s.mTint != null && s.mTint.isStateful()); + return (mBitmapState.mTint != null && mBitmapState.mTint.isStateful()) + || super.isStateful(); } @Override @@ -718,6 +723,9 @@ public class BitmapDrawable extends Drawable { updateStateFromTypedArray(a); verifyState(a); a.recycle(); + + // Update local properties. + updateLocalState(r); } /** @@ -800,9 +808,6 @@ public class BitmapDrawable extends Drawable { if (tileModeY != TILE_MODE_UNDEFINED) { setTileModeY(parseTileMode(tileModeY)); } - - // Update local properties. - initializeWithState(state, r); } @Override @@ -810,18 +815,28 @@ public class BitmapDrawable extends Drawable { super.applyTheme(t); final BitmapState state = mBitmapState; - if (state == null || state.mThemeAttrs == null) { + if (state == null) { return; } - final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.BitmapDrawable); - try { - updateStateFromTypedArray(a); - } catch (XmlPullParserException e) { - throw new RuntimeException(e); - } finally { - a.recycle(); + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.BitmapDrawable); + try { + updateStateFromTypedArray(a); + } catch (XmlPullParserException e) { + throw new RuntimeException(e); + } finally { + a.recycle(); + } + } + + // Apply theme to contained color state list. + if (state.mTint != null && state.mTint.canApplyTheme()) { + state.mTint.applyTheme(t); } + + // Update local properties. + updateLocalState(t.getResources()); } private static Shader.TileMode parseTileMode(int tileMode) { @@ -839,7 +854,7 @@ public class BitmapDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mBitmapState != null && mBitmapState.mThemeAttrs != null; + return mBitmapState != null && mBitmapState.canApplyTheme(); } @Override @@ -910,7 +925,7 @@ public class BitmapDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mThemeAttrs != null; + return mThemeAttrs != null || mTint != null && mTint.canApplyTheme(); } @Override @@ -944,7 +959,7 @@ public class BitmapDrawable extends Drawable { private BitmapDrawable(BitmapState state, Resources res) { mBitmapState = state; - initializeWithState(mBitmapState, res); + updateLocalState(res); } /** @@ -952,14 +967,14 @@ public class BitmapDrawable extends Drawable { * after significant state changes, e.g. from the One True Constructor and * after inflating or applying a theme. */ - private void initializeWithState(BitmapState state, Resources res) { + private void updateLocalState(Resources res) { if (res != null) { mTargetDensity = res.getDisplayMetrics().densityDpi; } else { - mTargetDensity = state.mTargetDensity; + mTargetDensity = mBitmapState.mTargetDensity; } - mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); + mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, mBitmapState.mTintMode); computeBitmapSize(); } } diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index e3b50ea..85e02b7 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -70,7 +70,7 @@ public class ColorDrawable extends Drawable { @Override public int getChangingConfigurations() { - return super.getChangingConfigurations() | mColorState.mChangingConfigurations; + return super.getChangingConfigurations() | mColorState.getChangingConfigurations(); } /** @@ -233,6 +233,8 @@ public class ColorDrawable extends Drawable { final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ColorDrawable); updateStateFromTypedArray(a); a.recycle(); + + updateLocalState(r); } /** @@ -261,13 +263,21 @@ public class ColorDrawable extends Drawable { super.applyTheme(t); final ColorState state = mColorState; - if (state == null || state.mThemeAttrs == null) { + if (state == null) { return; } - final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ColorDrawable); - updateStateFromTypedArray(a); - a.recycle(); + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ColorDrawable); + updateStateFromTypedArray(a); + a.recycle(); + } + + if (state.mTint != null && state.mTint.canApplyTheme()) { + state.mTint.applyTheme(t); + } + + updateLocalState(t.getResources()); } @Override @@ -299,17 +309,18 @@ public class ColorDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mThemeAttrs != null; + return mThemeAttrs != null + || (mTint != null && mTint.canApplyTheme()); } @Override public Drawable newDrawable() { - return new ColorDrawable(this); + return new ColorDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new ColorDrawable(this); + return new ColorDrawable(this, res); } @Override @@ -318,8 +329,18 @@ public class ColorDrawable extends Drawable { } } - private ColorDrawable(ColorState state) { + private ColorDrawable(ColorState state, Resources res) { mColorState = state; - mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); + + updateLocalState(res); + } + + /** + * Initializes local dynamic properties from state. This should be called + * after significant state changes, e.g. from the One True Constructor and + * after inflating or applying a theme. + */ + private void updateLocalState(Resources r) { + mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, mColorState.mTintMode); } } diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 0e38cc0..fa269e0 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -274,6 +274,14 @@ public abstract class Drawable { public void setDither(boolean dither) {} /** + * @return whether this drawable dither its colors + * @see #setDither(boolean) + */ + public boolean getDither() { + return false; + } + + /** * Set to true to have the drawable filter its bitmap when scaled or rotated * (for drawables that use bitmaps). If the drawable does not use bitmaps, * this call is ignored. This can improve the look when scaled or rotated, @@ -282,6 +290,14 @@ public abstract class Drawable { public void setFilterBitmap(boolean filter) {} /** + * @return whether this drawable filters its bitmap + * @see #setFilterBitmap(boolean) + */ + public boolean getFilterBitmap() { + return false; + } + + /** * Implement this interface if you want to create an animated drawable that * extends {@link android.graphics.drawable.Drawable Drawable}. * Upon retrieving a drawable, use diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 39ef10c..557f563 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -167,6 +167,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } @Override + public boolean getDither() { + return mDrawableContainerState.mDither; + } + + @Override public void setColorFilter(ColorFilter cf) { mDrawableContainerState.mHasColorFilter = (cf != null); diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 72707e6..cc2de22 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -143,7 +143,7 @@ public class GradientDrawable extends Drawable { private final RectF mRect = new RectF(); private Paint mLayerPaint; // internal, used if we use saveLayer() - private boolean mGradientIsDirty; // internal state + private boolean mGradientIsDirty; private boolean mMutated; private Path mRingPath; private boolean mPathIsDirty = true; @@ -174,7 +174,7 @@ public class GradientDrawable extends Drawable { } public GradientDrawable() { - this(new GradientState(Orientation.TOP_BOTTOM, null)); + this(new GradientState(Orientation.TOP_BOTTOM, null), null); } /** @@ -182,7 +182,7 @@ public class GradientDrawable extends Drawable { * of colors for the gradient. */ public GradientDrawable(Orientation orientation, int[] colors) { - this(new GradientState(orientation, colors)); + this(new GradientState(orientation, colors), null); } @Override @@ -822,6 +822,11 @@ public class GradientDrawable extends Drawable { } @Override + public boolean getDither() { + return mGradientState.mDither; + } + + @Override public ColorFilter getColorFilter() { return mColorFilter; } @@ -1018,7 +1023,7 @@ public class GradientDrawable extends Drawable { inflateChildElements(r, parser, attrs, theme); - mGradientState.computeOpacity(); + updateLocalState(r); } @Override @@ -1037,9 +1042,21 @@ public class GradientDrawable extends Drawable { a.recycle(); } + if (state.mTint != null && state.mTint.canApplyTheme()) { + state.mTint.applyTheme(t); + } + + if (state.mColorStateList != null && state.mColorStateList.canApplyTheme()) { + state.mColorStateList.applyTheme(t); + } + + if (state.mStrokeColorStateList != null && state.mStrokeColorStateList.canApplyTheme()) { + state.mStrokeColorStateList.applyTheme(t); + } + applyThemeChildElements(t); - state.computeOpacity(); + updateLocalState(t.getResources()); } /** @@ -1087,8 +1104,6 @@ public class GradientDrawable extends Drawable { if (tint != null) { state.mTint = tint; } - - mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); } @Override @@ -1516,7 +1531,7 @@ public class GradientDrawable extends Drawable { public Drawable mutate() { if (!mMutated && super.mutate() == this) { mGradientState = new GradientState(mGradientState); - initializeWithState(mGradientState); + updateLocalState(null); mMutated = true; } return this; @@ -1577,7 +1592,7 @@ public class GradientDrawable extends Drawable { int[] mAttrCorners; int[] mAttrPadding; - GradientState(Orientation orientation, int[] colors) { + public GradientState(Orientation orientation, int[] colors) { mOrientation = orientation; setColors(colors); } @@ -1634,19 +1649,24 @@ public class GradientDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mThemeAttrs != null || mAttrSize != null || mAttrGradient != null - || mAttrSolid != null || mAttrStroke != null || mAttrCorners != null - || mAttrPadding != null || super.canApplyTheme(); + return mThemeAttrs != null + || mAttrSize != null || mAttrGradient != null + || mAttrSolid != null || mAttrStroke != null + || mAttrCorners != null || mAttrPadding != null + || (mTint != null && mTint.canApplyTheme()) + || (mStrokeColorStateList != null && mStrokeColorStateList.canApplyTheme()) + || (mColorStateList != null && mColorStateList.canApplyTheme()) + || super.canApplyTheme(); } @Override public Drawable newDrawable() { - return new GradientDrawable(this); + return new GradientDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new GradientDrawable(this); + return new GradientDrawable(this, res); } @Override @@ -1751,16 +1771,15 @@ public class GradientDrawable extends Drawable { * * @param state Constant state from which the drawable inherits */ - private GradientDrawable(GradientState state) { + private GradientDrawable(GradientState state, Resources res) { mGradientState = state; - initializeWithState(mGradientState); - - mGradientIsDirty = true; - mMutated = false; + updateLocalState(res); } - private void initializeWithState(GradientState state) { + private void updateLocalState(Resources res) { + final GradientState state = mGradientState; + if (state.mColorStateList != null) { final int[] currentState = getState(); final int stateColor = state.mColorStateList.getColorForState(currentState, 0); @@ -1797,5 +1816,8 @@ public class GradientDrawable extends Drawable { } mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); + mGradientIsDirty = true; + + state.computeOpacity(); } } diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 4aa5f59..daf4427 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -648,6 +648,18 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } @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(); + } else { + return super.getDither(); + } + } + + @Override public void setAlpha(int alpha) { final ChildDrawable[] array = mLayerState.mChildren; final int N = mLayerState.mNum; diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index b87ae92..617bf7c 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -374,6 +374,11 @@ public class NinePatchDrawable extends Drawable { } @Override + public boolean getDither() { + return mPaint == null ? DEFAULT_DITHER : mPaint.isDither(); + } + + @Override public void setAutoMirrored(boolean mirrored) { mNinePatchState.mAutoMirrored = mirrored; } @@ -401,6 +406,8 @@ public class NinePatchDrawable extends Drawable { final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.NinePatchDrawable); updateStateFromTypedArray(a); a.recycle(); + + updateLocalState(r); } /** @@ -467,12 +474,6 @@ public class NinePatchDrawable extends Drawable { if (tint != null) { state.mTint = tint; } - - // Update local properties. - initializeWithState(state, r); - - // Push density applied by setNinePatchState into state. - state.mTargetDensity = mTargetDensity; } @Override @@ -480,23 +481,32 @@ public class NinePatchDrawable extends Drawable { super.applyTheme(t); final NinePatchState state = mNinePatchState; - if (state == null || state.mThemeAttrs == null) { + if (state == null) { return; } - final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.NinePatchDrawable); - try { - updateStateFromTypedArray(a); - } catch (XmlPullParserException e) { - throw new RuntimeException(e); - } finally { - a.recycle(); + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes( + state.mThemeAttrs, R.styleable.NinePatchDrawable); + try { + updateStateFromTypedArray(a); + } catch (XmlPullParserException e) { + throw new RuntimeException(e); + } finally { + a.recycle(); + } + } + + if (state.mTint != null && state.mTint.canApplyTheme()) { + state.mTint.applyTheme(t); } + + updateLocalState(t.getResources()); } @Override public boolean canApplyTheme() { - return mNinePatchState != null && mNinePatchState.mThemeAttrs != null; + return mNinePatchState != null && mNinePatchState.canApplyTheme(); } public Paint getPaint() { @@ -645,7 +655,8 @@ public class NinePatchDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mThemeAttrs != null; + return mThemeAttrs != null + || (mTint != null && mTint.canApplyTheme()); } @Override @@ -680,19 +691,25 @@ public class NinePatchDrawable extends Drawable { private NinePatchDrawable(NinePatchState state, Resources res) { mNinePatchState = state; - initializeWithState(mNinePatchState, res); + updateLocalState(res); + + // Push density applied by setNinePatchState into state. + mNinePatchState.mTargetDensity = mTargetDensity; } /** * Initializes local dynamic properties from state. */ - private void initializeWithState(NinePatchState state, Resources res) { + private void updateLocalState(Resources res) { + final NinePatchState state = mNinePatchState; + if (res != null) { mTargetDensity = res.getDisplayMetrics().densityDpi; } else { mTargetDensity = state.mTargetDensity; } + // If we can, avoid calling any methods that initialize Paint. if (state.mDither != DEFAULT_DITHER) { setDither(state.mDither); diff --git a/graphics/java/android/graphics/drawable/PictureDrawable.java b/graphics/java/android/graphics/drawable/PictureDrawable.java index 6dcda1f..583cffb 100644 --- a/graphics/java/android/graphics/drawable/PictureDrawable.java +++ b/graphics/java/android/graphics/drawable/PictureDrawable.java @@ -88,12 +88,6 @@ public class PictureDrawable extends Drawable { } @Override - public void setFilterBitmap(boolean filter) {} - - @Override - public void setDither(boolean dither) {} - - @Override public void setColorFilter(ColorFilter colorFilter) {} @Override diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 9809606..c7b506e 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,7 +198,7 @@ public class RippleDrawable extends LayerDrawable { setColor(color); ensurePadding(); - initializeFromState(); + updateLocalState(); } @Override @@ -352,6 +352,11 @@ public class RippleDrawable extends LayerDrawable { return true; } + /** + * Sets the ripple color. + * + * @param color Ripple color as a color state list. + */ public void setColor(ColorStateList color) { mState.mColor = color; invalidateSelf(); @@ -370,7 +375,8 @@ public class RippleDrawable extends LayerDrawable { super.inflate(r, parser, attrs, theme); setTargetDensity(r.getDisplayMetrics()); - initializeFromState(); + + updateLocalState(); } @Override @@ -450,21 +456,27 @@ public class RippleDrawable extends LayerDrawable { super.applyTheme(t); final RippleState state = mState; - if (state == null || state.mTouchThemeAttrs == null) { + if (state == null) { return; } - final TypedArray a = t.resolveAttributes(state.mTouchThemeAttrs, - R.styleable.RippleDrawable); - try { - updateStateFromTypedArray(a); - } catch (XmlPullParserException e) { - throw new RuntimeException(e); - } finally { - a.recycle(); + if (state.mTouchThemeAttrs != null) { + final TypedArray a = t.resolveAttributes(state.mTouchThemeAttrs, + R.styleable.RippleDrawable); + try { + updateStateFromTypedArray(a); + } catch (XmlPullParserException e) { + throw new RuntimeException(e); + } finally { + a.recycle(); + } + } + + if (state.mColor != null && state.mColor.canApplyTheme()) { + state.mColor.applyTheme(t); } - initializeFromState(); + updateLocalState(); } @Override @@ -931,7 +943,9 @@ public class RippleDrawable extends LayerDrawable { @Override public boolean canApplyTheme() { - return mTouchThemeAttrs != null || super.canApplyTheme(); + return mTouchThemeAttrs != null + || (mColor != null && mColor.canApplyTheme()) + || super.canApplyTheme(); } @Override @@ -987,10 +1001,10 @@ public class RippleDrawable extends LayerDrawable { mDensity = res.getDisplayMetrics().density; } - initializeFromState(); + updateLocalState(); } - private void initializeFromState() { + private void updateLocalState() { // Initialize from constant state. mMask = findDrawableByLayerId(R.id.mask); } diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index a3d8c92..c208c03 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -329,6 +329,11 @@ public class ShapeDrawable extends Drawable { } @Override + public boolean getDither() { + return mShapeState.mPaint.isDither(); + } + + @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); updateShape(); @@ -402,7 +407,7 @@ public class ShapeDrawable extends Drawable { } // Update local properties. - initializeWithState(mShapeState, r); + updateLocalState(r); } @Override @@ -410,16 +415,23 @@ public class ShapeDrawable extends Drawable { super.applyTheme(t); final ShapeState state = mShapeState; - if (state == null || state.mThemeAttrs == null) { + if (state == null) { return; } - final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ShapeDrawable); - updateStateFromTypedArray(a); - a.recycle(); + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ShapeDrawable); + updateStateFromTypedArray(a); + a.recycle(); + } + + // Apply theme to contained color state list. + if (state.mTint != null && state.mTint.canApplyTheme()) { + state.mTint.applyTheme(t); + } // Update local properties. - initializeWithState(state, t.getResources()); + updateLocalState(t.getResources()); } private void updateStateFromTypedArray(TypedArray a) { @@ -550,7 +562,8 @@ public class ShapeDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mThemeAttrs != null; + return mThemeAttrs != null + || (mTint != null && mTint.canApplyTheme()); } @Override @@ -576,7 +589,7 @@ public class ShapeDrawable extends Drawable { private ShapeDrawable(ShapeState state, Resources res) { mShapeState = state; - initializeWithState(state, res); + updateLocalState(res); } /** @@ -584,8 +597,8 @@ public class ShapeDrawable extends Drawable { * after significant state changes, e.g. from the One True Constructor and * after inflating or applying a theme. */ - private void initializeWithState(ShapeState state, Resources res) { - mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); + private void updateLocalState(Resources res) { + mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, mShapeState.mTintMode); } /** diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 8b0f635..f937ddb 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -369,8 +369,13 @@ public class VectorDrawable extends Drawable { super.applyTheme(t); final VectorDrawableState state = mVectorState; - if (state != null && state.mThemeAttrs != null) { - final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.VectorDrawable); + if (state == null) { + return; + } + + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes( + state.mThemeAttrs, R.styleable.VectorDrawable); try { state.mCacheDirty = true; updateStateFromTypedArray(a); @@ -379,14 +384,20 @@ public class VectorDrawable extends Drawable { } finally { a.recycle(); } + } - mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); + // Apply theme to contained color state list. + if (state.mTint != null && state.mTint.canApplyTheme()) { + state.mTint.applyTheme(t); } final VPathRenderer path = state.mVPathRenderer; if (path != null && path.canApplyTheme()) { path.applyTheme(t); } + + // Update local state. + mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); } /** @@ -750,7 +761,9 @@ public class VectorDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mThemeAttrs != null || (mVPathRenderer != null && mVPathRenderer.canApplyTheme()) + return mThemeAttrs != null + || (mVPathRenderer != null && mVPathRenderer.canApplyTheme()) + || (mTint != null && mTint.canApplyTheme()) || super.canApplyTheme(); } @@ -913,9 +926,10 @@ public class VectorDrawable extends Drawable { // Basically the Mfinal = Mviewport * M0 * M1 * M2; // Mi the local matrix at level i of the group tree. currentGroup.mStackedMatrix.set(currentMatrix); - currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); + // Save the current clip information, which is local to this group. + canvas.save(); // Draw the group tree in the same order as the XML file. for (int i = 0; i < currentGroup.mChildren.size(); i++) { Object child = currentGroup.mChildren.get(i); @@ -928,6 +942,7 @@ public class VectorDrawable extends Drawable { drawPath(currentGroup, childPath, canvas, w, h, filter); } } + canvas.restore(); } public void draw(Canvas canvas, int w, int h, ColorFilter filter) { |