Improve nine patch scaling

Apply separate coefficient for X and Y, when scaling nine patch
lattice dividers. This is reducing rounding error and fixing
a nine patch issue in Clock app alarm background.
There are other issues in nine patch scaling (see ag/3378768).

Test: Ran clock app
Bug: 70353853
Change-Id: Ibbbfddc47767fb3314cdb88820e520b3f472e727
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 79c5a34..79aa5ac 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -385,10 +385,18 @@
             return nullObjectReturn("codec->getAndroidPixels() failed.");
     }
 
+    // This is weird so let me explain: we could use the scale parameter
+    // directly, but for historical reasons this is how the corresponding
+    // Dalvik code has always behaved. We simply recreate the behavior here.
+    // The result is slightly different from simply using scale because of
+    // the 0.5f rounding bias applied when computing the target image size
+    const float scaleX = scaledWidth / float(decodingBitmap.width());
+    const float scaleY = scaledHeight / float(decodingBitmap.height());
+
     jbyteArray ninePatchChunk = NULL;
     if (peeker.mPatch != NULL) {
         if (willScale) {
-            peeker.scale(scale, scale, scaledWidth, scaledHeight);
+            peeker.scale(scaleX, scaleY, scaledWidth, scaledHeight);
         }
 
         size_t ninePatchArraySize = peeker.mPatch->serializedSize();
@@ -419,14 +427,6 @@
 
     SkBitmap outputBitmap;
     if (willScale) {
-        // This is weird so let me explain: we could use the scale parameter
-        // directly, but for historical reasons this is how the corresponding
-        // Dalvik code has always behaved. We simply recreate the behavior here.
-        // The result is slightly different from simply using scale because of
-        // the 0.5f rounding bias applied when computing the target image size
-        const float sx = scaledWidth / float(decodingBitmap.width());
-        const float sy = scaledHeight / float(decodingBitmap.height());
-
         // Set the allocator for the outputBitmap.
         SkBitmap::Allocator* outputAllocator;
         if (javaBitmap != nullptr) {
@@ -456,7 +456,7 @@
         paint.setFilterQuality(kLow_SkFilterQuality); // bilinear filtering
 
         SkCanvas canvas(outputBitmap, SkCanvas::ColorBehavior::kLegacy);
-        canvas.scale(sx, sy);
+        canvas.scale(scaleX, scaleY);
         canvas.drawBitmap(decodingBitmap, 0.0f, 0.0f, &paint);
     } else {
         outputBitmap.swap(decodingBitmap);
diff --git a/core/jni/android/graphics/NinePatchPeeker.cpp b/core/jni/android/graphics/NinePatchPeeker.cpp
index 066d47b..9171fc6 100644
--- a/core/jni/android/graphics/NinePatchPeeker.cpp
+++ b/core/jni/android/graphics/NinePatchPeeker.cpp
@@ -76,13 +76,18 @@
     if (!mPatch) {
         return;
     }
-    mPatch->paddingLeft   = int(mPatch->paddingLeft   * scaleX + 0.5f);
-    mPatch->paddingTop    = int(mPatch->paddingTop    * scaleY + 0.5f);
-    mPatch->paddingRight  = int(mPatch->paddingRight  * scaleX + 0.5f);
-    mPatch->paddingBottom = int(mPatch->paddingBottom * scaleY + 0.5f);
 
     // The max value for the divRange is one pixel less than the actual max to ensure that the size
     // of the last div is not zero. A div of size 0 is considered invalid input and will not render.
-    scaleDivRange(mPatch->getXDivs(), mPatch->numXDivs, scaleX, scaledWidth - 1);
-    scaleDivRange(mPatch->getYDivs(), mPatch->numYDivs, scaleY, scaledHeight - 1);
+    if (!SkScalarNearlyEqual(scaleX, 1.0f)) {
+        mPatch->paddingLeft   = int(mPatch->paddingLeft   * scaleX + 0.5f);
+        mPatch->paddingRight  = int(mPatch->paddingRight  * scaleX + 0.5f);
+        scaleDivRange(mPatch->getXDivs(), mPatch->numXDivs, scaleX, scaledWidth - 1);
+    }
+
+    if (!SkScalarNearlyEqual(scaleY, 1.0f)) {
+        mPatch->paddingTop    = int(mPatch->paddingTop    * scaleY + 0.5f);
+        mPatch->paddingBottom = int(mPatch->paddingBottom * scaleY + 0.5f);
+        scaleDivRange(mPatch->getYDivs(), mPatch->numYDivs, scaleY, scaledHeight - 1);
+    }
 }