Fix NinePatch insets scaling
bug:27323867
Change-Id: I33c0007eb9259703c73d2e3672ae1427a2155037
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 5efc00c..b6a209f 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -45,15 +45,11 @@
int outlineLeft, int outlineTop, int outlineRight, int outlineBottom,
float outlineRadius, int outlineAlpha, float decodeScale) {
opticalRect = new Rect(opticalLeft, opticalTop, opticalRight, opticalBottom);
- outlineRect = new Rect(outlineLeft, outlineTop, outlineRight, outlineBottom);
+ opticalRect.scale(decodeScale);
- if (decodeScale != 1.0f) {
- // if bitmap was scaled when decoded, scale the insets from the metadata values
- opticalRect.scale(decodeScale);
+ outlineRect = scaleInsets(outlineLeft, outlineTop,
+ outlineRight, outlineBottom, decodeScale);
- // round inward while scaling outline, as the outline should always be conservative
- outlineRect.scaleRoundIn(decodeScale);
- }
this.outlineRadius = outlineRadius * decodeScale;
this.outlineAlpha = outlineAlpha / 255.0f;
}
@@ -62,6 +58,23 @@
public final Rect outlineRect;
public final float outlineRadius;
public final float outlineAlpha;
+
+ /**
+ * Scales up the rect by the given scale, ceiling values, so actual outline Rect
+ * grows toward the inside.
+ */
+ public static Rect scaleInsets(int left, int top, int right, int bottom, float scale) {
+ if (scale == 1.0f) {
+ return new Rect(left, top, right, bottom);
+ }
+
+ Rect result = new Rect();
+ result.left = (int) Math.ceil(left * scale);
+ result.top = (int) Math.ceil(top * scale);
+ result.right = (int) Math.ceil(right * scale);
+ result.bottom = (int) Math.ceil(bottom * scale);
+ return result;
+ }
}
private final Bitmap mBitmap;
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 93ef3f0..7f579a2 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -647,16 +647,4 @@
}
}
- /**
- * Scales up the rect by the given scale, rounding values toward the inside.
- * @hide
- */
- public void scaleRoundIn(float scale) {
- if (scale != 1.0f) {
- left = (int) Math.ceil(left * scale);
- top = (int) Math.ceil(top * scale);
- right = (int) Math.floor(right * scale);
- bottom = (int) Math.floor(bottom * scale);
- }
- }
}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 5b1cc80..d962385 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -706,18 +706,9 @@
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);
+ Rect outlineRect = insets.outlineRect;
+ mOutlineInsets = NinePatch.InsetStruct.scaleInsets(outlineRect.left, outlineRect.top,
+ outlineRect.right, outlineRect.bottom, targetDensity / (float) sourceDensity);
mOutlineRadius = Drawable.scaleFromDensity(
insets.outlineRadius, sourceDensity, targetDensity);
} else {