summaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2009-07-25 19:52:22 -0700
committerJean-Baptiste Queru <jbq@google.com>2009-07-25 21:15:25 -0700
commit2af1b3db3d4f687d008db74b150f149e956b4bc6 (patch)
tree39d7d5bf15667c01f9b6dfe02bdd0e7fa36cd303 /graphics
parent8ecb36eec61f119f500a805b82438aadb3396a19 (diff)
parentcf4550c3198d6b3d92cdc52707fe70d7cc0caa9f (diff)
downloadframeworks_base-2af1b3db3d4f687d008db74b150f149e956b4bc6.zip
frameworks_base-2af1b3db3d4f687d008db74b150f149e956b4bc6.tar.gz
frameworks_base-2af1b3db3d4f687d008db74b150f149e956b4bc6.tar.bz2
Merge korg/donut into korg/master
Diffstat (limited to 'graphics')
-rw-r--r--graphics/java/android/graphics/Bitmap.java108
-rw-r--r--graphics/java/android/graphics/BitmapFactory.java66
-rw-r--r--graphics/java/android/graphics/Canvas.java18
-rw-r--r--graphics/java/android/graphics/Matrix.java44
-rw-r--r--graphics/java/android/graphics/NinePatch.java5
-rw-r--r--graphics/java/android/graphics/Paint.java5
-rw-r--r--graphics/java/android/graphics/Rect.java45
-rw-r--r--graphics/java/android/graphics/Region.java33
-rw-r--r--graphics/java/android/graphics/Typeface.java32
-rw-r--r--graphics/java/android/graphics/drawable/Animatable.java39
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java332
-rw-r--r--graphics/java/android/graphics/drawable/AnimationDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java109
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java72
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java4
15 files changed, 739 insertions, 175 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 0b398bc..e2e93eb 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -16,14 +16,14 @@
package android.graphics;
-import android.os.Parcelable;
import android.os.Parcel;
+import android.os.Parcelable;
+import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
-import java.nio.ShortBuffer;
import java.nio.IntBuffer;
-import java.io.OutputStream;
+import java.nio.ShortBuffer;
public final class Bitmap implements Parcelable {
/**
@@ -32,14 +32,14 @@ public final class Bitmap implements Parcelable {
* @see Bitmap#getDensityScale()
* @see Bitmap#setDensityScale(float)
*
- * @hide pending API council approval
+ * @hide pending API council approval
*/
public static final float DENSITY_SCALE_UNKNOWN = -1.0f;
// Note: mNativeBitmap is used by FaceDetector_jni.cpp
// Don't change/rename without updating FaceDetector_jni.cpp
private final int mNativeBitmap;
-
+
private final boolean mIsMutable;
private byte[] mNinePatchChunk; // may be null
private int mWidth = -1;
@@ -63,7 +63,7 @@ public final class Bitmap implements Parcelable {
if (nativeBitmap == 0) {
throw new RuntimeException("internal error: native bitmap is 0");
}
-
+
// we delete this in our finalizer
mNativeBitmap = nativeBitmap;
mIsMutable = isMutable;
@@ -83,7 +83,7 @@ public final class Bitmap implements Parcelable {
*
* @see #setDensityScale(float)
* @see #isAutoScalingEnabled()
- * @see #setAutoScalingEnabled(boolean)
+ * @see #setAutoScalingEnabled(boolean)
* @see android.util.DisplayMetrics#DEFAULT_DENSITY
* @see android.util.DisplayMetrics#density
* @see #DENSITY_SCALE_UNKNOWN
@@ -105,7 +105,7 @@ public final class Bitmap implements Parcelable {
*
* @see #getDensityScale()
* @see #isAutoScalingEnabled()
- * @see #setAutoScalingEnabled(boolean)
+ * @see #setAutoScalingEnabled(boolean)
* @see android.util.DisplayMetrics#DEFAULT_DENSITY
* @see android.util.DisplayMetrics#density
* @see #DENSITY_SCALE_UNKNOWN
@@ -126,7 +126,7 @@ public final class Bitmap implements Parcelable {
* <p>Auto scaling is turned off by default. If auto scaling is enabled but the
* bitmap has an unknown density scale, then the bitmap will never be automatically
* scaled at drawing time.</p>
- *
+ *
* @return True if the bitmap must be scaled at drawing time, false otherwise.
*
* @see #setAutoScalingEnabled(boolean)
@@ -167,7 +167,7 @@ public final class Bitmap implements Parcelable {
public void setNinePatchChunk(byte[] chunk) {
mNinePatchChunk = chunk;
}
-
+
/**
* Free up the memory associated with this bitmap's pixels, and mark the
* bitmap as "dead", meaning it will throw an exception if getPixels() or
@@ -194,7 +194,7 @@ public final class Bitmap implements Parcelable {
public final boolean isRecycled() {
return mRecycled;
}
-
+
/**
* This is called by methods that want to throw an exception if the bitmap
* has already been recycled.
@@ -204,7 +204,7 @@ public final class Bitmap implements Parcelable {
throw new IllegalStateException(errorMessage);
}
}
-
+
/**
* Common code for checking that x and y are >= 0
*
@@ -246,16 +246,16 @@ public final class Bitmap implements Parcelable {
this.nativeInt = ni;
}
final int nativeInt;
-
+
/* package */ static Config nativeToConfig(int ni) {
return sConfigs[ni];
}
-
+
private static Config sConfigs[] = {
null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
};
}
-
+
/**
* Copy the bitmap's pixels into the specified buffer (allocated by the
* caller). An exception is thrown if the buffer is not large enough to
@@ -275,16 +275,16 @@ public final class Bitmap implements Parcelable {
} else {
throw new RuntimeException("unsupported Buffer subclass");
}
-
+
long bufferSize = (long)elements << shift;
long pixelSize = (long)getRowBytes() * getHeight();
-
+
if (bufferSize < pixelSize) {
throw new RuntimeException("Buffer not large enough for pixels");
}
-
+
nativeCopyPixelsToBuffer(mNativeBitmap, dst);
-
+
// now update the buffer's position
int position = dst.position();
position += pixelSize >> shift;
@@ -299,7 +299,7 @@ public final class Bitmap implements Parcelable {
*/
public void copyPixelsFromBuffer(Buffer src) {
checkRecycled("copyPixelsFromBuffer called on recycled bitmap");
-
+
int elements = src.remaining();
int shift;
if (src instanceof ByteBuffer) {
@@ -311,17 +311,17 @@ public final class Bitmap implements Parcelable {
} else {
throw new RuntimeException("unsupported Buffer subclass");
}
-
+
long bufferBytes = (long)elements << shift;
long bitmapBytes = (long)getRowBytes() * getHeight();
-
+
if (bufferBytes < bitmapBytes) {
throw new RuntimeException("Buffer not large enough for pixels");
}
-
+
nativeCopyPixelsFromBuffer(mNativeBitmap, src);
}
-
+
/**
* Tries to make a new bitmap based on the dimensions of this bitmap,
* setting the new bitmap's config to the one specified, and then copying
@@ -350,7 +350,7 @@ public final class Bitmap implements Parcelable {
if (m == null) {
m = new Matrix();
}
-
+
final int width = src.getWidth();
final int height = src.getHeight();
final float sx = dstWidth / (float)width;
@@ -365,9 +365,9 @@ public final class Bitmap implements Parcelable {
}
}
- return b;
+ return b;
}
-
+
/**
* Returns an immutable bitmap from the source bitmap. The new bitmap may
* be the same object as source, or a copy may have been made.
@@ -390,7 +390,7 @@ public final class Bitmap implements Parcelable {
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) {
return createBitmap(source, x, y, width, height, null, false);
}
-
+
/**
* Returns an immutable bitmap from subset of the source bitmap,
* transformed by the optional matrix.
@@ -400,7 +400,7 @@ public final class Bitmap implements Parcelable {
* @param y The y coordinate of the first pixel in source
* @param width The number of pixels in each row
* @param height The number of rows
- * @param m Option matrix to be applied to the pixels
+ * @param m Optional matrix to be applied to the pixels
* @param filter true if the source should be filtered.
* Only applies if the matrix contains more than just
* translation.
@@ -425,7 +425,7 @@ public final class Bitmap implements Parcelable {
height == source.getHeight() && (m == null || m.isIdentity())) {
return source;
}
-
+
int neww = width;
int newh = height;
Canvas canvas = new Canvas();
@@ -470,7 +470,7 @@ public final class Bitmap implements Parcelable {
return bitmap;
}
-
+
/**
* Returns a mutable bitmap with the specified width and height.
*
@@ -484,7 +484,7 @@ public final class Bitmap implements Parcelable {
bm.eraseColor(0); // start with black/transparent pixels
return bm;
}
-
+
/**
* Returns a immutable bitmap with the specified width and height, with each
* pixel value set to the corresponding value in the colors array.
@@ -593,7 +593,7 @@ public final class Bitmap implements Parcelable {
return nativeCompress(mNativeBitmap, format.nativeInt, quality,
stream, new byte[WORKING_COMPRESS_STORAGE]);
}
-
+
/**
* Returns true if the bitmap is marked as mutable (i.e. can be drawn into)
*/
@@ -610,7 +610,7 @@ public final class Bitmap implements Parcelable {
public final int getHeight() {
return mHeight == -1 ? mHeight = nativeHeight(mNativeBitmap) : mHeight;
}
-
+
/**
* Convenience method that returns the width of this bitmap divided
* by the density scale factor.
@@ -648,7 +648,7 @@ public final class Bitmap implements Parcelable {
public final int getRowBytes() {
return nativeRowBytes(mNativeBitmap);
}
-
+
/**
* If the bitmap's internal config is in one of the public formats, return
* that config, otherwise return null.
@@ -690,7 +690,7 @@ public final class Bitmap implements Parcelable {
checkPixelAccess(x, y);
return nativeGetPixel(mNativeBitmap, x, y);
}
-
+
/**
* Returns in pixels[] a copy of the data in the bitmap. Each value is
* a packed int representing a {@link Color}. The stride parameter allows
@@ -722,7 +722,7 @@ public final class Bitmap implements Parcelable {
nativeGetPixels(mNativeBitmap, pixels, offset, stride,
x, y, width, height);
}
-
+
/**
* Shared code to check for illegal arguments passed to getPixel()
* or setPixel()
@@ -779,7 +779,7 @@ public final class Bitmap implements Parcelable {
throw new ArrayIndexOutOfBoundsException();
}
}
-
+
/**
* Write the specified {@link Color} into the bitmap (assuming it is
* mutable) at the x,y coordinate.
@@ -799,10 +799,10 @@ public final class Bitmap implements Parcelable {
checkPixelAccess(x, y);
nativeSetPixel(mNativeBitmap, x, y, color);
}
-
+
/**
* Replace pixels in the bitmap with the colors in the array. Each element
- * in the array is a packed int prepresenting a {@link Color}
+ * in the array is a packed int prepresenting a {@link Color}
*
* @param pixels The colors to write to the bitmap
* @param offset The index of the first color to read from pixels[]
@@ -834,7 +834,7 @@ public final class Bitmap implements Parcelable {
nativeSetPixels(mNativeBitmap, pixels, offset, stride,
x, y, width, height);
}
-
+
public static final Parcelable.Creator<Bitmap> CREATOR
= new Parcelable.Creator<Bitmap>() {
/**
@@ -884,7 +884,7 @@ public final class Bitmap implements Parcelable {
public Bitmap extractAlpha() {
return extractAlpha(null, null);
}
-
+
/**
* Returns a new bitmap that captures the alpha values of the original.
* These values may be affected by the optional Paint parameter, which
@@ -917,6 +917,22 @@ public final class Bitmap implements Parcelable {
return bm;
}
+ /**
+ * Rebuilds any caches associated with the bitmap that are used for
+ * drawing it. In the case of purgeable bitmaps, this call will attempt to
+ * ensure that the pixels have been decoded.
+ * If this is called on more than one bitmap in sequence, the priority is
+ * given in LRU order (i.e. the last bitmap called will be given highest
+ * priority).
+ *
+ * For bitmaps with no associated caches, this call is effectively a no-op,
+ * and therefore is harmless.
+ */
+ public void prepareToDraw() {
+ nativePrepareToDraw(mNativeBitmap);
+ }
+
+ @Override
protected void finalize() throws Throwable {
try {
nativeDestructor(mNativeBitmap);
@@ -924,7 +940,7 @@ public final class Bitmap implements Parcelable {
super.finalize();
}
}
-
+
//////////// native methods
private static native Bitmap nativeCreate(int[] colors, int offset,
@@ -944,12 +960,12 @@ public final class Bitmap implements Parcelable {
private static native int nativeRowBytes(int nativeBitmap);
private static native int nativeConfig(int nativeBitmap);
private static native boolean nativeHasAlpha(int nativeBitmap);
-
+
private static native int nativeGetPixel(int nativeBitmap, int x, int y);
private static native void nativeGetPixels(int nativeBitmap, int[] pixels,
int offset, int stride, int x,
int y, int width, int height);
-
+
private static native void nativeSetPixel(int nativeBitmap, int x, int y,
int color);
private static native void nativeSetPixels(int nativeBitmap, int[] colors,
@@ -969,6 +985,8 @@ public final class Bitmap implements Parcelable {
int nativePaint,
int[] offsetXY);
+ private static native void nativePrepareToDraw(int nativeBitmap);
+
/* package */ final int ni() {
return mNativeBitmap;
}
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 3813d8f..e5a9aab 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -18,18 +18,18 @@ package android.graphics;
import android.content.res.AssetManager;
import android.content.res.Resources;
-import android.util.TypedValue;
import android.util.DisplayMetrics;
+import android.util.TypedValue;
import java.io.BufferedInputStream;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
-import java.io.InputStream;
import java.io.IOException;
-import java.io.FileDescriptor;
+import java.io.InputStream;
/**
- * Creates Bitmap objects from various sources, including files, streams,
- * and byte-arrays.
+ * Creates Bitmap objects from various sources, including files, streams,
+ * and byte-arrays.
*/
public class BitmapFactory {
public static class Options {
@@ -62,7 +62,7 @@ public class BitmapFactory {
* Also, powers of 2 are often faster/easier for the decoder to honor.
*/
public int inSampleSize;
-
+
/**
* If this is non-null, the decoder will try to decode into this
* internal configuration. If it is null, or the request cannot be met,
@@ -71,7 +71,7 @@ public class BitmapFactory {
* as if it has per-pixel alpha (requiring a config that also does).
*/
public Bitmap.Config inPreferredConfig;
-
+
/**
* If dither is true, the decoder will atttempt to dither the decoded
* image.
@@ -103,6 +103,32 @@ public class BitmapFactory {
public boolean inScaled;
/**
+ * If this is set to true, then the resulting bitmap will allocate its
+ * pixels such that they can be purged if the system needs to reclaim
+ * memory. In that instance, when the pixels need to be accessed again
+ * (e.g. the bitmap is drawn, getPixels() is called), they will be
+ * automatically re-decoded.
+ *
+ * For the re-decode to happen, the bitmap must have access to the
+ * encoded data, either by sharing a reference to the input
+ * or by making a copy of it. This distinction is controlled by
+ * inInputShareable. If this is true, then the bitmap may keep a shallow
+ * reference to the input. If this is false, then the bitmap will
+ * explicitly make a copy of the input data, and keep that. Even if
+ * sharing is allowed, the implementation may still decide to make a
+ * deep copy of the input data.
+ */
+ public boolean inPurgeable;
+
+ /**
+ * This field works in conjuction with inPurgeable. If inPurgeable is
+ * false, then this field is ignored. If inPurgeable is true, then this
+ * field determines whether the bitmap can share a reference to the
+ * input data (inputstream, array, etc.) or if it must make a deep copy.
+ */
+ public boolean inInputShareable;
+
+ /**
* The resulting width of the bitmap, set independent of the state of
* inJustDecodeBounds. However, if there is an error trying to decode,
* outWidth will be set to -1.
@@ -121,12 +147,12 @@ public class BitmapFactory {
* If not know, or there is an error, it is set to null.
*/
public String outMimeType;
-
+
/**
* Temp storage to use for decoding. Suggest 16K or so.
*/
public byte[] inTempStorage;
-
+
private native void requestCancel();
/**
@@ -137,7 +163,7 @@ public class BitmapFactory {
* if the operation is canceled.
*/
public boolean mCancel;
-
+
/**
* This can be called from another thread while this options object is
* inside a decode... call. Calling this will notify the decoder that
@@ -219,7 +245,7 @@ public class BitmapFactory {
if (opts.inDensity == 0) {
opts.inDensity = density == TypedValue.DENSITY_DEFAULT ?
DisplayMetrics.DEFAULT_DENSITY : density;
- }
+ }
float scale = opts.inDensity / (float) DisplayMetrics.DEFAULT_DENSITY;
if (opts.inScaled || isNinePatch) {
@@ -261,7 +287,7 @@ public class BitmapFactory {
*/
public static Bitmap decodeResource(Resources res, int id, Options opts) {
Bitmap bm = null;
-
+
try {
final TypedValue value = new TypedValue();
final InputStream is = res.openRawResource(id, value);
@@ -276,7 +302,7 @@ public class BitmapFactory {
}
return bm;
}
-
+
/**
* Decode an image referenced by a resource ID.
*
@@ -307,7 +333,7 @@ public class BitmapFactory {
}
return nativeDecodeByteArray(data, offset, length, opts);
}
-
+
/**
* Decode an immutable bitmap from the specified byte array.
*
@@ -320,13 +346,13 @@ public class BitmapFactory {
public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
return decodeByteArray(data, offset, length, null);
}
-
+
/**
* Decode an input stream into a bitmap. If the input stream is null, or
* cannot be used to decode a bitmap, the function returns null.
* The stream's position will be where ever it was after the encoded data
* was read.
- *
+ *
* @param is The input stream that holds the raw data to be decoded into a
* bitmap.
* @param outPadding If not null, return the padding rect for the bitmap if
@@ -345,7 +371,7 @@ public class BitmapFactory {
if (is == null) {
return null;
}
-
+
// we need mark/reset to work properly
if (!is.markSupported()) {
@@ -383,7 +409,7 @@ public class BitmapFactory {
* cannot be used to decode a bitmap, the function returns null.
* The stream's position will be where ever it was after the encoded data
* was read.
- *
+ *
* @param is The input stream that holds the raw data to be decoded into a
* bitmap.
* @return The decoded bitmap, or null if the image data could not be
@@ -411,7 +437,7 @@ public class BitmapFactory {
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
return nativeDecodeFileDescriptor(fd, outPadding, opts);
}
-
+
/**
* Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
* return null. The position within the descriptor will not be changed when
@@ -423,7 +449,7 @@ public class BitmapFactory {
public static Bitmap decodeFileDescriptor(FileDescriptor fd) {
return nativeDecodeFileDescriptor(fd, null, null);
}
-
+
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
Rect padding, Options opts);
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 32ecd9f..4498e1a 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -112,7 +112,9 @@ public class Canvas {
* on behalf of the Canvas. Any subsequent drawing with a GL-backed Canvas
* will have to recreate those resources.
*/
- public static native void freeGlCaches();
+ public static void freeGlCaches() {
+ freeCaches();
+ }
/**
* Specify a bitmap for the canvas to draw into.
@@ -1402,9 +1404,21 @@ public class Canvas {
protected void finalize() throws Throwable {
super.finalize();
- finalizer(mNativeCanvas);
+ // If the constructor threw an exception before setting mNativeCanvas, the native finalizer
+ // must not be invoked.
+ if (mNativeCanvas != 0) {
+ finalizer(mNativeCanvas);
+ }
}
+ /**
+ * Free up as much memory as possible from private caches (e.g. fonts,
+ * images)
+ *
+ * @hide - for now
+ */
+ public static native void freeCaches();
+
private static native int initRaster(int nativeBitmapOrZero);
private static native int initGL();
private static native void native_setBitmap(int nativeCanvas, int bitmap);
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index 2681eae..f549900 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -16,6 +16,8 @@
package android.graphics;
+import java.io.PrintWriter;
+
/**
* The Matrix class holds a 3x3 matrix for transforming coordinates.
@@ -539,17 +541,49 @@ public class Matrix {
}
public String toString() {
- return "Matrix{" + toShortString() + "}";
+ StringBuilder sb = new StringBuilder(64);
+ sb.append("Matrix{");
+ toShortString(sb);
+ sb.append('}');
+ return sb.toString();
}
public String toShortString() {
+ StringBuilder sb = new StringBuilder(64);
+ toShortString(sb);
+ return sb.toString();
+ }
+
+ /**
+ * @hide
+ */
+ public void toShortString(StringBuilder sb) {
+ float[] values = new float[9];
+ getValues(values);
+ sb.append('[');
+ sb.append(values[0]); sb.append(", "); sb.append(values[1]); sb.append(", ");
+ sb.append(values[2]); sb.append("][");
+ sb.append(values[3]); sb.append(", "); sb.append(values[4]); sb.append(", ");
+ sb.append(values[5]); sb.append("][");
+ sb.append(values[6]); sb.append(", "); sb.append(values[7]); sb.append(", ");
+ sb.append(values[8]); sb.append(']');
+ }
+
+ /**
+ * Print short string, to optimize dumping.
+ * @hide
+ */
+ public void printShortString(PrintWriter pw) {
float[] values = new float[9];
getValues(values);
- return "[" +
- values[0] + ", " + values[1] + ", " + values[2] + "][" +
- values[3] + ", " + values[4] + ", " + values[5] + "][" +
- values[6] + ", " + values[7] + ", " + values[8] + "]";
+ pw.print('[');
+ pw.print(values[0]); pw.print(", "); pw.print(values[1]); pw.print(", ");
+ pw.print(values[2]); pw.print("][");
+ pw.print(values[3]); pw.print(", "); pw.print(values[4]); pw.print(", ");
+ pw.print(values[5]); pw.print("][");
+ pw.print(values[6]); pw.print(", "); pw.print(values[7]); pw.print(", ");
+ pw.print(values[8]); pw.print(']');
}
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 2b24ef2..778c903 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -57,7 +57,9 @@ public class NinePatch {
mBitmap = patch.mBitmap;
mChunk = patch.mChunk;
mSrcName = patch.mSrcName;
- mPaint = new Paint(patch.mPaint);
+ if (patch.mPaint != null) {
+ mPaint = new Paint(patch.mPaint);
+ }
validateNinePatchChunk(mBitmap.ni(), mChunk);
}
@@ -120,7 +122,6 @@ public class NinePatch {
public native static boolean isNinePatchChunk(byte[] chunk);
- private final Rect mRect = new Rect();
private final Bitmap mBitmap;
private final byte[] mChunk;
private Paint mPaint;
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 81980d9..862e827 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1084,8 +1084,9 @@ public class Paint {
* not null, return in it the actual width measured.
*
* @param text The text to measure
- * @param measureForwards If true, measure forwards, starting at index.
- * Otherwise, measure backwards, starting with the
+ * @param measureForwards If true, measure forwards, starting with the
+ * first character in the string. Otherwise,
+ * measure backwards, starting with the
* last character in the string.
* @param maxWidth The maximum width to accumulate.
* @param measuredWidth Optional. If not null, returns the actual width
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 2005344..50ab566 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -19,6 +19,8 @@ package android.graphics;
import android.os.Parcel;
import android.os.Parcelable;
+import java.io.PrintWriter;
+
/**
* Rect holds four integer coordinates for a rectangle. The rectangle is
* represented by the coordinates of its 4 edges (left, top, right bottom).
@@ -78,14 +80,40 @@ public final class Rect implements Parcelable {
}
public String toString() {
- return "Rect(" + left + ", " + top + " - " + right + ", " + bottom + ")";
+ StringBuilder sb = new StringBuilder(32);
+ sb.append("Rect("); sb.append(left); sb.append(", ");
+ sb.append(top); sb.append(" - "); sb.append(right);
+ sb.append(", "); sb.append(bottom); sb.append(")");
+ return sb.toString();
}
/**
* Return a string representation of the rectangle in a compact form.
*/
public String toShortString() {
- return "[" + left + "," + top + "][" + right + "," + bottom + "]";
+ return toShortString(new StringBuilder(32));
+ }
+
+ /**
+ * Return a string representation of the rectangle in a compact form.
+ * @hide
+ */
+ public String toShortString(StringBuilder sb) {
+ sb.setLength(0);
+ sb.append('['); sb.append(left); sb.append(',');
+ sb.append(top); sb.append("]["); sb.append(right);
+ sb.append(','); sb.append(bottom); sb.append(']');
+ return sb.toString();
+ }
+
+ /**
+ * Print short representation to given writer.
+ * @hide
+ */
+ public void printShortString(PrintWriter pw) {
+ pw.print('['); pw.print(left); pw.print(',');
+ pw.print(top); pw.print("]["); pw.print(right);
+ pw.print(','); pw.print(bottom); pw.print(']');
}
/**
@@ -517,4 +545,17 @@ public final class Rect implements Parcelable {
right = in.readInt();
bottom = in.readInt();
}
+
+ /**
+ * Scales up the rect by the given scale.
+ * @hide
+ */
+ public void scale(float scale) {
+ if (scale != 1.0f) {
+ left *= scale;
+ top *= scale;
+ right *= scale;
+ bottom*= scale;
+ }
+ }
}
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index 544ff4f..2b080aa 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -211,6 +211,26 @@ public class Region implements Parcelable {
*/
public native void translate(int dx, int dy, Region dst);
+ /**
+ * Scale the region by the given scale amount. This re-constructs new region by
+ * scaling the rects that this region consists of. New rectis are computed by scaling
+ * coordinates by float, then rounded by roundf() function to integers. This may results
+ * in less internal rects if 0 < scale < 1. Zero and Negative scale result in
+ * an empty region. If this region is empty, do nothing.
+ *
+ * @hide
+ */
+ public void scale(float scale) {
+ scale(scale, null);
+ }
+
+ /**
+ * Set the dst region to the result of scaling this region by the given scale amount.
+ * If this region is empty, then dst will be set to empty.
+ * @hide
+ */
+ public native void scale(float scale, Region dst);
+
public final boolean union(Rect r) {
return op(r, Op.UNION);
}
@@ -294,7 +314,16 @@ public class Region implements Parcelable {
throw new RuntimeException();
}
}
-
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof Region)) {
+ return false;
+ }
+ Region peer = (Region) obj;
+ return nativeEquals(mNativeRegion, peer.mNativeRegion);
+ }
+
protected void finalize() throws Throwable {
nativeDestructor(mNativeRegion);
}
@@ -340,5 +369,7 @@ public class Region implements Parcelable {
private static native boolean nativeWriteToParcel(int native_region,
Parcel p);
+ private static native boolean nativeEquals(int native_r1, int native_r2);
+
private final int mNativeRegion;
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index c69c92c..e40e84a 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -18,6 +18,8 @@ package android.graphics;
import android.content.res.AssetManager;
+import java.io.File;
+
/**
* The Typeface class specifies the typeface and intrinsic style of a font.
* This is used in the paint, along with optionally Paint settings like
@@ -118,7 +120,27 @@ public class Typeface {
public static Typeface createFromAsset(AssetManager mgr, String path) {
return new Typeface(nativeCreateFromAsset(mgr, path));
}
-
+
+ /**
+ * Create a new typeface from the specified font file.
+ *
+ * @param path The path to the font data.
+ * @return The new typeface.
+ */
+ public static Typeface createFromFile(File path) {
+ return new Typeface(nativeCreateFromFile(path.getAbsolutePath()));
+ }
+
+ /**
+ * Create a new typeface from the specified font file.
+ *
+ * @param path The full path to the font data.
+ * @return The new typeface.
+ */
+ public static Typeface createFromFile(String path) {
+ return new Typeface(nativeCreateFromFile(path));
+ }
+
// don't allow clients to call this directly
private Typeface(int ni) {
native_instance = ni;
@@ -140,14 +162,14 @@ public class Typeface {
}
protected void finalize() throws Throwable {
+ super.finalize();
nativeUnref(native_instance);
}
private static native int nativeCreate(String familyName, int style);
- private static native int nativeCreateFromTypeface(int native_instance,
- int style);
+ private static native int nativeCreateFromTypeface(int native_instance, int style);
private static native void nativeUnref(int native_instance);
private static native int nativeGetStyle(int native_instance);
- private static native int nativeCreateFromAsset(AssetManager mgr,
- String path);
+ private static native int nativeCreateFromAsset(AssetManager mgr, String path);
+ private static native int nativeCreateFromFile(String path);
}
diff --git a/graphics/java/android/graphics/drawable/Animatable.java b/graphics/java/android/graphics/drawable/Animatable.java
new file mode 100644
index 0000000..9dc62c3
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/Animatable.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+/**
+ * Interface that drawables suporting animations should implement.
+ */
+public interface Animatable {
+ /**
+ * Starts the drawable's animation.
+ */
+ void start();
+
+ /**
+ * Stops the drawable's animation.
+ */
+ void stop();
+
+ /**
+ * Indicates whether the animation is running.
+ *
+ * @return True if the animation is running, false otherwise.
+ */
+ boolean isRunning();
+}
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
new file mode 100644
index 0000000..ac96f20
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2009 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.ColorFilter;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.util.Log;
+import android.os.SystemClock;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+import com.android.internal.R;
+
+/**
+ * @hide
+ */
+public class AnimatedRotateDrawable extends Drawable implements Drawable.Callback, Runnable,
+ Animatable {
+
+ private AnimatedRotateState mState;
+ private boolean mMutated;
+ private float mCurrentDegrees;
+ private float mIncrement;
+ private boolean mRunning;
+
+ public AnimatedRotateDrawable() {
+ this(null);
+ }
+
+ private AnimatedRotateDrawable(AnimatedRotateState rotateState) {
+ mState = new AnimatedRotateState(rotateState, this);
+ init();
+ }
+
+ private void init() {
+ final AnimatedRotateState state = mState;
+ mIncrement = 360.0f / (float) state.mFramesCount;
+ final Drawable drawable = state.mDrawable;
+ if (drawable != null) {
+ drawable.setFilterBitmap(true);
+ if (drawable instanceof BitmapDrawable) {
+ ((BitmapDrawable) drawable).setAntiAlias(true);
+ }
+ }
+ }
+
+ public void draw(Canvas canvas) {
+ int saveCount = canvas.save();
+
+ final AnimatedRotateState st = mState;
+ final Drawable drawable = st.mDrawable;
+ final Rect bounds = drawable.getBounds();
+
+ int w = bounds.right - bounds.left;
+ int h = bounds.bottom - bounds.top;
+
+ float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
+ float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
+
+ canvas.rotate(mCurrentDegrees, px, py);
+
+ drawable.draw(canvas);
+
+ canvas.restoreToCount(saveCount);
+ }
+
+ public void start() {
+ if (!mRunning) {
+ mRunning = true;
+ nextFrame();
+ }
+ }
+
+ public void stop() {
+ mRunning = false;
+ unscheduleSelf(this);
+ }
+
+ public boolean isRunning() {
+ return mRunning;
+ }
+
+ private void nextFrame() {
+ unscheduleSelf(this);
+ scheduleSelf(this, SystemClock.uptimeMillis() + mState.mFrameDuration);
+ }
+
+ public void run() {
+ // TODO: This should be computed in draw(Canvas), based on the amount
+ // of time since the last frame drawn
+ mCurrentDegrees += mIncrement;
+ if (mCurrentDegrees > (360.0f - mIncrement)) {
+ mCurrentDegrees = 0.0f;
+ }
+ invalidateSelf();
+ nextFrame();
+ }
+
+ @Override
+ public boolean setVisible(boolean visible, boolean restart) {
+ mState.mDrawable.setVisible(visible, restart);
+ boolean changed = super.setVisible(visible, restart);
+ if (visible) {
+ if (changed || restart) {
+ mCurrentDegrees = 0.0f;
+ nextFrame();
+ }
+ } else {
+ unscheduleSelf(this);
+ }
+ return changed;
+ }
+
+ /**
+ * Returns the drawable rotated by this RotateDrawable.
+ */
+ public Drawable getDrawable() {
+ return mState.mDrawable;
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return super.getChangingConfigurations()
+ | mState.mChangingConfigurations
+ | mState.mDrawable.getChangingConfigurations();
+ }
+
+ public void setAlpha(int alpha) {
+ mState.mDrawable.setAlpha(alpha);
+ }
+
+ public void setColorFilter(ColorFilter cf) {
+ mState.mDrawable.setColorFilter(cf);
+ }
+
+ public int getOpacity() {
+ return mState.mDrawable.getOpacity();
+ }
+
+ public void invalidateDrawable(Drawable who) {
+ if (mCallback != null) {
+ mCallback.invalidateDrawable(this);
+ }
+ }
+
+ public void scheduleDrawable(Drawable who, Runnable what, long when) {
+ if (mCallback != null) {
+ mCallback.scheduleDrawable(this, what, when);
+ }
+ }
+
+ public void unscheduleDrawable(Drawable who, Runnable what) {
+ if (mCallback != null) {
+ mCallback.unscheduleDrawable(this, what);
+ }
+ }
+
+ @Override
+ public boolean getPadding(Rect padding) {
+ return mState.mDrawable.getPadding(padding);
+ }
+
+ @Override
+ public boolean isStateful() {
+ return mState.mDrawable.isStateful();
+ }
+
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ mState.mDrawable.setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mState.mDrawable.getIntrinsicWidth();
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mState.mDrawable.getIntrinsicHeight();
+ }
+
+ @Override
+ public ConstantState getConstantState() {
+ if (mState.canConstantState()) {
+ mState.mChangingConfigurations = super.getChangingConfigurations();
+ return mState;
+ }
+ return null;
+ }
+
+ @Override
+ public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+
+ final TypedArray a = r.obtainAttributes(attrs, R.styleable.AnimatedRotateDrawable);
+
+ super.inflateWithAttributes(r, parser, a, R.styleable.AnimatedRotateDrawable_visible);
+
+ TypedValue tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotX);
+ final boolean pivotXRel = tv.type == TypedValue.TYPE_FRACTION;
+ final float pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
+
+ tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotY);
+ final boolean pivotYRel = tv.type == TypedValue.TYPE_FRACTION;
+ final float pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
+
+ final int framesCount = a.getInt(R.styleable.AnimatedRotateDrawable_framesCount, 12);
+ final int frameDuration = a.getInt(R.styleable.AnimatedRotateDrawable_frameDuration, 150);
+
+ final int res = a.getResourceId(R.styleable.AnimatedRotateDrawable_drawable, 0);
+ Drawable drawable = null;
+ if (res > 0) {
+ drawable = r.getDrawable(res);
+ }
+
+ a.recycle();
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT &&
+ (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ if ((drawable = Drawable.createFromXmlInner(r, parser, attrs)) == null) {
+ Log.w("drawable", "Bad element under <animated-rotate>: "
+ + parser .getName());
+ }
+ }
+
+ if (drawable == null) {
+ Log.w("drawable", "No drawable specified for <animated-rotate>");
+ }
+
+ final AnimatedRotateState rotateState = mState;
+ rotateState.mDrawable = drawable;
+ rotateState.mPivotXRel = pivotXRel;
+ rotateState.mPivotX = pivotX;
+ rotateState.mPivotYRel = pivotYRel;
+ rotateState.mPivotY = pivotY;
+ rotateState.mFramesCount = framesCount;
+ rotateState.mFrameDuration = frameDuration;
+
+ init();
+
+ if (drawable != null) {
+ drawable.setCallback(this);
+ }
+ }
+
+ @Override
+ public Drawable mutate() {
+ if (!mMutated && super.mutate() == this) {
+ mState.mDrawable.mutate();
+ mMutated = true;
+ }
+ return this;
+ }
+
+ final static class AnimatedRotateState extends Drawable.ConstantState {
+ Drawable mDrawable;
+
+ int mChangingConfigurations;
+
+ boolean mPivotXRel;
+ float mPivotX;
+ boolean mPivotYRel;
+ float mPivotY;
+ int mFrameDuration;
+ int mFramesCount;
+
+ private boolean mCanConstantState;
+ private boolean mCheckedConstantState;
+
+ public AnimatedRotateState(AnimatedRotateState source, AnimatedRotateDrawable owner) {
+ if (source != null) {
+ mDrawable = source.mDrawable.getConstantState().newDrawable();
+ mDrawable.setCallback(owner);
+ mPivotXRel = source.mPivotXRel;
+ mPivotX = source.mPivotX;
+ mPivotYRel = source.mPivotYRel;
+ mPivotY = source.mPivotY;
+ mFramesCount = source.mFramesCount;
+ mFrameDuration = source.mFrameDuration;
+ mCanConstantState = mCheckedConstantState = true;
+ }
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return new AnimatedRotateDrawable(this);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+
+ public boolean canConstantState() {
+ if (!mCheckedConstantState) {
+ mCanConstantState = mDrawable.getConstantState() != null;
+ mCheckedConstantState = true;
+ }
+
+ return mCanConstantState;
+ }
+ }
+}
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index bab1703..68718c9 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -71,7 +71,7 @@ import android.util.AttributeSet;
* @attr ref android.R.styleable#AnimationDrawableItem_duration
* @attr ref android.R.styleable#AnimationDrawableItem_drawable
*/
-public class AnimationDrawable extends DrawableContainer implements Runnable {
+public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
private final AnimationState mAnimationState;
private int mCurFrame = -1;
private boolean mMutated;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index ca0ed7e..4f58a0c 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -38,32 +38,32 @@ import android.util.TypedValue;
* dealing with an underlying visual resource that may take a variety of forms.
* Unlike a {@link android.view.View}, a Drawable does not have any facility to
* receive events or otherwise interact with the user.
- *
+ *
* <p>In addition to simple drawing, Drawable provides a number of generic
* mechanisms for its client to interact with what is being drawn:
- *
+ *
* <ul>
* <li> The {@link #setBounds} method <var>must</var> be called to tell the
* Drawable where it is drawn and how large it should be. All Drawables
* should respect the requested size, often simply by scaling their
* imagery. A client can find the preferred size for some Drawables with
* the {@link #getIntrinsicHeight} and {@link #getIntrinsicWidth} methods.
- *
+ *
* <li> The {@link #getPadding} method can return from some Drawables
* information about how to frame content that is placed inside of them.
* For example, a Drawable that is intended to be the frame for a button
* widget would need to return padding that correctly places the label
* inside of itself.
- *
+ *
* <li> The {@link #setState} method allows the client to tell the Drawable
* in which state it is to be drawn, such as "focused", "selected", etc.
* Some drawables may modify their imagery based on the selected state.
- *
+ *
* <li> The {@link #setLevel} method allows the client to supply a single
* continuous controller that can modify the Drawable is displayed, such as
* a battery level or progress level. Some drawables may modify their
* imagery based on the current level.
- *
+ *
* <li> A Drawable can perform animations by calling back to its client
* through the {@link Callback} interface. All clients should support this
* interface (via {@link #setCallback}) so that animations will work. A
@@ -71,7 +71,7 @@ import android.util.TypedValue;
* {@link android.view.View#setBackgroundDrawable(Drawable)} and
* {@link android.widget.ImageView}.
* </ul>
- *
+ *
* Though usually not visible to the application, Drawables may take a variety
* of forms:
*
@@ -96,7 +96,6 @@ import android.util.TypedValue;
* and Internationalization</a>.
*/
public abstract class Drawable {
-
private static final Rect ZERO_BOUNDS_RECT = new Rect();
private int[] mStateSet = StateSet.WILD_CARD;
@@ -131,7 +130,7 @@ public abstract class Drawable {
onBoundsChange(mBounds);
}
}
-
+
/**
* Specify a bounding rectangle for the Drawable. This is where the drawable
* will draw when its draw() method is called.
@@ -151,12 +150,12 @@ public abstract class Drawable {
public final void copyBounds(Rect bounds) {
bounds.set(mBounds);
}
-
+
/**
* Return a copy of the drawable's bounds in a new Rect. This returns the
* same values as getBounds(), but the returned object is guaranteed to not
* be changed later by the drawable (i.e. it retains no reference to this
- * rect). If the caller already has a Rect allocated, call copyBounds(rect)
+ * rect). If the caller already has a Rect allocated, call copyBounds(rect).
*
* @return A copy of the drawable's bounds
*/
@@ -169,27 +168,37 @@ public abstract class Drawable {
* object may be the same object stored in the drawable (though this is not
* guaranteed), so if a persistent copy of the bounds is needed, call
* copyBounds(rect) instead.
+ * You should also not change the object returned by this method as it may
+ * be the same object stored in the drawable.
*
* @return The bounds of the drawable (which may change later, so caller
- * beware).
+ * beware). DO NOT ALTER the returned object as it may change the
+ * stored bounds of this drawable.
+ *
+ * @see #copyBounds()
+ * @see #copyBounds(android.graphics.Rect)
*/
public final Rect getBounds() {
+ if (mBounds == ZERO_BOUNDS_RECT) {
+ mBounds = new Rect();
+ }
+
return mBounds;
}
/**
* Set a mask of the configuration parameters for which this drawable
* may change, requiring that it be re-created.
- *
+ *
* @param configs A mask of the changing configuration parameters, as
* defined by {@link android.content.res.Configuration}.
- *
+ *
* @see android.content.res.Configuration
*/
public void setChangingConfigurations(int configs) {
mChangingConfigurations = configs;
}
-
+
/**
* Return a mask of the configuration parameters for which this drawable
* mau change, requiring that it be re-created. The default implementation
@@ -197,23 +206,23 @@ public abstract class Drawable {
* {@link #setChangingConfigurations(int)} or 0 by default. Subclasses
* may extend this to or in the changing configurations of any other
* drawables they hold.
- *
+ *
* @return Returns a mask of the changing configuration parameters, as
* defined by {@link android.content.res.Configuration}.
- *
+ *
* @see android.content.res.Configuration
*/
public int getChangingConfigurations() {
return mChangingConfigurations;
}
-
+
/**
* Set to true to have the drawable dither its colors when drawn to a device
* with fewer than 8-bits per color component. This can improve the look on
* those devices, but can also slow down the drawing a little.
*/
public void setDither(boolean dither) {}
-
+
/**
* 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,
@@ -235,7 +244,7 @@ public abstract class Drawable {
* Called when the drawable needs to be redrawn. A view at this point
* should invalidate itself (or at least the part of itself where the
* drawable appears).
- *
+ *
* @param who The drawable that is requesting the update.
*/
public void invalidateDrawable(Drawable who);
@@ -246,7 +255,7 @@ public abstract class Drawable {
* {@link android.os.Handler#postAtTime(Runnable, Object, long)} with
* the parameters <var>(what, who, when)</var> to perform the
* scheduling.
- *
+ *
* @param who The drawable being scheduled.
* @param what The action to execute.
* @param when The time (in milliseconds) to run. The timebase is
@@ -260,7 +269,7 @@ public abstract class Drawable {
* generally simply call
* {@link android.os.Handler#removeCallbacks(Runnable, Object)} with
* the parameters <var>(what, who)</var> to unschedule the drawable.
- *
+ *
* @param who The drawable being unscheduled.
* @param what The action being unscheduled.
*/
@@ -270,7 +279,7 @@ public abstract class Drawable {
/**
* Bind a {@link Callback} object to this Drawable. Required for clients
* that want to support animated drawables.
- *
+ *
* @param cb The client's Callback implementation.
*/
public final void setCallback(Callback cb) {
@@ -281,7 +290,7 @@ public abstract class Drawable {
* Use the current {@link Callback} implementation to have this Drawable
* redrawn. Does nothing if there is no Callback attached to the
* Drawable.
- *
+ *
* @see Callback#invalidateDrawable
*/
public void invalidateSelf()
@@ -295,10 +304,10 @@ public abstract class Drawable {
* Use the current {@link Callback} implementation to have this Drawable
* scheduled. Does nothing if there is no Callback attached to the
* Drawable.
- *
+ *
* @param what The action being scheduled.
* @param when The time (in milliseconds) to run.
- *
+ *
* @see Callback#scheduleDrawable
*/
public void scheduleSelf(Runnable what, long when)
@@ -312,9 +321,9 @@ public abstract class Drawable {
* Use the current {@link Callback} implementation to have this Drawable
* unscheduled. Does nothing if there is no Callback attached to the
* Drawable.
- *
+ *
* @param what The runnable that you no longer want called.
- *
+ *
* @see Callback#unscheduleDrawable
*/
public void unscheduleSelf(Runnable what)
@@ -329,13 +338,13 @@ public abstract class Drawable {
* 255 means fully opaque.
*/
public abstract void setAlpha(int alpha);
-
+
/**
* Specify an optional colorFilter for the drawable. Pass null to remove
* any filters.
*/
public abstract void setColorFilter(ColorFilter cf);
-
+
/**
* Specify a color and porterduff mode to be the colorfilter for this
* drawable.
@@ -343,7 +352,7 @@ public abstract class Drawable {
public void setColorFilter(int color, PorterDuff.Mode mode) {
setColorFilter(new PorterDuffColorFilter(color, mode));
}
-
+
public void clearColorFilter() {
setColorFilter(null);
}
@@ -352,34 +361,34 @@ public abstract class Drawable {
* Indicates whether this view will change its appearance based on state.
* Clients can use this to determine whether it is necessary to calculate
* their state and call setState.
- *
+ *
* @return True if this view changes its appearance based on state, false
* otherwise.
- *
+ *
* @see #setState(int[])
*/
public boolean isStateful() {
return false;
}
-
+
/**
* Specify a set of states for the drawable. These are use-case specific,
* so see the relevant documentation. As an example, the background for
* widgets like Button understand the following states:
* [{@link android.R.attr#state_focused},
* {@link android.R.attr#state_pressed}].
- *
+ *
* <p>If the new state you are supplying causes the appearance of the
* Drawable to change, then it is responsible for calling
* {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
* true will be returned from this function.
- *
+ *
* <p>Note: The Drawable holds a reference on to <var>stateSet</var>
* until a new state array is given to it, so you must not modify this
* array during that time.</p>
- *
+ *
* @param stateSet The new set of states to be displayed.
- *
+ *
* @return Returns true if this change in state has caused the appearance
* of the Drawable to change (hence requiring an invalidate), otherwise
* returns false.
@@ -402,7 +411,7 @@ public abstract class Drawable {
public int[] getState() {
return mStateSet;
}
-
+
/**
* @return The current drawable that will be used by this drawable. For simple drawables, this
* is just the drawable itself. For drawables that change state like
@@ -422,9 +431,9 @@ public abstract class Drawable {
* Drawable to change, then it is responsible for calling
* {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
* true will be returned from this function.
- *
+ *
* @param level The new level, from 0 (minimum) to 10000 (maximum).
- *
+ *
* @return Returns true if this change in level has caused the appearance
* of the Drawable to change (hence requiring an invalidate), otherwise
* returns false.
@@ -535,7 +544,7 @@ public abstract class Drawable {
* region; subclasses can optionally override this to return an actual
* Region if they want to supply this optimization information, but it is
* not required that they do so.
- *
+ *
* @return Returns null if the Drawables has no transparent region to
* report, else a Region holding the parts of the Drawable's bounds that
* are transparent.
@@ -543,11 +552,11 @@ public abstract class Drawable {
public Region getTransparentRegion() {
return null;
}
-
+
/**
* Override this in your subclass to change appearance if you recognize the
* specified state.
- *
+ *
* @return Returns true if the state change has caused the appearance of
* the Drawable to change (that is, it needs to be drawn), else false
* if it looks the same and there is no need to redraw it since its
@@ -583,13 +592,13 @@ public abstract class Drawable {
public int getIntrinsicHeight() {
return -1;
}
-
+
/**
* Returns the minimum width suggested by this Drawable. If a View uses this
* Drawable as a background, it is suggested that the View use at least this
* value for its width. (There will be some scenarios where this will not be
* possible.) This value should INCLUDE any padding.
- *
+ *
* @return The minimum width suggested by this Drawable. If this Drawable
* doesn't have a suggested minimum width, 0 is returned.
*/
@@ -603,7 +612,7 @@ public abstract class Drawable {
* Drawable as a background, it is suggested that the View use at least this
* value for its height. (There will be some scenarios where this will not be
* possible.) This value should INCLUDE any padding.
- *
+ *
* @return The minimum height suggested by this Drawable. If this Drawable
* doesn't have a suggested minimum height, 0 is returned.
*/
@@ -611,7 +620,7 @@ public abstract class Drawable {
final int intrinsicHeight = getIntrinsicHeight();
return intrinsicHeight > 0 ? intrinsicHeight : 0;
}
-
+
/**
* Return in padding the insets suggested by this Drawable for placing
* content inside the drawable's bounds. Positive values move toward the
@@ -649,7 +658,7 @@ public abstract class Drawable {
/**
* Create a drawable from an inputstream
- *
+ *
* @hide pending API council approval
*/
public static Drawable createFromResourceStream(Resources res, TypedValue value,
@@ -736,6 +745,8 @@ public abstract class Drawable {
drawable = new ClipDrawable();
} else if (name.equals("rotate")) {
drawable = new RotateDrawable();
+ } else if (name.equals("animated-rotate")) {
+ drawable = new AnimatedRotateDrawable();
} else if (name.equals("animation-list")) {
drawable = new AnimationDrawable();
} else if (name.equals("inset")) {
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 29f2a00..376b1df 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -181,7 +181,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public int getOpacity() {
- return mDrawableContainerState.getOpacity();
+ return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT :
+ mDrawableContainerState.getOpacity();
}
public boolean selectDrawable(int idx)
@@ -233,8 +234,10 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
- for (Drawable child : mDrawableContainerState.mDrawables) {
- child.mutate();
+ final int N = mDrawableContainerState.getChildCount();
+ final Drawable[] drawables = mDrawableContainerState.getChildren();
+ for (int i = 0; i < N; i++) {
+ drawables[i].mutate();
}
mMutated = true;
}
@@ -336,13 +339,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return pos;
}
- public final int getChildCount()
- {
+ public final int getChildCount() {
return mNumChildren;
}
- public final Drawable[] getChildren()
- {
+ public final Drawable[] getChildren() {
return mDrawables;
}
@@ -350,13 +351,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
* all frames in the set (false), or to use the padding value of the frame
* being shown (true). Default value is false.
*/
- public final void setVariablePadding(boolean variable)
- {
+ public final void setVariablePadding(boolean variable) {
mVariablePadding = variable;
}
- public final Rect getConstantPadding()
- {
+ public final Rect getConstantPadding() {
if (mVariablePadding) {
return null;
}
@@ -364,11 +363,12 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return mConstantPadding;
}
- Rect r = new Rect(0, 0, 0, 0);
- Rect t = new Rect();
+ final Rect r = new Rect(0, 0, 0, 0);
+ final Rect t = new Rect();
final int N = getChildCount();
- for (int i=0; i<N; i++) {
- if (mDrawables[i].getPadding(t)) {
+ final Drawable[] drawables = mDrawables;
+ for (int i = 0; i < N; i++) {
+ if (drawables[i].getPadding(t)) {
if (t.left > r.left) r.left = t.left;
if (t.top > r.top) r.top = t.top;
if (t.right > r.right) r.right = t.right;
@@ -378,18 +378,15 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return (mConstantPadding=r);
}
- public final void setConstantSize(boolean constant)
- {
+ public final void setConstantSize(boolean constant) {
mConstantSize = constant;
}
- public final boolean isConstantSize()
- {
+ public final boolean isConstantSize() {
return mConstantSize;
}
- public final int getConstantWidth()
- {
+ public final int getConstantWidth() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -397,8 +394,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return mConstantWidth;
}
- public final int getConstantHeight()
- {
+ public final int getConstantHeight() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -406,8 +402,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return mConstantHeight;
}
- public final int getConstantMinimumWidth()
- {
+ public final int getConstantMinimumWidth() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -415,8 +410,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return mConstantMinimumWidth;
}
- public final int getConstantMinimumHeight()
- {
+ public final int getConstantMinimumHeight() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -424,15 +418,15 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return mConstantMinimumHeight;
}
- private void computeConstantSize()
- {
+ private void computeConstantSize() {
mComputedConstantSize = true;
final int N = getChildCount();
+ final Drawable[] drawables = mDrawables;
mConstantWidth = mConstantHeight = 0;
mConstantMinimumWidth = mConstantMinimumHeight = 0;
- for (int i=0; i<N; i++) {
- Drawable dr = mDrawables[i];
+ for (int i = 0; i < N; i++) {
+ Drawable dr = drawables[i];
int s = dr.getIntrinsicWidth();
if (s > mConstantWidth) mConstantWidth = s;
s = dr.getIntrinsicHeight();
@@ -444,23 +438,22 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
}
- public final int getOpacity()
- {
+ public final int getOpacity() {
if (mHaveOpacity) {
return mOpacity;
}
final int N = getChildCount();
- int op = N > 0
- ? mDrawables[0].getOpacity() : PixelFormat.TRANSPARENT;
- for (int i=1; i<N; i++) {
- op = Drawable.resolveOpacity(op, mDrawables[i].getOpacity());
+ final Drawable[] drawables = mDrawables;
+ int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
+ for (int i = 1; i < N; i++) {
+ op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
}
mOpacity = op;
mHaveOpacity = true;
return op;
}
-
+
public final boolean isStateful() {
if (mHaveStateful) {
return mStateful;
@@ -480,8 +473,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return stateful;
}
- public void growArray(int oldSize, int newSize)
- {
+ public void growArray(int oldSize, int newSize) {
Drawable[] newDrawables = new Drawable[newSize];
System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize);
mDrawables = newDrawables;
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 3db45f0..a7a8708 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -880,7 +880,9 @@ public class GradientDrawable extends Drawable {
mShape = state.mShape;
mGradient = state.mGradient;
mOrientation = state.mOrientation;
- mColors = state.mColors.clone();
+ if (state.mColors != null) {
+ mColors = state.mColors.clone();
+ }
if (state.mPositions != null) {
mPositions = state.mPositions.clone();
}