Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7aedf6f0 authored by Stan Iliev's avatar Stan Iliev
Browse files

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
parent 1824f66c
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -385,10 +385,18 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
            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 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,

    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 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
        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);
+11 −6
Original line number Diff line number Diff line
@@ -76,13 +76,18 @@ void NinePatchPeeker::scale(float scaleX, float scaleY, int scaledWidth, int sca
    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.
    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);
    }
}