Automatically scale compositions to the size of the canvas (#178)
diff --git a/LottieSample/screenshots/LottieLogo1.png b/LottieSample/screenshots/LottieLogo1.png index 54744cb..a402f3b 100644 --- a/LottieSample/screenshots/LottieLogo1.png +++ b/LottieSample/screenshots/LottieLogo1.png Binary files differ
diff --git a/LottieSample/screenshots/LottieLogo2.png b/LottieSample/screenshots/LottieLogo2.png index 3871e29..f9355c8 100644 --- a/LottieSample/screenshots/LottieLogo2.png +++ b/LottieSample/screenshots/LottieLogo2.png Binary files differ
diff --git a/LottieSample/screenshots/MotionCorpse-Jrcanest.png b/LottieSample/screenshots/MotionCorpse-Jrcanest.png index 713a34a..c7eea27 100644 --- a/LottieSample/screenshots/MotionCorpse-Jrcanest.png +++ b/LottieSample/screenshots/MotionCorpse-Jrcanest.png Binary files differ
diff --git a/LottieSample/screenshots/Tests_Laugh4.png b/LottieSample/screenshots/Tests_Laugh4.png index 494b478..ed208a6 100644 --- a/LottieSample/screenshots/Tests_Laugh4.png +++ b/LottieSample/screenshots/Tests_Laugh4.png Binary files differ
diff --git a/lottie/src/main/java/com/airbnb/lottie/BitmapCanvas.java b/lottie/src/main/java/com/airbnb/lottie/BitmapCanvas.java new file mode 100644 index 0000000..1a2e9b1 --- /dev/null +++ b/lottie/src/main/java/com/airbnb/lottie/BitmapCanvas.java
@@ -0,0 +1,18 @@ +package com.airbnb.lottie; + +import android.graphics.Bitmap; +import android.graphics.Canvas; + +class BitmapCanvas extends Canvas { + + private final Bitmap bitmap; + + BitmapCanvas(Bitmap bitmap) { + super(bitmap); + this.bitmap = bitmap; + } + + Bitmap getBitmap() { + return bitmap; + } +}
diff --git a/lottie/src/main/java/com/airbnb/lottie/CanvasPool.java b/lottie/src/main/java/com/airbnb/lottie/CanvasPool.java new file mode 100644 index 0000000..072ab26 --- /dev/null +++ b/lottie/src/main/java/com/airbnb/lottie/CanvasPool.java
@@ -0,0 +1,81 @@ +package com.airbnb.lottie; + +import android.graphics.Bitmap; +import android.graphics.Color; +import android.support.v4.util.LongSparseArray; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static junit.framework.Assert.assertNotNull; + +class CanvasPool { + private final LongSparseArray<List<Bitmap>> availableBitmaps = new LongSparseArray<>(); + private final Map<BitmapCanvas, Bitmap> canvasBitmapMap = new HashMap<>(); + private final Map<Bitmap, BitmapCanvas> bitmapCanvasMap = new HashMap<>(); + + BitmapCanvas acquire(int width, int height, Bitmap.Config config) { + int key = getKey(width, height, config); + List<Bitmap> bitmaps = availableBitmaps.get(key); + if (bitmaps == null) { + bitmaps = new ArrayList<>(); + availableBitmaps.put(key, bitmaps); + } + + BitmapCanvas canvas; + if (bitmaps.isEmpty()) { + Bitmap bitmap = Bitmap.createBitmap(width, height, config); + canvas = new BitmapCanvas(bitmap); + canvasBitmapMap.put(canvas, bitmap); + bitmapCanvasMap.put(bitmap, canvas); + } else { + Bitmap bitmap = bitmaps.remove(0); + canvas = bitmapCanvasMap.get(bitmap); + assertNotNull(canvas); + } + canvas.getBitmap().eraseColor(Color.TRANSPARENT); + return canvas; + } + + void release(BitmapCanvas canvas) { + assertNotNull(canvas); + Bitmap bitmap = canvasBitmapMap.get(canvas); + assertNotNull(bitmap); + int key = getKey(bitmap); + List<Bitmap> bitmaps = availableBitmaps.get(key); + assertNotNull(bitmaps); + if (bitmaps.contains(bitmap)) { + throw new IllegalStateException("Canvas already released."); + } + bitmaps.add(bitmap); + } + + void recycleBitmaps() { + for (int i = 0; i < availableBitmaps.size(); i++) { + List<Bitmap> bitmaps = availableBitmaps.valueAt(i); + Iterator<Bitmap> it = bitmaps.iterator(); + while (it.hasNext()) { + Bitmap bitmap = it.next(); + BitmapCanvas canvas = bitmapCanvasMap.get(bitmap); + bitmapCanvasMap.remove(bitmap); + canvasBitmapMap.remove(canvas); + bitmap.recycle(); + it.remove(); + } + } + if (!bitmapCanvasMap.isEmpty()) { + throw new IllegalStateException("Not all canvases have been released!"); + } + } + + private int getKey(Bitmap bitmap) { + return getKey(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig()); + } + + private int getKey(int width, int height, Bitmap.Config config) { + return (width & 0xffff) << 17 | (height & 0xffff) << 1 | (config.ordinal() & 0x1); + } +}
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java index dffc010..b6b7132 100644 --- a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java +++ b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
@@ -196,6 +196,10 @@ if (composition == null) { return; } + float xScale = canvas.getWidth() / (float) composition.getBounds().width(); + float yScale = canvas.getHeight() / (float) composition.getBounds().height(); + setScale(Math.min(xScale, yScale)); + int saveCount = canvas.save(); canvas.clipRect(0, 0, getIntrinsicWidth(), getIntrinsicHeight()); super.draw(canvas); @@ -274,7 +278,6 @@ @SuppressWarnings("WeakerAccess") public void setScale(float scale) { this.scale = scale; updateBounds(); - invalidateSelf(); } @SuppressWarnings("WeakerAccess") public float getScale() {