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

Commit 5e8447f7 authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

Draw AnimatedImageDrawable mirrored if desired

Bug: 73529437
Test: I27af7c3b2e08fa50bc19e08930d970931ce4b5e9

If isAutoMirrored, and the layout direction is RTL, make
AnimatedImageDrawable draw flipped.

Change-Id: I9a3436ef4cb9df2845a67663a2503c2c1a3dba89
parent 999e97f4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -213,6 +213,12 @@ static void AnimatedImageDrawable_nMarkInvisible(JNIEnv* env, jobject /*clazz*/,
    drawable->markInvisible();
}

static void AnimatedImageDrawable_nSetMirrored(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
                                               jboolean mirrored) {
    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
    drawable->setStagingMirrored(mirrored);
}

static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
    { "nCreate",             "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate },
    { "nGetNativeFinalizer", "()J",                                                          (void*) AnimatedImageDrawable_nGetNativeFinalizer },
@@ -228,6 +234,7 @@ static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
    { "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
    { "nNativeByteSize",     "(J)J",                                                         (void*) AnimatedImageDrawable_nNativeByteSize },
    { "nMarkInvisible",      "(J)V",                                                         (void*) AnimatedImageDrawable_nMarkInvisible },
    { "nSetMirrored",        "(JZ)V",                                                        (void*) AnimatedImageDrawable_nSetMirrored },
};

int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) {
+18 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.os.Looper;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;

import com.android.internal.R;

@@ -389,9 +390,23 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
    public void setAutoMirrored(boolean mirrored) {
        if (mState.mAutoMirrored != mirrored) {
            mState.mAutoMirrored = mirrored;
            if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL && mState.mNativePtr != 0) {
                nSetMirrored(mState.mNativePtr, mirrored);
                invalidateSelf();
            }
        }
    }

    @Override
    public boolean onLayoutDirectionChanged(int layoutDirection) {
        if (!mState.mAutoMirrored || mState.mNativePtr == 0) {
            return false;
        }

        final boolean mirror = layoutDirection == View.LAYOUT_DIRECTION_RTL;
        nSetMirrored(mState.mNativePtr, mirror);
        return true;
    }

    @Override
    public final boolean isAutoMirrored() {
@@ -585,4 +600,6 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
    private static native long nNativeByteSize(long nativePtr);
    @FastNative
    private static native void nMarkInvisible(long nativePtr);
    @FastNative
    private static native void nSetMirrored(long nativePtr, boolean mirror);
}
+18 −9
Original line number Diff line number Diff line
@@ -32,8 +32,7 @@ AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImag
}

void AnimatedImageDrawable::syncProperties() {
    mAlpha = mStagingAlpha;
    mColorFilter = mStagingColorFilter;
    mProperties = mStagingProperties;
}

bool AnimatedImageDrawable::start() {
@@ -115,12 +114,18 @@ AnimatedImageDrawable::Snapshot AnimatedImageDrawable::reset() {
// Only called on the RenderThread.
void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
    SkTLazy<SkPaint> lazyPaint;
    if (mAlpha != SK_AlphaOPAQUE || mColorFilter.get()) {
    SkAutoCanvasRestore acr(canvas, false);
    if (mProperties.mAlpha != SK_AlphaOPAQUE || mProperties.mColorFilter.get()) {
        lazyPaint.init();
        lazyPaint.get()->setAlpha(mAlpha);
        lazyPaint.get()->setColorFilter(mColorFilter);
        lazyPaint.get()->setAlpha(mProperties.mAlpha);
        lazyPaint.get()->setColorFilter(mProperties.mColorFilter);
        lazyPaint.get()->setFilterQuality(kLow_SkFilterQuality);
    }
    if (mProperties.mMirrored) {
        canvas->save();
        canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
        canvas->scale(-1, 1);
    }

    mDidDraw = true;

@@ -131,7 +136,6 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
    if (drawDirectly) {
        // The image is not animating, and never was. Draw directly from
        // mSkAnimatedImage.
        SkAutoCanvasRestore acr(canvas, false);
        if (lazyPaint.isValid()) {
            canvas->saveLayer(mSkAnimatedImage->getBounds(), lazyPaint.get());
        }
@@ -190,12 +194,17 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {

double AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
    SkAutoCanvasRestore acr(canvas, false);
    if (mStagingAlpha != SK_AlphaOPAQUE || mStagingColorFilter.get()) {
    if (mStagingProperties.mAlpha != SK_AlphaOPAQUE || mStagingProperties.mColorFilter.get()) {
        SkPaint paint;
        paint.setAlpha(mStagingAlpha);
        paint.setColorFilter(mStagingColorFilter);
        paint.setAlpha(mStagingProperties.mAlpha);
        paint.setColorFilter(mStagingProperties.mColorFilter);
        canvas->saveLayer(mSkAnimatedImage->getBounds(), &paint);
    }
    if (mStagingProperties.mMirrored) {
        canvas->save();
        canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
        canvas->scale(-1, 1);
    }

    if (!mRunning) {
        // Continue drawing the current frame, and return 0 to indicate no need
+17 −7
Original line number Diff line number Diff line
@@ -55,9 +55,12 @@ public:
     */
    bool isDirty();

    int getStagingAlpha() const { return mStagingAlpha; }
    void setStagingAlpha(int alpha) { mStagingAlpha = alpha; }
    void setStagingColorFilter(sk_sp<SkColorFilter> filter) { mStagingColorFilter = filter; }
    int getStagingAlpha() const { return mStagingProperties.mAlpha; }
    void setStagingAlpha(int alpha) { mStagingProperties.mAlpha = alpha; }
    void setStagingColorFilter(sk_sp<SkColorFilter> filter) {
        mStagingProperties.mColorFilter = filter;
    }
    void setStagingMirrored(bool mirrored) { mStagingProperties.mMirrored = mirrored; }
    void syncProperties();

    virtual SkRect onGetBounds() override { return mSkAnimatedImage->getBounds(); }
@@ -131,11 +134,18 @@ private:
    // Locked when mSkAnimatedImage is being updated or drawn.
    std::mutex mImageLock;

    int mStagingAlpha = SK_AlphaOPAQUE;
    sk_sp<SkColorFilter> mStagingColorFilter;

    struct Properties {
        int mAlpha = SK_AlphaOPAQUE;
        sk_sp<SkColorFilter> mColorFilter;
        bool mMirrored = false;

        Properties() = default;
        Properties(Properties&) = default;
        Properties& operator=(Properties&) = default;
    };

    Properties mStagingProperties;
    Properties mProperties;

    std::unique_ptr<OnAnimationEndListener> mEndListener;
};