Merge "Draw AnimatedImageDrawable mirrored if desired" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
e781724b41
@@ -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) {
|
||||
|
||||
@@ -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,10 +390,24 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
|
||||
public void setAutoMirrored(boolean mirrored) {
|
||||
if (mState.mAutoMirrored != mirrored) {
|
||||
mState.mAutoMirrored = mirrored;
|
||||
invalidateSelf();
|
||||
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() {
|
||||
return mState.mAutoMirrored;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
int mAlpha = SK_AlphaOPAQUE;
|
||||
sk_sp<SkColorFilter> mColorFilter;
|
||||
Properties() = default;
|
||||
Properties(Properties&) = default;
|
||||
Properties& operator=(Properties&) = default;
|
||||
};
|
||||
|
||||
Properties mStagingProperties;
|
||||
Properties mProperties;
|
||||
|
||||
std::unique_ptr<OnAnimationEndListener> mEndListener;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user