Merge "Fix NinePatchDrawable handling of density changes" into nyc-dev

This commit is contained in:
Alan Viverette
2016-02-23 19:56:22 +00:00
committed by Android (Google) Code Review
5 changed files with 224 additions and 188 deletions

View File

@@ -11947,6 +11947,8 @@ package android.graphics {
ctor public Outline(android.graphics.Outline);
method public boolean canClip();
method public float getAlpha();
method public float getRadius();
method public boolean getRect(android.graphics.Rect);
method public boolean isEmpty();
method public void offset(int, int);
method public void set(android.graphics.Outline);
@@ -12974,12 +12976,10 @@ package android.graphics.drawable {
ctor public deprecated NinePatchDrawable(android.graphics.NinePatch);
ctor public NinePatchDrawable(android.content.res.Resources, android.graphics.NinePatch);
method public void draw(android.graphics.Canvas);
method public android.graphics.NinePatch getNinePatch();
method public int getOpacity();
method public android.graphics.Paint getPaint();
method public void setAlpha(int);
method public void setColorFilter(android.graphics.ColorFilter);
method public void setNinePatch(android.graphics.NinePatch);
method public void setTargetDensity(android.graphics.Canvas);
method public void setTargetDensity(android.util.DisplayMetrics);
method public void setTargetDensity(int);

View File

@@ -12357,6 +12357,8 @@ package android.graphics {
ctor public Outline(android.graphics.Outline);
method public boolean canClip();
method public float getAlpha();
method public float getRadius();
method public boolean getRect(android.graphics.Rect);
method public boolean isEmpty();
method public void offset(int, int);
method public void set(android.graphics.Outline);
@@ -13384,12 +13386,10 @@ package android.graphics.drawable {
ctor public deprecated NinePatchDrawable(android.graphics.NinePatch);
ctor public NinePatchDrawable(android.content.res.Resources, android.graphics.NinePatch);
method public void draw(android.graphics.Canvas);
method public android.graphics.NinePatch getNinePatch();
method public int getOpacity();
method public android.graphics.Paint getPaint();
method public void setAlpha(int);
method public void setColorFilter(android.graphics.ColorFilter);
method public void setNinePatch(android.graphics.NinePatch);
method public void setTargetDensity(android.graphics.Canvas);
method public void setTargetDensity(android.util.DisplayMetrics);
method public void setTargetDensity(int);

View File

@@ -11955,6 +11955,8 @@ package android.graphics {
ctor public Outline(android.graphics.Outline);
method public boolean canClip();
method public float getAlpha();
method public float getRadius();
method public boolean getRect(android.graphics.Rect);
method public boolean isEmpty();
method public void offset(int, int);
method public void set(android.graphics.Outline);
@@ -12982,12 +12984,10 @@ package android.graphics.drawable {
ctor public deprecated NinePatchDrawable(android.graphics.NinePatch);
ctor public NinePatchDrawable(android.content.res.Resources, android.graphics.NinePatch);
method public void draw(android.graphics.Canvas);
method public android.graphics.NinePatch getNinePatch();
method public int getOpacity();
method public android.graphics.Paint getPaint();
method public void setAlpha(int);
method public void setColorFilter(android.graphics.ColorFilter);
method public void setNinePatch(android.graphics.NinePatch);
method public void setTargetDensity(android.graphics.Canvas);
method public void setTargetDensity(android.util.DisplayMetrics);
method public void setTargetDensity(int);

View File

@@ -18,6 +18,7 @@ package android.graphics;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.drawable.Drawable;
/**
@@ -175,6 +176,34 @@ public final class Outline {
setRoundRect(rect.left, rect.top, rect.right, rect.bottom, radius);
}
/**
* Populates {@code outBounds} with the outline bounds, if set, and returns
* {@code true}. If no outline bounds are set, or if a path has been set
* via {@link #setConvexPath(Path)}, returns {@code false}.
*
* @param outRect the rect to populate with the outline bounds, if set
* @return {@code true} if {@code outBounds} was populated with outline
* bounds, or {@code false} if no outline bounds are set
*/
public boolean getRect(@NonNull Rect outRect) {
if (mRect == null) {
return false;
}
outRect.set(mRect);
return true;
}
/**
* Returns the rounded rect radius, if set, or {@code -1} if a path has
* been set via {@link #setConvexPath(Path)}. A return value of {@code 0}
* indicates a non-rounded rect.
*
* @return the rounded rect radius or {@code -1}
*/
public float getRadius() {
return mRadius;
}
/**
* Sets the outline to the oval defined by input rect.
*/

View File

@@ -66,11 +66,16 @@ import java.util.Collection;
public class NinePatchDrawable extends Drawable {
// dithering helps a lot, and is pretty cheap, so default is true
private static final boolean DEFAULT_DITHER = false;
/** Temporary rect used for density scaling. */
private Rect mTempRect;
private NinePatchState mNinePatchState;
private NinePatch mNinePatch;
private PorterDuffColorFilter mTintFilter;
private Rect mPadding;
private Insets mOpticalInsets = Insets.NONE;
private Rect mOutlineInsets;
private float mOutlineRadius;
private Paint mPaint;
private boolean mMutated;
@@ -86,8 +91,9 @@ public class NinePatchDrawable extends Drawable {
/**
* 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.
* to ensure that the drawable has correctly set its target density.
*/
@Deprecated
public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) {
@@ -101,7 +107,6 @@ public class NinePatchDrawable extends Drawable {
public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk,
Rect padding, String srcName) {
this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), res);
mNinePatchState.mTargetDensity = mTargetDensity;
}
/**
@@ -114,16 +119,17 @@ public class NinePatchDrawable extends Drawable {
Rect padding, Rect opticalInsets, String srcName) {
this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding, opticalInsets),
res);
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.
* to ensure that the drawable has correctly set its target
* density.
*/
@Deprecated
public NinePatchDrawable(NinePatch patch) {
public NinePatchDrawable(@NonNull NinePatch patch) {
this(new NinePatchState(patch, new Rect()), null);
}
@@ -131,9 +137,8 @@ public class NinePatchDrawable extends Drawable {
* Create drawable from existing nine-patch, setting initial target density
* based on the display metrics of the resources.
*/
public NinePatchDrawable(Resources res, NinePatch patch) {
public NinePatchDrawable(@Nullable Resources res, @NonNull NinePatch patch) {
this(new NinePatchState(patch, new Rect()), res);
mNinePatchState.mTargetDensity = mTargetDensity;
}
/**
@@ -146,7 +151,7 @@ public class NinePatchDrawable extends Drawable {
* @see android.graphics.Bitmap#setDensity(int)
* @see android.graphics.Bitmap#getDensity()
*/
public void setTargetDensity(Canvas canvas) {
public void setTargetDensity(@NonNull Canvas canvas) {
setTargetDensity(canvas.getDensity());
}
@@ -158,7 +163,7 @@ public class NinePatchDrawable extends Drawable {
* @see android.graphics.Bitmap#setDensity(int)
* @see android.graphics.Bitmap#getDensity()
*/
public void setTargetDensity(DisplayMetrics metrics) {
public void setTargetDensity(@NonNull DisplayMetrics metrics) {
setTargetDensity(metrics.densityDpi);
}
@@ -171,78 +176,24 @@ public class NinePatchDrawable extends Drawable {
* @see android.graphics.Bitmap#getDensity()
*/
public void setTargetDensity(int density) {
if (density != mTargetDensity) {
mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
if (mNinePatch != null) {
computeBitmapSize();
}
if (density == 0) {
density = DisplayMetrics.DENSITY_DEFAULT;
}
if (mTargetDensity != density) {
mTargetDensity = density;
computeBitmapSize();
invalidateSelf();
}
}
private static Insets scaleFromDensity(Insets insets, int sdensity, int tdensity) {
int left = Drawable.scaleFromDensity(insets.left, sdensity, tdensity, true);
int top = Drawable.scaleFromDensity(insets.top, sdensity, tdensity, true);
int right = Drawable.scaleFromDensity(insets.right, sdensity, tdensity, true);
int bottom = Drawable.scaleFromDensity(insets.bottom, sdensity, tdensity, true);
return Insets.of(left, top, right, bottom);
}
private void computeBitmapSize() {
final int sdensity = mNinePatch.getDensity();
final int tdensity = mTargetDensity;
if (sdensity == tdensity) {
mBitmapWidth = mNinePatch.getWidth();
mBitmapHeight = mNinePatch.getHeight();
mOpticalInsets = mNinePatchState.mOpticalInsets;
} else {
mBitmapWidth = Drawable.scaleFromDensity(
mNinePatch.getWidth(), sdensity, tdensity, true);
mBitmapHeight = Drawable.scaleFromDensity(
mNinePatch.getHeight(), sdensity, tdensity, true);
if (mNinePatchState.mPadding != null && mPadding != null) {
Rect dest = mPadding;
Rect src = mNinePatchState.mPadding;
if (dest == src) {
mPadding = dest = new Rect(src);
}
dest.left = Drawable.scaleFromDensity(src.left, sdensity, tdensity, true);
dest.top = Drawable.scaleFromDensity(src.top, sdensity, tdensity, true);
dest.right = Drawable.scaleFromDensity(src.right, sdensity, tdensity, true);
dest.bottom = Drawable.scaleFromDensity(src.bottom, sdensity, tdensity, true);
}
mOpticalInsets = scaleFromDensity(mNinePatchState.mOpticalInsets, sdensity, tdensity);
}
}
/**
* Sets the nine patch used by this drawable.
*
* @param ninePatch the nine patch for this drawable
*/
public void setNinePatch(NinePatch ninePatch) {
if (mNinePatch != ninePatch) {
mNinePatch = ninePatch;
if (ninePatch != null) {
computeBitmapSize();
} else {
mBitmapWidth = mBitmapHeight = -1;
mOpticalInsets = Insets.NONE;
}
invalidateSelf();
}
}
/**
* @return the nine patch used by this drawable
*/
public NinePatch getNinePatch() {
return mNinePatch;
}
@Override
public void draw(Canvas canvas) {
final Rect bounds = getBounds();
final NinePatchState state = mNinePatchState;
Rect bounds = getBounds();
int restoreToCount = -1;
final boolean clearColorFilter;
if (mTintFilter != null && getPaint().getColorFilter() == null) {
@@ -252,22 +203,52 @@ public class NinePatchDrawable extends Drawable {
clearColorFilter = false;
}
final boolean needsMirroring = needsMirroring();
if (needsMirroring) {
// Mirror the 9patch
canvas.translate(bounds.right - bounds.left, 0);
canvas.scale(-1.0f, 1.0f);
}
final int restoreAlpha;
if (mNinePatchState.mBaseAlpha != 1.0f) {
restoreAlpha = mPaint.getAlpha();
mPaint.setAlpha((int) (restoreAlpha * mNinePatchState.mBaseAlpha + 0.5f));
if (state.mBaseAlpha != 1.0f) {
restoreAlpha = getPaint().getAlpha();
mPaint.setAlpha((int) (restoreAlpha * state.mBaseAlpha + 0.5f));
} else {
restoreAlpha = -1;
}
mNinePatch.draw(canvas, bounds, mPaint);
final boolean needsDensityScaling = canvas.getDensity() == 0;
if (needsDensityScaling) {
restoreToCount = restoreToCount >= 0 ? restoreToCount : canvas.save();
// Apply density scaling.
final float scale = mTargetDensity / (float) state.mNinePatch.getDensity();
final float px = bounds.left;
final float py = bounds.top;
canvas.scale(scale, scale, px, py);
if (mTempRect == null) {
mTempRect = new Rect();
}
// Scale the bounds to match.
final Rect scaledBounds = mTempRect;
scaledBounds.left = bounds.left;
scaledBounds.top = bounds.top;
scaledBounds.right = bounds.left + Math.round(bounds.width() / scale);
scaledBounds.bottom = bounds.top + Math.round(bounds.height() / scale);
bounds = scaledBounds;
}
final boolean needsMirroring = needsMirroring();
if (needsMirroring) {
restoreToCount = restoreToCount >= 0 ? restoreToCount : canvas.save();
// Mirror the 9patch.
final float cx = (bounds.left + bounds.right) / 2.0f;
final float cy = (bounds.top + bounds.bottom) / 2.0f;
canvas.scale(-1.0f, 1.0f, cx, cy);
}
state.mNinePatch.draw(canvas, bounds, mPaint);
if (restoreToCount >= 0) {
canvas.restoreToCount(restoreToCount);
}
if (clearColorFilter) {
mPaint.setColorFilter(null);
@@ -284,38 +265,36 @@ public class NinePatchDrawable extends Drawable {
}
@Override
public boolean getPadding(Rect padding) {
final Rect scaledPadding = mPadding;
if (scaledPadding != null) {
if (needsMirroring()) {
padding.set(scaledPadding.right, scaledPadding.top,
scaledPadding.left, scaledPadding.bottom);
} else {
padding.set(scaledPadding);
}
public boolean getPadding(@NonNull Rect padding) {
if (mPadding != null) {
padding.set(mPadding);
return (padding.left | padding.top | padding.right | padding.bottom) != 0;
} else {
return super.getPadding(padding);
}
return false;
}
@Override
public void getOutline(@NonNull Outline outline) {
final Rect bounds = getBounds();
if (bounds.isEmpty()) return;
if (bounds.isEmpty()) {
return;
}
if (mNinePatchState != null) {
NinePatch.InsetStruct insets = mNinePatchState.mNinePatch.getBitmap().getNinePatchInsets();
if (mNinePatchState != null && mOutlineInsets != null) {
final NinePatch.InsetStruct insets =
mNinePatchState.mNinePatch.getBitmap().getNinePatchInsets();
if (insets != null) {
final Rect outlineInsets = insets.outlineRect;
outline.setRoundRect(bounds.left + outlineInsets.left,
bounds.top + outlineInsets.top,
bounds.right - outlineInsets.right,
bounds.bottom - outlineInsets.bottom,
insets.outlineRadius);
outline.setRoundRect(bounds.left + mOutlineInsets.left,
bounds.top + mOutlineInsets.top,
bounds.right - mOutlineInsets.right,
bounds.bottom - mOutlineInsets.bottom,
mOutlineRadius);
outline.setAlpha(insets.outlineAlpha * (getAlpha() / 255.0f));
return;
}
}
super.getOutline(outline);
}
@@ -324,11 +303,12 @@ public class NinePatchDrawable extends Drawable {
*/
@Override
public Insets getOpticalInsets() {
final Insets opticalInsets = mOpticalInsets;
if (needsMirroring()) {
return Insets.of(mOpticalInsets.right, mOpticalInsets.top,
mOpticalInsets.left, mOpticalInsets.bottom);
return Insets.of(opticalInsets.right, opticalInsets.top,
opticalInsets.left, opticalInsets.bottom);
} else {
return mOpticalInsets;
return opticalInsets;
}
}
@@ -352,7 +332,7 @@ public class NinePatchDrawable extends Drawable {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
public void setColorFilter(@Nullable ColorFilter colorFilter) {
if (mPaint == null && colorFilter == null) {
// Fast common case -- leave at no color filter.
return;
@@ -362,14 +342,14 @@ public class NinePatchDrawable extends Drawable {
}
@Override
public void setTintList(ColorStateList tint) {
public void setTintList(@Nullable ColorStateList tint) {
mNinePatchState.mTint = tint;
mTintFilter = updateTintFilter(mTintFilter, tint, mNinePatchState.mTintMode);
invalidateSelf();
}
@Override
public void setTintMode(PorterDuff.Mode tintMode) {
public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
mNinePatchState.mTintMode = tintMode;
mTintFilter = updateTintFilter(mTintFilter, mNinePatchState.mTint, tintMode);
invalidateSelf();
@@ -409,10 +389,7 @@ public class NinePatchDrawable extends Drawable {
@Override
public boolean isFilterBitmap() {
if (mPaint == null) {
return false;
}
return getPaint().isFilterBitmap();
return mPaint != null && getPaint().isFilterBitmap();
}
@Override
@@ -430,7 +407,7 @@ public class NinePatchDrawable extends Drawable {
/**
* Updates the constant state from the values in the typed array.
*/
private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
private void updateStateFromTypedArray(@NonNull TypedArray a) throws XmlPullParserException {
final Resources r = a.getResources();
final NinePatchState state = mNinePatchState;
@@ -491,12 +468,10 @@ public class NinePatchDrawable extends Drawable {
if (tint != null) {
state.mTint = tint;
}
state.mTargetDensity = Drawable.resolveDensity(r, state.mTargetDensity);
}
@Override
public void applyTheme(Theme t) {
public void applyTheme(@NonNull Theme t) {
super.applyTheme(t);
final NinePatchState state = mNinePatchState;
@@ -528,6 +503,7 @@ public class NinePatchDrawable extends Drawable {
return mNinePatchState != null && mNinePatchState.canApplyTheme();
}
@NonNull
public Paint getPaint() {
if (mPaint == null) {
mPaint = new Paint();
@@ -536,45 +512,26 @@ public class NinePatchDrawable extends Drawable {
return mPaint;
}
/**
* Retrieves the width of the source .png file (before resizing).
*/
@Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
/**
* Retrieves the height of the source .png file (before resizing).
*/
@Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
@Override
public int getMinimumWidth() {
return mBitmapWidth;
}
@Override
public int getMinimumHeight() {
return mBitmapHeight;
}
/**
* Returns a {@link android.graphics.PixelFormat graphics.PixelFormat}
* value of OPAQUE or TRANSLUCENT.
*/
@Override
public int getOpacity() {
return mNinePatch.hasAlpha() || (mPaint != null && mPaint.getAlpha() < 255) ?
PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
return mNinePatchState.mNinePatch.hasAlpha()
|| (mPaint != null && mPaint.getAlpha() < 255) ?
PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
}
@Override
public Region getTransparentRegion() {
return mNinePatch.getTransparentRegion(getBounds());
return mNinePatchState.mNinePatch.getTransparentRegion(getBounds());
}
@Override
@@ -587,7 +544,6 @@ public class NinePatchDrawable extends Drawable {
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
mNinePatchState = new NinePatchState(mNinePatchState);
mNinePatch = mNinePatchState.mNinePatch;
mMutated = true;
}
return this;
@@ -619,8 +575,9 @@ public class NinePatchDrawable extends Drawable {
}
final static class NinePatchState extends ConstantState {
int mChangingConfigurations;
// Values loaded during inflation.
int[] mThemeAttrs = null;
NinePatch mNinePatch = null;
ColorStateList mTint = null;
Mode mTintMode = DEFAULT_TINT_MODE;
@@ -628,10 +585,9 @@ public class NinePatchDrawable extends Drawable {
Insets mOpticalInsets = Insets.NONE;
float mBaseAlpha = 1.0f;
boolean mDither = DEFAULT_DITHER;
int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
boolean mAutoMirrored = false;
int mChangingConfigurations;
int[] mThemeAttrs;
NinePatchState() {
// Empty constructor.
@@ -655,27 +611,24 @@ public class NinePatchDrawable extends Drawable {
mAutoMirrored = autoMirror;
}
// Copy constructor
NinePatchState(@NonNull NinePatchState state) {
// We don't deep-copy any fields because they are all immutable.
mNinePatch = state.mNinePatch;
mTint = state.mTint;
mTintMode = state.mTintMode;
mThemeAttrs = state.mThemeAttrs;
mPadding = state.mPadding;
mOpticalInsets = state.mOpticalInsets;
mBaseAlpha = state.mBaseAlpha;
mDither = state.mDither;
mChangingConfigurations = state.mChangingConfigurations;
mTargetDensity = state.mTargetDensity;
mAutoMirrored = state.mAutoMirrored;
NinePatchState(@NonNull NinePatchState orig) {
mChangingConfigurations = orig.mChangingConfigurations;
mNinePatch = orig.mNinePatch;
mTint = orig.mTint;
mTintMode = orig.mTintMode;
mPadding = orig.mPadding;
mOpticalInsets = orig.mOpticalInsets;
mBaseAlpha = orig.mBaseAlpha;
mDither = orig.mDither;
mAutoMirrored = orig.mAutoMirrored;
mThemeAttrs = orig.mThemeAttrs;
}
@Override
public boolean canApplyTheme() {
return mThemeAttrs != null
|| (mTint != null && mTint.canApplyTheme());
|| (mTint != null && mTint.canApplyTheme())
|| super.canApplyTheme();
}
@Override
@@ -704,44 +657,98 @@ public class NinePatchDrawable extends Drawable {
}
}
private void computeBitmapSize() {
final NinePatch ninePatch = mNinePatchState.mNinePatch;
if (ninePatch == null) {
return;
}
final int sourceDensity = ninePatch.getDensity();
final int targetDensity = mTargetDensity;
final Insets sourceOpticalInsets = mNinePatchState.mOpticalInsets;
if (sourceOpticalInsets != Insets.NONE) {
final int left = Drawable.scaleFromDensity(
sourceOpticalInsets.left, sourceDensity, targetDensity, true);
final int top = Drawable.scaleFromDensity(
sourceOpticalInsets.top, sourceDensity, targetDensity, true);
final int right = Drawable.scaleFromDensity(
sourceOpticalInsets.right, sourceDensity, targetDensity, true);
final int bottom = Drawable.scaleFromDensity(
sourceOpticalInsets.bottom, sourceDensity, targetDensity, true);
mOpticalInsets = Insets.of(left, top, right, bottom);
} else {
mOpticalInsets = Insets.NONE;
}
final Rect sourcePadding = mNinePatchState.mPadding;
if (sourcePadding != null) {
if (mPadding == null) {
mPadding = new Rect();
}
mPadding.left = Drawable.scaleFromDensity(
sourcePadding.left, sourceDensity, targetDensity, false);
mPadding.top = Drawable.scaleFromDensity(
sourcePadding.top, sourceDensity, targetDensity, false);
mPadding.right = Drawable.scaleFromDensity(
sourcePadding.right, sourceDensity, targetDensity, false);
mPadding.bottom = Drawable.scaleFromDensity(
sourcePadding.bottom, sourceDensity, targetDensity, false);
} else {
mPadding = null;
}
mBitmapHeight = Drawable.scaleFromDensity(
ninePatch.getHeight(), sourceDensity, targetDensity, true);
mBitmapWidth = Drawable.scaleFromDensity(
ninePatch.getWidth(), sourceDensity, targetDensity, true);
final NinePatch.InsetStruct insets = ninePatch.getBitmap().getNinePatchInsets();
if (insets != null) {
if (mOutlineInsets == null) {
mOutlineInsets = new Rect();
}
final Rect outlineInsets = insets.outlineRect;
mOutlineInsets.left = Drawable.scaleFromDensity(
outlineInsets.left, sourceDensity, targetDensity, false);
mOutlineInsets.top = Drawable.scaleFromDensity(
outlineInsets.top, sourceDensity, targetDensity, false);
mOutlineInsets.right = Drawable.scaleFromDensity(
outlineInsets.right, sourceDensity, targetDensity, false);
mOutlineInsets.bottom = Drawable.scaleFromDensity(
outlineInsets.bottom, sourceDensity, targetDensity, false);
mOutlineRadius = Drawable.scaleFromDensity(
insets.outlineRadius, sourceDensity, targetDensity);
} else {
mOutlineInsets = null;
}
}
/**
* The one constructor to rule them all. This is called by all public
* constructors to set the state and initialize local properties.
*
* @param state constant state to assign to the new drawable
*/
private NinePatchDrawable(NinePatchState state, Resources res) {
private NinePatchDrawable(@NonNull NinePatchState state, @Nullable Resources res) {
mNinePatchState = state;
updateLocalState(res);
// Push density applied by setNinePatchState into state.
mNinePatchState.mTargetDensity = mTargetDensity;
}
/**
* Initializes local dynamic properties from state.
*/
private void updateLocalState(Resources res) {
private void updateLocalState(@Nullable Resources res) {
final NinePatchState state = mNinePatchState;
if (res != null) {
final int densityDpi = res.getDisplayMetrics().densityDpi;
mTargetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
} else {
mTargetDensity = state.mTargetDensity;
}
// If we can, avoid calling any methods that initialize Paint.
if (state.mDither != DEFAULT_DITHER) {
setDither(state.mDither);
}
// Make a local copy of the padding.
if (state.mPadding != null) {
mPadding = new Rect(state.mPadding);
}
mTargetDensity = Drawable.resolveDensity(res, mTargetDensity);
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
setNinePatch(state.mNinePatch);
computeBitmapSize();
}
}