From ec4a50428d5f26a22df3edaf7e5b08f41d5cb54b Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Wed, 4 Apr 2012 10:27:15 -0700 Subject: Embed layout padding in nine patch images - Added a new custom PNG chunk that carries the layout padding ints. - Extract the padding ticks from .9.png images and store in the chunk. - Load the padding information at runtime into Bitmap and NinePatchDrawable. - The new chunk is ordered first so that it doesn't cause a problem in older versions of the platform. Bug: 6087201 Change-Id: I5de46167a1d44b3ec21065b0c165e594b1dc8399 --- graphics/java/android/graphics/Bitmap.java | 36 ++++++++++++++++++++++ graphics/java/android/graphics/BitmapFactory.java | 2 +- .../java/android/graphics/drawable/Drawable.java | 16 +++++++--- .../graphics/drawable/NinePatchDrawable.java | 10 +++++- 4 files changed, 58 insertions(+), 6 deletions(-) (limited to 'graphics/java/android') diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 6f939be0b0b2..ed5b2f6f2ef4 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -16,9 +16,12 @@ package android.graphics; +import android.os.Debug; import android.os.Parcel; import android.os.Parcelable; import android.util.DisplayMetrics; +import android.util.Log; + import java.io.OutputStream; import java.nio.Buffer; import java.nio.ByteBuffer; @@ -57,6 +60,7 @@ public final class Bitmap implements Parcelable { private final boolean mIsMutable; private byte[] mNinePatchChunk; // may be null + private int[] mLayoutBounds; // may be null private int mWidth = -1; private int mHeight = -1; private boolean mRecycled; @@ -95,6 +99,19 @@ public final class Bitmap implements Parcelable { */ /*package*/ Bitmap(int nativeBitmap, byte[] buffer, boolean isMutable, byte[] ninePatchChunk, int density) { + this(nativeBitmap, buffer, isMutable, ninePatchChunk, null, density); + } + + /** + * @noinspection UnusedDeclaration + */ + /* Private constructor that must received an already allocated native + bitmap int (pointer). + + This can be called from JNI code. + */ + /*package*/ Bitmap(int nativeBitmap, byte[] buffer, boolean isMutable, byte[] ninePatchChunk, + int[] layoutBounds, int density) { if (nativeBitmap == 0) { throw new RuntimeException("internal error: native bitmap is 0"); } @@ -106,6 +123,7 @@ public final class Bitmap implements Parcelable { mIsMutable = isMutable; mNinePatchChunk = ninePatchChunk; + mLayoutBounds = layoutBounds; if (density >= 0) { mDensity = density; } @@ -163,6 +181,16 @@ public final class Bitmap implements Parcelable { mNinePatchChunk = chunk; } + /** + * Sets the layout bounds as an array of left, top, right, bottom integers + * @param padding the array containing the padding values + * + * @hide + */ + public void setLayoutBounds(int[] bounds) { + mLayoutBounds = bounds; + } + /** * Free the native object associated with this bitmap, and clear the * reference to the pixel data. This will not free the pixel data synchronously; @@ -689,6 +717,14 @@ public final class Bitmap implements Parcelable { return mNinePatchChunk; } + /** + * @hide + * @return the layout padding [left, right, top, bottom] + */ + public int[] getLayoutBounds() { + return mLayoutBounds; + } + /** * Specifies the known formats a bitmap can be compressed into */ diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index c5705f6b8809..1599e40a8d41 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -424,6 +424,7 @@ public class BitmapFactory { throw new ArrayIndexOutOfBoundsException(); } Bitmap bm = nativeDecodeByteArray(data, offset, length, opts); + if (bm == null && opts != null && opts.inBitmap != null) { throw new IllegalArgumentException("Problem decoding into existing bitmap"); } @@ -554,7 +555,6 @@ public class BitmapFactory { if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) { return bm; } - byte[] np = bm.getNinePatchChunk(); final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np); if (opts.inScaled || isNinePatch) { diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 043adae50443..86e824b9e8ea 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -773,7 +773,13 @@ public abstract class Drawable { np = null; pad = null; } - return drawableFromBitmap(res, bm, np, pad, srcName); + int[] layoutBounds = bm.getLayoutBounds(); + Rect layoutBoundsRect = null; + if (layoutBounds != null) { + layoutBoundsRect = new Rect(layoutBounds[0], layoutBounds[1], + layoutBounds[2], layoutBounds[3]); + } + return drawableFromBitmap(res, bm, np, pad, layoutBoundsRect, srcName); } return null; } @@ -875,7 +881,7 @@ public abstract class Drawable { Bitmap bm = BitmapFactory.decodeFile(pathName); if (bm != null) { - return drawableFromBitmap(null, bm, null, null, pathName); + return drawableFromBitmap(null, bm, null, null, null, pathName); } return null; @@ -956,10 +962,12 @@ public abstract class Drawable { } private static Drawable drawableFromBitmap(Resources res, Bitmap bm, byte[] np, - Rect pad, String srcName) { + Rect pad, Rect layoutBounds, String srcName) { if (np != null) { - return new NinePatchDrawable(res, bm, np, pad, srcName); + NinePatchDrawable npd = new NinePatchDrawable(res, bm, np, pad, srcName); + npd.setLayoutBounds(layoutBounds); + return npd; } return new BitmapDrawable(res, bm); diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 18b8bc737c8e..1272071b2cda 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -47,6 +47,7 @@ public class NinePatchDrawable extends Drawable { private NinePatchState mNinePatchState; private NinePatch mNinePatch; private Rect mPadding; + private Rect mLayoutBounds; private Paint mPaint; private boolean mMutated; @@ -98,6 +99,13 @@ public class NinePatchDrawable extends Drawable { mNinePatchState.mTargetDensity = mTargetDensity; } + /** + * @hide + */ + void setLayoutBounds(Rect layoutBounds) { + mLayoutBounds = layoutBounds; + } + private void setNinePatchState(NinePatchState state, Resources res) { mNinePatchState = state; mNinePatch = state.mNinePatch; @@ -258,7 +266,7 @@ public class NinePatchDrawable extends Drawable { } options.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - final Rect padding = new Rect(); + final Rect padding = new Rect(); Bitmap bitmap = null; try { -- cgit v1.2.3-59-g8ed1b