summaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2009-07-22 21:48:55 -0700
committerDianne Hackborn <hackbod@google.com>2009-07-24 10:47:15 -0700
commit11ea33471e1a14a8594f0b2cd012d86340dd3bd8 (patch)
treebb73c079d8bb21c19fa913b8fd9c587a9089ea84 /graphics
parent3b99e64e5899030b5d6f8201cb56cd149c80b24d (diff)
downloadframeworks_base-11ea33471e1a14a8594f0b2cd012d86340dd3bd8.zip
frameworks_base-11ea33471e1a14a8594f0b2cd012d86340dd3bd8.tar.gz
frameworks_base-11ea33471e1a14a8594f0b2cd012d86340dd3bd8.tar.bz2
Allow for screen density drawables in compatibility mode.
This change allows us to use drawables that match the current screen density even when being loaded in compatibility mode. In this case, the bitmap is loaded in the screen density, and the bitmap and nine-patch drawables take care of accounting for the density difference. This should be safe for existing applications, for the most part, since they shouldn't really be pulling the bitmap out of the drawable. For the small rare chance of them breaking, it worth getting the correct graphics. Also this will only happen when there is actually a resource of the matching density, and no existing apps should have resources for anything besides the default density (though of course all of the framework resources will be available in the native density). As part of this, the bitmap density API has been changed to a single integer provider the DPI unit density.
Diffstat (limited to 'graphics')
-rw-r--r--graphics/java/android/graphics/Bitmap.java176
-rw-r--r--graphics/java/android/graphics/BitmapFactory.java180
-rw-r--r--graphics/java/android/graphics/Canvas.java86
-rw-r--r--graphics/java/android/graphics/NinePatch.java31
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java128
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java32
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java115
7 files changed, 465 insertions, 283 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index df659ef..bb19229 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -30,11 +30,11 @@ public final class Bitmap implements Parcelable {
/**
* Indicates that the bitmap was created for an unknown pixel density.
*
- * @see Bitmap#getDensityScale()
- * @see Bitmap#setDensityScale(float)
+ * @see Bitmap#getDensity()
+ * @see Bitmap#setDensity(int)
*/
- public static final float DENSITY_SCALE_UNKNOWN = -1.0f;
-
+ public static final int DENSITY_NONE = 0;
+
// Note: mNativeBitmap is used by FaceDetector_jni.cpp
// Don't change/rename without updating FaceDetector_jni.cpp
private final int mNativeBitmap;
@@ -45,10 +45,10 @@ public final class Bitmap implements Parcelable {
private int mHeight = -1;
private boolean mRecycled;
- private static volatile Matrix sScaleMatrix;
+ // Package-scoped for fast access.
+ /*package*/ int mDensity = DENSITY_NONE;
- private float mDensityScale = DENSITY_SCALE_UNKNOWN;
- private boolean mAutoScaling;
+ private static volatile Matrix sScaleMatrix;
/**
* @noinspection UnusedDeclaration
@@ -70,84 +70,39 @@ public final class Bitmap implements Parcelable {
}
/**
- * <p>Returns the density scale for this bitmap, expressed as a factor of
- * the default density (160.) For instance, a bitmap designed for
- * displays with a density of 240 will have a density scale of 1.5 whereas a bitmap
- * designed for a density of 160 will have a density scale of 1.0.</p>
+ * <p>Returns the density for this bitmap.</p>
*
- * <p>The default density scale is {@link #DENSITY_SCALE_UNKNOWN}.</p>
+ * <p>The default density scale is {@link #DENSITY_NONE}.</p>
*
- * @return A scaling factor of the default density (160) or {@link #DENSITY_SCALE_UNKNOWN}
+ * @return A scaling factor of the default density (160) or {@link #DENSITY_NONE}
* if the scaling factor is unknown.
*
- * @see #setDensityScale(float)
- * @see #isAutoScalingEnabled()
- * @see #setAutoScalingEnabled(boolean)
+ * @see #setDensity(int)
* @see android.util.DisplayMetrics#DENSITY_DEFAULT
- * @see android.util.DisplayMetrics#density
- * @see #DENSITY_SCALE_UNKNOWN
+ * @see android.util.DisplayMetrics#densityDpi
+ * @see #DENSITY_NONE
*/
- public float getDensityScale() {
- return mDensityScale;
+ public int getDensity() {
+ return mDensity;
}
/**
- * <p>Specifies the density scale for this bitmap, expressed as a factor of
- * the default density (160.) For instance, a bitmap designed for
- * displays with a density of 240 will have a density scale of 1.5 whereas a bitmap
- * designed for a density of 160 will have a density scale of 1.0.</p>
+ * <p>Specifies the density for this bitmap. When the bitmap is
+ * drawn to a Canvas that also has a density, it will be scaled
+ * appropriately.</p>
*
- * @param densityScale The density scaling factor to use with this bitmap or
- * {@link #DENSITY_SCALE_UNKNOWN} if the factor is unknown.
+ * @param density The density scaling factor to use with this bitmap or
+ * {@link #DENSITY_NONE} if the density is unknown.
*
- * @see #getDensityScale()
- * @see #isAutoScalingEnabled()
- * @see #setAutoScalingEnabled(boolean)
+ * @see #getDensity()
* @see android.util.DisplayMetrics#DENSITY_DEFAULT
- * @see android.util.DisplayMetrics#density
- * @see #DENSITY_SCALE_UNKNOWN
- */
- public void setDensityScale(float densityScale) {
- mDensityScale = densityScale;
- }
-
- /**
- * </p>Indicates whether this bitmap will be automatically be scaled at the
- * target's density at drawing time. If auto scaling is enabled, this bitmap
- * will be drawn with the following scale factor:</p>
- *
- * <pre>scale = (bitmap density scale factor) / (target density scale factor)</pre>
- *
- * <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)
- * @see #getDensityScale()
- * @see #setDensityScale(float)
- */
- public boolean isAutoScalingEnabled() {
- return mAutoScaling;
- }
-
- /**
- * <p>Enables or disables auto scaling for this bitmap. When auto scaling is enabled,
- * the bitmap will be scaled at drawing time to accomodate the drawing target's pixel
- * density. The final scale factor for this bitmap is thus defined:</p>
- *
- * <pre>scale = (bitmap density scale factor) / (target density scale factor)</pre>
- *
- * <p>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>
- *
- * @param autoScalingEnabled True to scale the bitmap at drawing time, false otherwise.
+ * @see android.util.DisplayMetrics#densityDpi
+ * @see #DENSITY_NONE
*/
- public void setAutoScalingEnabled(boolean autoScalingEnabled) {
- mAutoScaling = autoScalingEnabled;
+ public void setDensity(int density) {
+ mDensity = density;
}
-
+
/**
* Sets the nine patch chunk.
*
@@ -455,9 +410,8 @@ public final class Bitmap implements Parcelable {
canvas.drawBitmap(source, srcR, dstR, paint);
// The new bitmap was created from a known bitmap source so assume that
- // they use the same density scale
- bitmap.mDensityScale = source.mDensityScale;
- bitmap.mAutoScaling = source.mAutoScaling;
+ // they use the same density
+ bitmap.mDensity = source.mDensity;
return bitmap;
}
@@ -603,65 +557,71 @@ public final class Bitmap implements Parcelable {
}
/**
- * Convenience method that returns the width of this bitmap divided
- * by the density scale factor.
- *
- * @param canvas The Canvas the bitmap will be drawn to.
- * @return The scaled width of this bitmap, according to the density scale factor.
+ * Convenience for calling {@link #getScaledWidth(int)} with the target
+ * density of the given {@link Canvas}.
*/
public int getScaledWidth(Canvas canvas) {
- final float scale = mDensityScale;
- if (!mAutoScaling || scale < 0) {
- return getWidth();
- }
- return (int)(getWidth() * canvas.getDensityScale() / scale);
+ return scaleFromDensity(getWidth(), mDensity, canvas.mDensity);
}
/**
- * Convenience method that returns the height of this bitmap divided
- * by the density scale factor.
- *
- * @param canvas The Canvas the bitmap will be drawn to.
- * @return The scaled height of this bitmap, according to the density scale factor.
+ * Convenience for calling {@link #getScaledHeight(int)} with the target
+ * density of the given {@link Canvas}.
*/
public int getScaledHeight(Canvas canvas) {
- final float scale = mDensityScale;
- if (!mAutoScaling || scale < 0) {
- return getHeight();
- }
- return (int)(getHeight() * canvas.getDensityScale() / scale);
+ return scaleFromDensity(getHeight(), mDensity, canvas.mDensity);
+ }
+
+ /**
+ * Convenience for calling {@link #getScaledWidth(int)} with the target
+ * density of the given {@link DisplayMetrics}.
+ */
+ public int getScaledWidth(DisplayMetrics metrics) {
+ return scaleFromDensity(getWidth(), mDensity, metrics.densityDpi);
+ }
+
+ /**
+ * Convenience for calling {@link #getScaledHeight(int)} with the target
+ * density of the given {@link DisplayMetrics}.
+ */
+ public int getScaledHeight(DisplayMetrics metrics) {
+ return scaleFromDensity(getHeight(), mDensity, metrics.densityDpi);
}
/**
* Convenience method that returns the width of this bitmap divided
* by the density scale factor.
*
- * @param metrics The target display metrics.
+ * @param targetDensity The density of the target canvas of the bitmap.
* @return The scaled width of this bitmap, according to the density scale factor.
*/
- public int getScaledWidth(DisplayMetrics metrics) {
- final float scale = mDensityScale;
- if (!mAutoScaling || scale < 0) {
- return getWidth();
- }
- return (int)(getWidth() * metrics.density / scale);
+ public int getScaledWidth(int targetDensity) {
+ return scaleFromDensity(getWidth(), mDensity, targetDensity);
}
/**
* Convenience method that returns the height of this bitmap divided
* by the density scale factor.
*
- * @param metrics The target display metrics.
+ * @param targetDensity The density of the target canvas of the bitmap.
* @return The scaled height of this bitmap, according to the density scale factor.
*/
- public int getScaledHeight(DisplayMetrics metrics) {
- final float scale = mDensityScale;
- if (!mAutoScaling || scale < 0) {
- return getHeight();
+ public int getScaledHeight(int targetDensity) {
+ return scaleFromDensity(getHeight(), mDensity, targetDensity);
+ }
+
+ /**
+ * @hide
+ */
+ static public int scaleFromDensity(int size, int sdensity, int tdensity) {
+ if (sdensity == DENSITY_NONE || sdensity == tdensity) {
+ return size;
}
- return (int)(getHeight() * metrics.density / scale);
+
+ // Scale by tdensity / sdensity, rounding up.
+ return ( (size * tdensity) + (sdensity >> 1) ) / sdensity;
}
-
+
/**
* Return the number of bytes between rows in the bitmap's pixels. Note that
* this refers to the pixels as stored natively by the bitmap. If you call
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 76abaa2..c8bed24 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -39,7 +39,6 @@ public class BitmapFactory {
*/
public Options() {
inDither = true;
- inDensity = 0;
inScaled = true;
}
@@ -79,22 +78,87 @@ public class BitmapFactory {
public boolean inDither;
/**
- * The desired pixel density of the bitmap.
+ * The pixel density to use for the bitmap. This will always result
+ * in the returned bitmap having a density set for it (see
+ * {@link Bitmap#setDensity(int) Bitmap.setDensity(int)). In addition,
+ * if {@link #inScaled} is set (which it is by default} and this
+ * density does not match {@link #inTargetDensity}, then the bitmap
+ * will be scaled to the target density before being returned.
+ *
+ * <p>If this is 0,
+ * {@link BitmapFactory#decodeResource(Resources, int)},
+ * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
+ * and {@link BitmapFactory#decodeResourceStream}
+ * will fill in the density associated with the resource. The other
+ * functions will leave it as-is and no density will be applied.
*
- * @see android.util.DisplayMetrics#DENSITY_DEFAULT
- * @see android.util.DisplayMetrics#density
+ * @see #inTargetDensity
+ * @see #inScreenDensity
+ * @see #inScaled
+ * @see Bitmap#setDensity(int)
+ * @see android.util.DisplayMetrics#densityDpi
*/
public int inDensity;
/**
- * </p>If the bitmap is loaded from {@link android.content.res.Resources} and
- * this flag is turned on, the bitmap will be scaled to match the default
- * display's pixel density.</p>
+ * The pixel density of the destination this bitmap will be drawn to.
+ * This is used in conjunction with {@link #inDensity} and
+ * {@link #inScaled} to determine if and how to scale the bitmap before
+ * returning it.
+ *
+ * <p>If this is 0,
+ * {@link BitmapFactory#decodeResource(Resources, int)},
+ * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
+ * and {@link BitmapFactory#decodeResourceStream}
+ * will fill in the density associated the Resources object's
+ * DisplayMetrics. The other
+ * functions will leave it as-is and no scaling for density will be
+ * performed.
+ *
+ * @see #inDensity
+ * @see #inScreenDensity
+ * @see #inScaled
+ * @see android.util.DisplayMetrics#densityDpi
+ */
+ public int inTargetDensity;
+
+ /**
+ * The pixel density of the actual screen that is being used. This is
+ * purely for applications running in density compatibility code, where
+ * {@link #inTargetDensity} is actually the density the application
+ * sees rather than the real screen density.
+ *
+ * <p>By setting this, you
+ * allow the loading code to avoid scaling a bitmap that is currently
+ * in the screen density up/down to the compatibility density. Instead,
+ * if {@link #inDensity} is the same as {@link #inScreenDensity}, the
+ * bitmap will be left as-is. Anything using the resulting bitmap
+ * must also used {@link Bitmap#getScaledWidth(int)
+ * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight
+ * Bitmap.getScaledHeight} to account for any different between the
+ * bitmap's density and the target's density.
+ *
+ * <p>This is never set automatically for the caller by
+ * {@link BitmapFactory} itself. It must be explicitly set, since the
+ * caller must deal with the resulting bitmap in a density-aware way.
+ *
+ * @see #inDensity
+ * @see #inTargetDensity
+ * @see #inScaled
+ * @see android.util.DisplayMetrics#densityDpi
+ */
+ public int inScreenDensity;
+
+ /**
+ * When this flag is set, if {@link #inDensity} and
+ * {@link #inTargetDensity} are not 0, the
+ * bitmap will be scaled to match {@link #inTargetDensity} when loaded,
+ * rather than relying on the graphics system scaling it each time it
+ * is drawn to a Canvas.
*
- * </p>This flag is turned on by default and should be turned off if you need
- * a non-scaled version of the bitmap. In this case,
- * {@link android.graphics.Bitmap#setAutoScalingEnabled(boolean)} can be used
- * to properly scale the bitmap at drawing time.</p>
+ * <p>This flag is turned on by default and should be turned off if you need
+ * a non-scaled version of the bitmap. Nine-patch bitmaps ignore this
+ * flag and are always scaled.
*/
public boolean inScaled;
@@ -235,58 +299,32 @@ public class BitmapFactory {
* Decode a new Bitmap from an InputStream. This InputStream was obtained from
* resources, which we pass to be able to scale the bitmap accordingly.
*/
- public static Bitmap decodeStream(Resources res, TypedValue value, InputStream is,
- Rect pad, Options opts) {
+ public static Bitmap decodeResourceStream(Resources res, TypedValue value,
+ InputStream is, Rect pad, Options opts) {
if (opts == null) {
opts = new Options();
}
- Bitmap bm = decodeStream(is, pad, opts);
-
- if (bm != null && res != null && value != null) {
+ if (opts.inDensity == 0 && value != null) {
final int density = value.density;
- if (density == TypedValue.DENSITY_NONE) {
- return bm;
- }
-
- byte[] np = bm.getNinePatchChunk();
- final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
-
- if (opts.inDensity == 0) {
- opts.inDensity = density == TypedValue.DENSITY_DEFAULT ?
- DisplayMetrics.DENSITY_DEFAULT : density;
- }
- float scale = opts.inDensity / (float) DisplayMetrics.DENSITY_DEFAULT;
-
- if (opts.inScaled || isNinePatch) {
- bm.setDensityScale(1.0f);
- bm.setAutoScalingEnabled(false);
- // Assume we are going to prescale for the screen
- scale = res.getDisplayMetrics().density / scale;
- if (scale != 1.0f) {
- // TODO: This is very inefficient and should be done in native by Skia
- final Bitmap oldBitmap = bm;
- bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
- (int) (bm.getHeight() * scale + 0.5f), true);
- oldBitmap.recycle();
-
- if (isNinePatch) {
- np = nativeScaleNinePatch(np, scale, pad);
- bm.setNinePatchChunk(np);
- }
- }
- } else {
- bm.setDensityScale(scale);
- bm.setAutoScalingEnabled(true);
+ if (density == TypedValue.DENSITY_DEFAULT) {
+ opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
+ } else if (density != TypedValue.DENSITY_NONE) {
+ opts.inDensity = density;
}
}
-
- return bm;
+
+ if (opts.inTargetDensity == 0 && res != null) {
+ opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
+ }
+
+ return decodeStream(is, pad, opts);
}
/**
- * Decode an image referenced by a resource ID.
+ * Synonym for opening the given resource and calling
+ * {@link #decodeResourceStream}.
*
* @param res The resources object containing the image data
* @param id The resource id of the image data
@@ -303,7 +341,7 @@ public class BitmapFactory {
final TypedValue value = new TypedValue();
final InputStream is = res.openRawResource(id, value);
- bm = decodeStream(res, value, is, null, opts);
+ bm = decodeResourceStream(res, value, is, null, opts);
is.close();
} catch (java.io.IOException e) {
/* do nothing.
@@ -315,7 +353,8 @@ public class BitmapFactory {
}
/**
- * Decode an image referenced by a resource ID.
+ * Synonym for {@link #decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}
+ * will null Options.
*
* @param res The resources object containing the image data
* @param id The resource id of the image data
@@ -412,6 +451,39 @@ public class BitmapFactory {
bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
}
+ if (bm == null || opts == null) {
+ return bm;
+ }
+
+ final int density = opts.inDensity;
+ if (density == 0) {
+ return bm;
+ }
+
+ bm.setDensity(density);
+ final int targetDensity = opts.inTargetDensity;
+ 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) {
+ float scale = targetDensity / (float)density;
+ // TODO: This is very inefficient and should be done in native by Skia
+ final Bitmap oldBitmap = bm;
+ bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
+ (int) (bm.getHeight() * scale + 0.5f), true);
+ oldBitmap.recycle();
+
+ if (isNinePatch) {
+ np = nativeScaleNinePatch(np, scale, outPadding);
+ bm.setNinePatchChunk(np);
+ }
+ bm.setDensity(targetDensity);
+ }
+
return bm;
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index da73597..8ecbfbd 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -20,6 +20,7 @@ import android.text.TextUtils;
import android.text.SpannedString;
import android.text.SpannableString;
import android.text.GraphicsOperations;
+import android.util.DisplayMetrics;
import javax.microedition.khronos.opengles.GL;
@@ -47,11 +48,12 @@ public class Canvas {
// optional field set by the caller
private DrawFilter mDrawFilter;
+ // Package-scoped for quick access.
+ /*package*/ int mDensity = DisplayMetrics.DENSITY_DEFAULT;
+
// Used by native code
@SuppressWarnings({"UnusedDeclaration"})
private int mSurfaceFormat;
- @SuppressWarnings({"UnusedDeclaration"})
- private float mDensityScale = 1.0f;
/**
* Construct an empty raster canvas. Use setBitmap() to specify a bitmap to
@@ -76,8 +78,9 @@ public class Canvas {
throwIfRecycled(bitmap);
mNativeCanvas = initRaster(bitmap.ni());
mBitmap = bitmap;
- mDensityScale = bitmap.getDensityScale();
- if (mDensityScale == Bitmap.DENSITY_SCALE_UNKNOWN) mDensityScale = 1.0f;
+ final int density = bitmap.mDensity;
+ mDensity = density == Bitmap.DENSITY_NONE
+ ? DisplayMetrics.DENSITY_DEFAULT : density;
}
/*package*/ Canvas(int nativeCanvas) {
@@ -132,8 +135,9 @@ public class Canvas {
native_setBitmap(mNativeCanvas, bitmap.ni());
mBitmap = bitmap;
- mDensityScale = bitmap.getDensityScale();
- if (mDensityScale == Bitmap.DENSITY_SCALE_UNKNOWN) mDensityScale = 1.0f;
+ final int density = bitmap.mDensity;
+ mDensity = density == Bitmap.DENSITY_NONE
+ ? DisplayMetrics.DENSITY_DEFAULT : density;
}
/**
@@ -172,44 +176,34 @@ public class Canvas {
public native int getHeight();
/**
- * <p>Returns the density scale for this Canvas' backing bitmap, expressed as a
- * factor of the default density (160dpi.) For instance, a bitmap designed for
- * 240dpi displays will have a density scale of 1.5 whereas a bitmap
- * designed for 160dpi will have a density scale of 1.0.</p>
+ * <p>Returns the density for this Canvas' backing bitmap.</p>
*
- * <p>The default density scale is {@link Bitmap#DENSITY_SCALE_UNKNOWN}.</p>
+ * <p>The default density scale is {@link Bitmap#DENSITY_NONE}.</p>
*
* @return A scaling factor of the default density (160dpi) or
- * {@link Bitmap#DENSITY_SCALE_UNKNOWN} if the scaling factor is unknown.
+ * {@link Bitmap#DENSITY_NONE} if the scaling factor is unknown.
*
- * @see #setDensityScale(float)
- * @see Bitmap#getDensityScale()
+ * @see #setDensity(int)
+ * @see Bitmap#getDensity()
*/
- public float getDensityScale() {
- if (mBitmap != null) {
- return mBitmap.getDensityScale();
- }
- return mDensityScale;
+ public int getDensity() {
+ return mDensity;
}
/**
- * <p>Specifies the density scale for this Canvas' backing bitmap, expressed as a
- * factor of the default density (160dpi.) For instance, a bitmap designed for
- * 240dpi displays will have a density scale of 1.5 whereas a bitmap
- * designed for 160dpi will have a density scale of 1.0.</p>
+ * <p>Specifies the density for this Canvas' backing bitmap.
*
- * @param densityScale The density scaling factor to use with this bitmap or
- * {@link Bitmap#DENSITY_SCALE_UNKNOWN} if the factor is unknown.
+ * @param density The density scaling factor to use with this bitmap or
+ * {@link Bitmap#DENSITY_NONE} if the factor is unknown.
*
- * @see #getDensityScale()
- * @see Bitmap#setDensityScale(float)
+ * @see #getDensity()
+ * @see Bitmap#setDensity(int)
*/
- public void setDensityScale(float densityScale) {
+ public void setDensity(int density) {
if (mBitmap != null) {
- mBitmap.setDensityScale(densityScale);
+ mBitmap.setDensity(density);
}
- mDensityScale = densityScale;
- if (mDensityScale == Bitmap.DENSITY_SCALE_UNKNOWN) mDensityScale = 1.0f;
+ mDensity = density;
}
// the SAVE_FLAG constants must match their native equivalents
@@ -945,12 +939,17 @@ public class Canvas {
/**
* Draw the specified bitmap, with its top/left corner at (x,y), using
* the specified paint, transformed by the current matrix.
- * Note: if the paint contains a maskfilter that generates a mask which
+ *
+ * <p>Note: if the paint contains a maskfilter that generates a mask which
* extends beyond the bitmap's original width/height (e.g. BlurMaskFilter),
* then the bitmap will be drawn as if it were in a Shader with CLAMP mode.
* Thus the color outside of the original width/height will be the edge
* color replicated.
*
+ * <p>If the bitmap and canvas have different densities, this function
+ * will take care of automatically scaling the bitmap to draw at the
+ * same density as the canvas.
+ *
* @param bitmap The bitmap to be drawn
* @param left The position of the left side of the bitmap being drawn
* @param top The position of the top side of the bitmap being drawn
@@ -959,20 +958,25 @@ public class Canvas {
public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
throwIfRecycled(bitmap);
native_drawBitmap(mNativeCanvas, bitmap.ni(), left, top,
- paint != null ? paint.mNativePaint : 0, bitmap.isAutoScalingEnabled(),
- bitmap.getDensityScale());
+ paint != null ? paint.mNativePaint : 0, mDensity, bitmap.mDensity);
}
/**
* Draw the specified bitmap, scaling/translating automatically to fill
* the destination rectangle. If the source rectangle is not null, it
* specifies the subset of the bitmap to draw.
- * Note: if the paint contains a maskfilter that generates a mask which
+ *
+ * <p>Note: if the paint contains a maskfilter that generates a mask which
* extends beyond the bitmap's original width/height (e.g. BlurMaskFilter),
* then the bitmap will be drawn as if it were in a Shader with CLAMP mode.
* Thus the color outside of the original width/height will be the edge
* color replicated.
*
+ * <p>This function <em>ignores the density associated with the bitmap</em>.
+ * This is because the source and destination rectangle coordinate
+ * spaces are in their respective densities, so must already have the
+ * appropriate scaling factor applied.
+ *
* @param bitmap The bitmap to be drawn
* @param src May be null. The subset of the bitmap to be drawn
* @param dst The rectangle that the bitmap will be scaled/translated
@@ -992,12 +996,18 @@ public class Canvas {
* Draw the specified bitmap, scaling/translating automatically to fill
* the destination rectangle. If the source rectangle is not null, it
* specifies the subset of the bitmap to draw.
- * Note: if the paint contains a maskfilter that generates a mask which
+ *
+ * <p>Note: if the paint contains a maskfilter that generates a mask which
* extends beyond the bitmap's original width/height (e.g. BlurMaskFilter),
* then the bitmap will be drawn as if it were in a Shader with CLAMP mode.
* Thus the color outside of the original width/height will be the edge
* color replicated.
*
+ * <p>This function <em>ignores the density associated with the bitmap</em>.
+ * This is because the source and destination rectangle coordinate
+ * spaces are in their respective densities, so must already have the
+ * appropriate scaling factor applied.
+ *
* @param bitmap The bitmap to be drawn
* @param src May be null. The subset of the bitmap to be drawn
* @param dst The rectangle that the bitmap will be scaled/translated
@@ -1489,8 +1499,8 @@ public class Canvas {
int paint);
private native void native_drawBitmap(int nativeCanvas, int bitmap,
float left, float top,
- int nativePaintOrZero, boolean autoScale,
- float densityScale);
+ int nativePaintOrZero,
+ int canvasDensity, int bitmapDensity);
private native void native_drawBitmap(int nativeCanvas, int bitmap,
Rect src, RectF dst,
int nativePaintOrZero);
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 778c903..88dfd67 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -68,7 +68,7 @@ public class NinePatch {
}
/**
- * Draw a bitmap to nine patches.
+ * Draw a bitmap of nine patches.
*
* @param canvas A container for the current matrix and clip used to draw the bitmap.
* @param location Where to draw the bitmap.
@@ -76,23 +76,25 @@ public class NinePatch {
public void draw(Canvas canvas, RectF location) {
nativeDraw(canvas.mNativeCanvas, location,
mBitmap.ni(), mChunk,
- mPaint != null ? mPaint.mNativePaint : 0);
+ mPaint != null ? mPaint.mNativePaint : 0,
+ canvas.mDensity, mBitmap.mDensity);
}
/**
- * Draw a bitmap to nine patches.
+ * Draw a bitmap of nine patches.
*
* @param canvas A container for the current matrix and clip used to draw the bitmap.
* @param location Where to draw the bitmap.
*/
public void draw(Canvas canvas, Rect location) {
nativeDraw(canvas.mNativeCanvas, location,
- mBitmap.ni(), mChunk,
- mPaint != null ? mPaint.mNativePaint : 0);
+ mBitmap.ni(), mChunk,
+ mPaint != null ? mPaint.mNativePaint : 0,
+ canvas.mDensity, mBitmap.mDensity);
}
/**
- * Draw a bitmap to nine patches.
+ * Draw a bitmap of nine patches.
*
* @param canvas A container for the current matrix and clip used to draw the bitmap.
* @param location Where to draw the bitmap.
@@ -100,9 +102,18 @@ public class NinePatch {
*/
public void draw(Canvas canvas, Rect location, Paint paint) {
nativeDraw(canvas.mNativeCanvas, location,
- mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0);
+ mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0,
+ canvas.mDensity, mBitmap.mDensity);
}
+ /**
+ * Return the underlying bitmap's density, as per
+ * {@link Bitmap#getDensity() Bitmap.getDensity()}.
+ */
+ public int getDensity() {
+ return mBitmap.mDensity;
+ }
+
public int getWidth() {
return mBitmap.getWidth();
}
@@ -129,9 +140,11 @@ public class NinePatch {
private static native void validateNinePatchChunk(int bitmap, byte[] chunk);
private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
- byte[] c, int paint_instance_or_null);
+ byte[] c, int paint_instance_or_null,
+ int destDensity, int srcDensity);
private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
- byte[] c, int paint_instance_or_null);
+ byte[] c, int paint_instance_or_null,
+ int destDensity, int srcDensity);
private static native int nativeGetTransparentRegion(
int bitmap, byte[] chunk, Rect location);
}
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 5b32246..eade73a 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -63,18 +63,56 @@ public class BitmapDrawable extends Drawable {
private boolean mApplyGravity;
private boolean mRebuildShader;
- private int mBitmapWidth;
- private int mBitmapHeight;
private boolean mMutated;
+
+ private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+ // These are scaled to match the target density.
+ private int mBitmapWidth;
+ private int mBitmapHeight;
+
+ /**
+ * Create an empty drawable, not dealing with density.
+ * @deprecated Use {@link #BitmapDrawable(Resources)} to ensure
+ * that the drawable has correctly set its target density.
+ */
public BitmapDrawable() {
mBitmapState = new BitmapState((Bitmap) null);
}
+ /**
+ * Create an empty drawable, setting initial target density based on
+ * the display metrics of the resources.
+ */
+ public BitmapDrawable(Resources res) {
+ mBitmapState = new BitmapState((Bitmap) null);
+ if (res != null) {
+ setTargetDensity(res.getDisplayMetrics());
+ mBitmapState.mTargetDensity = mTargetDensity;
+ }
+ }
+
+ /**
+ * Create drawable from a bitmap, not dealing with density.
+ * @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure
+ * that the drawable has correctly set its target density.
+ */
public BitmapDrawable(Bitmap bitmap) {
this(new BitmapState(bitmap));
}
+ /**
+ * Create drawable from a bitmap, setting initial target density based on
+ * the display metrics of the resources.
+ */
+ public BitmapDrawable(Resources res, Bitmap bitmap) {
+ this(new BitmapState(bitmap));
+ if (res != null) {
+ setTargetDensity(res.getDisplayMetrics());
+ mBitmapState.mTargetDensity = mTargetDensity;
+ }
+ }
+
public BitmapDrawable(String filepath) {
this(new BitmapState(BitmapFactory.decodeFile(filepath)));
if (mBitmap == null) {
@@ -97,11 +135,15 @@ public class BitmapDrawable extends Drawable {
return mBitmap;
}
+ private void computeBitmapSize() {
+ mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);
+ mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);
+ }
+
private void setBitmap(Bitmap bitmap) {
mBitmap = bitmap;
if (bitmap != null) {
- mBitmapWidth = bitmap.getWidth();
- mBitmapHeight = bitmap.getHeight();
+ computeBitmapSize();
} else {
mBitmapWidth = mBitmapHeight = -1;
}
@@ -114,13 +156,11 @@ public class BitmapDrawable extends Drawable {
*
* @param canvas The Canvas from which the density scale must be obtained.
*
- * @see android.graphics.Bitmap#setDensityScale(float)
- * @see android.graphics.Bitmap#getDensityScale()
- *
- * @hide pending API council approval
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
*/
- public void setDensityScale(Canvas canvas) {
- setDensityScale(canvas.getDensityScale());
+ public void setTargetDensity(Canvas canvas) {
+ setTargetDensity(canvas.getDensity());
}
/**
@@ -128,32 +168,33 @@ public class BitmapDrawable extends Drawable {
*
* @param metrics The DisplayMetrics indicating the density scale for this drawable.
*
- * @see android.graphics.Bitmap#setDensityScale(float)
- * @see android.graphics.Bitmap#getDensityScale()
- *
- * @hide pending API council approval
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
*/
- public void setDensityScale(DisplayMetrics metrics) {
- setDensityScale(metrics.density);
+ public void setTargetDensity(DisplayMetrics metrics) {
+ mTargetDensity = metrics.densityDpi;
+ if (mBitmap != null) {
+ computeBitmapSize();
+ }
}
/**
- * Set the density scale at which this drawable will be rendered.
+ * Set the density at which this drawable will be rendered.
*
* @param density The density scale for this drawable.
*
- * @see android.graphics.Bitmap#setDensityScale(float)
- * @see android.graphics.Bitmap#getDensityScale()
- *
- * @hide pending API council approval
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
*/
- public void setDensityScale(float density) {
- density = (density == Bitmap.DENSITY_SCALE_UNKNOWN ? 1.0f : density);
- mBitmapState.mTargetDensityScale = density;
+ public void setTargetDensity(int density) {
+ mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
+ if (mBitmap != null) {
+ computeBitmapSize();
+ }
}
/** Get the gravity used to position/stretch the bitmap within its bounds.
- See android.view.Gravity
+ * See android.view.Gravity
* @return the gravity applied to the bitmap
*/
public int getGravity() {
@@ -302,7 +343,7 @@ public class BitmapDrawable extends Drawable {
}
mBitmapState.mBitmap = bitmap;
setBitmap(bitmap);
- setDensityScale(r.getDisplayMetrics());
+ setTargetDensity(r.getDisplayMetrics());
final Paint paint = mBitmapState.mPaint;
paint.setAntiAlias(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_antialias,
@@ -332,29 +373,12 @@ public class BitmapDrawable extends Drawable {
@Override
public int getIntrinsicWidth() {
- final Bitmap bitmap = mBitmap;
- final BitmapState state = mBitmapState;
-
- if (!state.mAutoScale || state.mBitmapScale == Bitmap.DENSITY_SCALE_UNKNOWN) {
- return mBitmapWidth;
- } else {
- return bitmap != null ? (int) (mBitmapWidth /
- (state.mBitmapScale / state.mTargetDensityScale) + 0.5f) : -1;
-
- }
+ return mBitmapWidth;
}
@Override
public int getIntrinsicHeight() {
- final Bitmap bitmap = mBitmap;
- final BitmapState state = mBitmapState;
-
- if (!state.mAutoScale || state.mBitmapScale == Bitmap.DENSITY_SCALE_UNKNOWN) {
- return mBitmapHeight;
- } else {
- return bitmap != null ? (int) (mBitmapHeight /
- (state.mBitmapScale / state.mTargetDensityScale) + 0.5f) : -1;
- }
+ return mBitmapHeight;
}
@Override
@@ -380,19 +404,10 @@ public class BitmapDrawable extends Drawable {
Paint mPaint = new Paint(DEFAULT_PAINT_FLAGS);
Shader.TileMode mTileModeX;
Shader.TileMode mTileModeY;
- boolean mAutoScale;
- float mBitmapScale;
- float mTargetDensityScale = 1.0f;
+ int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
BitmapState(Bitmap bitmap) {
mBitmap = bitmap;
- if (bitmap != null) {
- mBitmapScale = bitmap.getDensityScale();
- mAutoScale = bitmap.isAutoScalingEnabled();
- } else {
- mBitmapScale = 1.0f;
- mAutoScale = false;
- }
}
BitmapState(BitmapState bitmapState) {
@@ -401,7 +416,7 @@ public class BitmapDrawable extends Drawable {
mGravity = bitmapState.mGravity;
mTileModeX = bitmapState.mTileModeX;
mTileModeY = bitmapState.mTileModeY;
- mTargetDensityScale = bitmapState.mTargetDensityScale;
+ mTargetDensity = bitmapState.mTargetDensity;
mPaint = new Paint(bitmapState.mPaint);
}
@@ -418,6 +433,7 @@ public class BitmapDrawable extends Drawable {
private BitmapDrawable(BitmapState state) {
mBitmapState = state;
+ mTargetDensity = state.mTargetDensity;
setBitmap(state.mBitmap);
}
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 910e111..0a0e4eb 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -27,6 +27,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.*;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.StateSet;
import android.util.Xml;
import android.util.TypedValue;
@@ -657,9 +658,8 @@ public abstract class Drawable {
}
/**
- * Create a drawable from an inputstream
- *
- * @hide pending API council approval
+ * Create a drawable from an inputstream, using the given resources and
+ * value to determine density information.
*/
public static Drawable createFromResourceStream(Resources res, TypedValue value,
InputStream is, String srcName) {
@@ -675,7 +675,17 @@ public abstract class Drawable {
Rects only to drop them on the floor.
*/
Rect pad = new Rect();
- Bitmap bm = BitmapFactory.decodeStream(res, value, is, pad, null);
+
+ // Special stuff for compatibility mode: if the target density is not
+ // the same as the display density, but the resource -is- the same as
+ // the display density, then don't scale it down to the target density.
+ // This allows us to load the system's density-correct resources into
+ // an application in compatibility mode, without scaling those down
+ // to the compatibility density only to have them scaled back up when
+ // drawn to the screen.
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts);
if (bm != null) {
byte[] np = bm.getNinePatchChunk();
if (np == null || !NinePatch.isNinePatchChunk(np)) {
@@ -754,10 +764,13 @@ public abstract class Drawable {
} else if (name.equals("bitmap")) {
drawable = new BitmapDrawable();
if (r != null) {
- ((BitmapDrawable) drawable).setDensityScale(r.getDisplayMetrics());
+ ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
}
} else if (name.equals("nine-patch")) {
drawable = new NinePatchDrawable();
+ if (r != null) {
+ ((NinePatchDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
+ }
} else {
throw new XmlPullParserException(parser.getPositionDescription() +
": invalid drawable tag " + name);
@@ -812,15 +825,10 @@ public abstract class Drawable {
Rect pad, String srcName) {
if (np != null) {
- return new NinePatchDrawable(bm, np, pad, srcName);
+ return new NinePatchDrawable(res, bm, np, pad, srcName);
}
- final BitmapDrawable drawable = new BitmapDrawable(bm);
- if (res != null) {
- drawable.setDensityScale(res.getDisplayMetrics());
- }
-
- return drawable;
+ return new BitmapDrawable(res, bm);
}
}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index dace96c..d5c8a08 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -20,6 +20,7 @@ import android.graphics.*;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.TypedValue;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -41,24 +42,122 @@ public class NinePatchDrawable extends Drawable {
private Paint mPaint;
private boolean mMutated;
+ private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+
+ // These are scaled to match the target density.
+ private int mBitmapWidth;
+ private int mBitmapHeight;
+
NinePatchDrawable() {
}
+ /**
+ * Create drawable from raw nine-patch data, not dealing with density.
+ * @deprecated Use {@link #NinePatchDrawable(Resources, Bitmap, byte[], Rect, String)}
+ * to ensure that the drawable has correctly set its target density.
+ */
public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) {
this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding));
}
+ /**
+ * Create drawable from raw nine-patch data, setting initial target density
+ * based on the display metrics of the resources.
+ */
+ public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk,
+ Rect padding, String srcName) {
+ this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding));
+ if (res != null) {
+ setTargetDensity(res.getDisplayMetrics());
+ mNinePatchState.mTargetDensity = mTargetDensity;
+ }
+ }
+
+ /**
+ * Create drawable from existing nine-patch, not dealing with density.
+ * @deprecated Use {@link #NinePatchDrawable(Resources, NinePatch)}
+ * to ensure that the drawable has correctly set its target density.
+ */
public NinePatchDrawable(NinePatch patch) {
this(new NinePatchState(patch, null));
}
+ /**
+ * Create drawable from existing nine-patch, setting initial target density
+ * based on the display metrics of the resources.
+ */
+ public NinePatchDrawable(Resources res, NinePatch patch) {
+ this(new NinePatchState(patch, null));
+ if (res != null) {
+ setTargetDensity(res.getDisplayMetrics());
+ mNinePatchState.mTargetDensity = mTargetDensity;
+ }
+ }
+
private void setNinePatchState(NinePatchState state) {
mNinePatchState = state;
mNinePatch = state.mNinePatch;
mPadding = state.mPadding;
+ mTargetDensity = state.mTargetDensity;
if (state.mDither) setDither(state.mDither);
+ if (mNinePatch != null) {
+ computeBitmapSize();
+ }
}
+ /**
+ * Set the density scale at which this drawable will be rendered. This
+ * method assumes the drawable will be rendered at the same density as the
+ * specified canvas.
+ *
+ * @param canvas The Canvas from which the density scale must be obtained.
+ *
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
+ */
+ public void setTargetDensity(Canvas canvas) {
+ setTargetDensity(canvas.getDensity());
+ }
+
+ /**
+ * Set the density scale at which this drawable will be rendered.
+ *
+ * @param metrics The DisplayMetrics indicating the density scale for this drawable.
+ *
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
+ */
+ public void setTargetDensity(DisplayMetrics metrics) {
+ mTargetDensity = metrics.densityDpi;
+ if (mNinePatch != null) {
+ computeBitmapSize();
+ }
+ }
+
+ /**
+ * Set the density at which this drawable will be rendered.
+ *
+ * @param density The density scale for this drawable.
+ *
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
+ */
+ public void setTargetDensity(int density) {
+ mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
+ if (mNinePatch != null) {
+ computeBitmapSize();
+ }
+ }
+
+ private void computeBitmapSize() {
+ final int sdensity = mNinePatch.getDensity();
+ final int tdensity = mTargetDensity;
+ mBitmapWidth = Bitmap.scaleFromDensity(mNinePatch.getWidth(),
+ sdensity, tdensity);
+ mBitmapHeight = Bitmap.scaleFromDensity(mNinePatch.getHeight(),
+ sdensity, tdensity);
+ }
+
// overrides
@Override
@@ -111,6 +210,7 @@ public class NinePatchDrawable extends Drawable {
if (dither) {
options.inDither = false;
}
+ options.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
final Rect padding = new Rect();
Bitmap bitmap = null;
@@ -119,7 +219,7 @@ public class NinePatchDrawable extends Drawable {
final TypedValue value = new TypedValue();
final InputStream is = r.openRawResource(id, value);
- bitmap = BitmapFactory.decodeStream(r, value, is, padding, options);
+ bitmap = BitmapFactory.decodeResourceStream(r, value, is, padding, options);
is.close();
} catch (IOException e) {
@@ -136,6 +236,7 @@ public class NinePatchDrawable extends Drawable {
setNinePatchState(new NinePatchState(
new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"), padding, dither));
+ mNinePatchState.mTargetDensity = mTargetDensity;
a.recycle();
}
@@ -153,7 +254,7 @@ public class NinePatchDrawable extends Drawable {
*/
@Override
public int getIntrinsicWidth() {
- return mNinePatch.getWidth();
+ return mBitmapWidth;
}
/**
@@ -161,17 +262,17 @@ public class NinePatchDrawable extends Drawable {
*/
@Override
public int getIntrinsicHeight() {
- return mNinePatch.getHeight();
+ return mBitmapHeight;
}
@Override
public int getMinimumWidth() {
- return mNinePatch.getWidth();
+ return mBitmapWidth;
}
@Override
public int getMinimumHeight() {
- return mNinePatch.getHeight();
+ return mBitmapHeight;
}
/**
@@ -211,6 +312,7 @@ public class NinePatchDrawable extends Drawable {
final Rect mPadding;
final boolean mDither;
int mChangingConfigurations;
+ int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
NinePatchState(NinePatch ninePatch, Rect padding) {
this(ninePatch, padding, false);
@@ -225,8 +327,9 @@ public class NinePatchDrawable extends Drawable {
NinePatchState(NinePatchState state) {
mNinePatch = new NinePatch(state.mNinePatch);
mPadding = new Rect(state.mPadding);
- mChangingConfigurations = state.mChangingConfigurations;
mDither = state.mDither;
+ mChangingConfigurations = state.mChangingConfigurations;
+ mTargetDensity = state.mTargetDensity;
}
@Override