From 8e13d964cffe40629deb77a17010f3a60c015765 Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Sat, 8 Jan 2022 17:31:13 -0800 Subject: [PATCH] Add an API to determine whether or not bitmaps should be rescaled --- .../lottie/compose/LottieDynamicProperties.kt | 11 +++++++--- .../airbnb/lottie/LottieAnimationView.java | 20 ++++++++++++++++++ .../com/airbnb/lottie/LottieDrawable.java | 21 +++++++++++++++++++ .../airbnb/lottie/model/layer/ImageLayer.java | 10 +++++++-- .../airbnb/lottie/snapshots/FilmStripView.kt | 2 ++ 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieDynamicProperties.kt b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieDynamicProperties.kt index 3bec2455d..e050a5a68 100644 --- a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieDynamicProperties.kt +++ b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieDynamicProperties.kt @@ -19,13 +19,15 @@ import com.airbnb.lottie.value.ScaleXY * This takes a vararg of individual dynamic properties which should be created with [rememberLottieDynamicProperty]. * * @see rememberLottieDynamicProperty + * @see LottieDrawable.setRescaleBitmaps */ @Composable fun rememberLottieDynamicProperties( + rescaleBitmaps: Boolean = false, vararg properties: LottieDynamicProperty<*>, ): LottieDynamicProperties { - return remember(properties) { - LottieDynamicProperties(properties.toList()) + return remember(rescaleBitmaps, properties) { + LottieDynamicProperties(rescaleBitmaps, properties.toList()) } } @@ -91,6 +93,7 @@ class LottieDynamicProperty internal constructor( * @see rememberLottieDynamicProperties */ class LottieDynamicProperties internal constructor( + private val rescaleBitmaps: Boolean, private val intProperties: List>, private val pointFProperties: List>, private val floatProperties: List>, @@ -102,7 +105,8 @@ class LottieDynamicProperties internal constructor( private val bitmapProperties: List>, ) { @Suppress("UNCHECKED_CAST") - constructor(properties: List>) : this( + constructor(rescaleBitmaps: Boolean, properties: List>) : this( + rescaleBitmaps, properties.filter { it.property is Int } as List>, properties.filter { it.property is PointF } as List>, properties.filter { it.property is Float } as List>, @@ -114,6 +118,7 @@ class LottieDynamicProperties internal constructor( ) internal fun addTo(drawable: LottieDrawable) { + drawable.rescaleBitmaps = rescaleBitmaps intProperties.forEach { p -> drawable.addValueCallback(p.keyPath, p.property, p.callback.toValueCallback()) } diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java index 30c02c3c9..538ac06a2 100644 --- a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java +++ b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java @@ -893,6 +893,26 @@ public String getImageAssetsFolder() { return lottieDrawable.getImageAssetsFolder(); } + /** + * When true, dynamically set bitmaps will be drawn at the size of the original bitmap. + * When false, dynamically set bitmaps will be drawn at 0,0 at the original bitmap but at whatever size the dynamic bitmap is. + * + * Defaults to false. + */ + public void setRescaleBitmaps(boolean rescaleBitmaps) { + lottieDrawable.setRescaleBitmaps(rescaleBitmaps); + } + + /** + * When true, dynamically set bitmaps will be drawn at the size of the original bitmap. + * When false, dynamically set bitmaps will be drawn at 0,0 at the original bitmap but at whatever size the dynamic bitmap is. + * + * Defaults to false. + */ + public boolean getRescaleBitmaps() { + return lottieDrawable.getRescaleBitmaps(); + } + /** * Allows you to modify or clear a bitmap that was loaded for an image either automatically * through {@link #setImageAssetsFolder(String)} or with an {@link ImageAssetDelegate}. diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java index 4dfa3149f..e5fb793cc 100644 --- a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java +++ b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java @@ -99,6 +99,7 @@ public void onAnimationUpdate(ValueAnimator animation) { @Nullable TextDelegate textDelegate; private boolean enableMergePaths; + private boolean rescaleBitmaps; @Nullable private CompositionLayer compositionLayer; private int alpha = 255; @@ -219,6 +220,26 @@ public String getImageAssetsFolder() { return imageAssetsFolder; } + /** + * When true, dynamically set bitmaps will be drawn at the size of the original bitmap. + * When false, dynamically set bitmaps will be drawn at 0,0 at the original bitmap but at whatever size the dynamic bitmap is. + * + * Defaults to false. + */ + public void setRescaleBitmaps(boolean rescaleBitmaps) { + this.rescaleBitmaps = rescaleBitmaps; + } + + /** + * When true, dynamically set bitmaps will be drawn at the size of the original bitmap. + * When false, dynamically set bitmaps will be drawn at 0,0 at the original bitmap but at whatever size the dynamic bitmap is. + * + * Defaults to false. + */ + public boolean getRescaleBitmaps() { + return rescaleBitmaps; + } + /** * Create a composition with {@link LottieCompositionFactory} * diff --git a/lottie/src/main/java/com/airbnb/lottie/model/layer/ImageLayer.java b/lottie/src/main/java/com/airbnb/lottie/model/layer/ImageLayer.java index 068b10939..a4017cedf 100644 --- a/lottie/src/main/java/com/airbnb/lottie/model/layer/ImageLayer.java +++ b/lottie/src/main/java/com/airbnb/lottie/model/layer/ImageLayer.java @@ -48,7 +48,12 @@ public class ImageLayer extends BaseLayer { canvas.save(); canvas.concat(parentMatrix); src.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); - dst.set(0, 0, (int) (lottieImageAsset.getWidth() * density), (int) (lottieImageAsset.getHeight() * density)); + if (lottieDrawable.getRescaleBitmaps()) { + dst.set(0, 0, (int) (lottieImageAsset.getWidth() * density), (int) (lottieImageAsset.getHeight() * density)); + } else { + dst.set(0, 0, (int) (bitmap.getWidth() * density), (int) (bitmap.getHeight() * density)); + } + canvas.drawBitmap(bitmap, src, dst, paint); canvas.restore(); } @@ -65,8 +70,9 @@ public class ImageLayer extends BaseLayer { private Bitmap getBitmap() { if (imageAnimation != null) { Bitmap callbackBitmap = imageAnimation.getValue(); - if (callbackBitmap != null) + if (callbackBitmap != null) { return callbackBitmap; + } } String refId = layerModel.getRefId(); return lottieDrawable.getBitmapForId(refId); diff --git a/snapshot-tests/src/main/java/com/airbnb/lottie/snapshots/FilmStripView.kt b/snapshot-tests/src/main/java/com/airbnb/lottie/snapshots/FilmStripView.kt index 310a43c60..2a9341aee 100644 --- a/snapshot-tests/src/main/java/com/airbnb/lottie/snapshots/FilmStripView.kt +++ b/snapshot-tests/src/main/java/com/airbnb/lottie/snapshots/FilmStripView.kt @@ -33,6 +33,8 @@ class FilmStripView @JvmOverloads constructor( fun setImageAssetDelegate(delegate: ImageAssetDelegate?) { animationViews.forEach { it.setImageAssetDelegate(delegate) } + // Enable bitmap rescaling for the first 4 views so both APIs get test coverage. + animationViews.forEachIndexed { i, av -> av.rescaleBitmaps = i <= 4 } } fun setFontAssetDelegate(delegate: FontAssetDelegate?) {