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

Commit 056b84b5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Improve nine patch scaling"

parents 5d50100e 7aedf6f0
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);
    }
}