Merge "Draw AnimatedImageDrawable mirrored if desired" into pi-dev
am: e781724b41
Change-Id: I0ab5753074ec20b7c0600bcdb0d9f0e837951998
This commit is contained in:
@@ -213,6 +213,12 @@ static void AnimatedImageDrawable_nMarkInvisible(JNIEnv* env, jobject /*clazz*/,
|
|||||||
drawable->markInvisible();
|
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[] = {
|
static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
|
||||||
{ "nCreate", "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate },
|
{ "nCreate", "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate },
|
||||||
{ "nGetNativeFinalizer", "()J", (void*) AnimatedImageDrawable_nGetNativeFinalizer },
|
{ "nGetNativeFinalizer", "()J", (void*) AnimatedImageDrawable_nGetNativeFinalizer },
|
||||||
@@ -228,6 +234,7 @@ static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
|
|||||||
{ "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
|
{ "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
|
||||||
{ "nNativeByteSize", "(J)J", (void*) AnimatedImageDrawable_nNativeByteSize },
|
{ "nNativeByteSize", "(J)J", (void*) AnimatedImageDrawable_nNativeByteSize },
|
||||||
{ "nMarkInvisible", "(J)V", (void*) AnimatedImageDrawable_nMarkInvisible },
|
{ "nMarkInvisible", "(J)V", (void*) AnimatedImageDrawable_nMarkInvisible },
|
||||||
|
{ "nSetMirrored", "(JZ)V", (void*) AnimatedImageDrawable_nSetMirrored },
|
||||||
};
|
};
|
||||||
|
|
||||||
int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) {
|
int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import android.os.Looper;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
|
|
||||||
@@ -389,10 +390,24 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
|
|||||||
public void setAutoMirrored(boolean mirrored) {
|
public void setAutoMirrored(boolean mirrored) {
|
||||||
if (mState.mAutoMirrored != mirrored) {
|
if (mState.mAutoMirrored != mirrored) {
|
||||||
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
|
@Override
|
||||||
public final boolean isAutoMirrored() {
|
public final boolean isAutoMirrored() {
|
||||||
return mState.mAutoMirrored;
|
return mState.mAutoMirrored;
|
||||||
@@ -585,4 +600,6 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
|
|||||||
private static native long nNativeByteSize(long nativePtr);
|
private static native long nNativeByteSize(long nativePtr);
|
||||||
@FastNative
|
@FastNative
|
||||||
private static native void nMarkInvisible(long nativePtr);
|
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() {
|
void AnimatedImageDrawable::syncProperties() {
|
||||||
mAlpha = mStagingAlpha;
|
mProperties = mStagingProperties;
|
||||||
mColorFilter = mStagingColorFilter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimatedImageDrawable::start() {
|
bool AnimatedImageDrawable::start() {
|
||||||
@@ -115,12 +114,18 @@ AnimatedImageDrawable::Snapshot AnimatedImageDrawable::reset() {
|
|||||||
// Only called on the RenderThread.
|
// Only called on the RenderThread.
|
||||||
void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
|
void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
|
||||||
SkTLazy<SkPaint> lazyPaint;
|
SkTLazy<SkPaint> lazyPaint;
|
||||||
if (mAlpha != SK_AlphaOPAQUE || mColorFilter.get()) {
|
SkAutoCanvasRestore acr(canvas, false);
|
||||||
|
if (mProperties.mAlpha != SK_AlphaOPAQUE || mProperties.mColorFilter.get()) {
|
||||||
lazyPaint.init();
|
lazyPaint.init();
|
||||||
lazyPaint.get()->setAlpha(mAlpha);
|
lazyPaint.get()->setAlpha(mProperties.mAlpha);
|
||||||
lazyPaint.get()->setColorFilter(mColorFilter);
|
lazyPaint.get()->setColorFilter(mProperties.mColorFilter);
|
||||||
lazyPaint.get()->setFilterQuality(kLow_SkFilterQuality);
|
lazyPaint.get()->setFilterQuality(kLow_SkFilterQuality);
|
||||||
}
|
}
|
||||||
|
if (mProperties.mMirrored) {
|
||||||
|
canvas->save();
|
||||||
|
canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
|
||||||
|
canvas->scale(-1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
mDidDraw = true;
|
mDidDraw = true;
|
||||||
|
|
||||||
@@ -131,7 +136,6 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
|
|||||||
if (drawDirectly) {
|
if (drawDirectly) {
|
||||||
// The image is not animating, and never was. Draw directly from
|
// The image is not animating, and never was. Draw directly from
|
||||||
// mSkAnimatedImage.
|
// mSkAnimatedImage.
|
||||||
SkAutoCanvasRestore acr(canvas, false);
|
|
||||||
if (lazyPaint.isValid()) {
|
if (lazyPaint.isValid()) {
|
||||||
canvas->saveLayer(mSkAnimatedImage->getBounds(), lazyPaint.get());
|
canvas->saveLayer(mSkAnimatedImage->getBounds(), lazyPaint.get());
|
||||||
}
|
}
|
||||||
@@ -190,12 +194,17 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
|
|||||||
|
|
||||||
double AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
|
double AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
|
||||||
SkAutoCanvasRestore acr(canvas, false);
|
SkAutoCanvasRestore acr(canvas, false);
|
||||||
if (mStagingAlpha != SK_AlphaOPAQUE || mStagingColorFilter.get()) {
|
if (mStagingProperties.mAlpha != SK_AlphaOPAQUE || mStagingProperties.mColorFilter.get()) {
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setAlpha(mStagingAlpha);
|
paint.setAlpha(mStagingProperties.mAlpha);
|
||||||
paint.setColorFilter(mStagingColorFilter);
|
paint.setColorFilter(mStagingProperties.mColorFilter);
|
||||||
canvas->saveLayer(mSkAnimatedImage->getBounds(), &paint);
|
canvas->saveLayer(mSkAnimatedImage->getBounds(), &paint);
|
||||||
}
|
}
|
||||||
|
if (mStagingProperties.mMirrored) {
|
||||||
|
canvas->save();
|
||||||
|
canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
|
||||||
|
canvas->scale(-1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (!mRunning) {
|
if (!mRunning) {
|
||||||
// Continue drawing the current frame, and return 0 to indicate no need
|
// Continue drawing the current frame, and return 0 to indicate no need
|
||||||
|
|||||||
@@ -55,9 +55,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isDirty();
|
bool isDirty();
|
||||||
|
|
||||||
int getStagingAlpha() const { return mStagingAlpha; }
|
int getStagingAlpha() const { return mStagingProperties.mAlpha; }
|
||||||
void setStagingAlpha(int alpha) { mStagingAlpha = alpha; }
|
void setStagingAlpha(int alpha) { mStagingProperties.mAlpha = alpha; }
|
||||||
void setStagingColorFilter(sk_sp<SkColorFilter> filter) { mStagingColorFilter = filter; }
|
void setStagingColorFilter(sk_sp<SkColorFilter> filter) {
|
||||||
|
mStagingProperties.mColorFilter = filter;
|
||||||
|
}
|
||||||
|
void setStagingMirrored(bool mirrored) { mStagingProperties.mMirrored = mirrored; }
|
||||||
void syncProperties();
|
void syncProperties();
|
||||||
|
|
||||||
virtual SkRect onGetBounds() override { return mSkAnimatedImage->getBounds(); }
|
virtual SkRect onGetBounds() override { return mSkAnimatedImage->getBounds(); }
|
||||||
@@ -131,11 +134,18 @@ private:
|
|||||||
// Locked when mSkAnimatedImage is being updated or drawn.
|
// Locked when mSkAnimatedImage is being updated or drawn.
|
||||||
std::mutex mImageLock;
|
std::mutex mImageLock;
|
||||||
|
|
||||||
int mStagingAlpha = SK_AlphaOPAQUE;
|
struct Properties {
|
||||||
sk_sp<SkColorFilter> mStagingColorFilter;
|
int mAlpha = SK_AlphaOPAQUE;
|
||||||
|
sk_sp<SkColorFilter> mColorFilter;
|
||||||
|
bool mMirrored = false;
|
||||||
|
|
||||||
int mAlpha = SK_AlphaOPAQUE;
|
Properties() = default;
|
||||||
sk_sp<SkColorFilter> mColorFilter;
|
Properties(Properties&) = default;
|
||||||
|
Properties& operator=(Properties&) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
Properties mStagingProperties;
|
||||||
|
Properties mProperties;
|
||||||
|
|
||||||
std::unique_ptr<OnAnimationEndListener> mEndListener;
|
std::unique_ptr<OnAnimationEndListener> mEndListener;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user