From 32f25e61f2e3deaf82a09ddb5abc0dcebacf4ff8 Mon Sep 17 00:00:00 2001 From: judds Date: Wed, 25 Nov 2015 16:26:27 -0800 Subject: [PATCH] Automated g4 rollback of changelist 108724201. *** Reason for rollback *** Rollforward with compatibility for apps targeting API 21 *** Original change description *** Automated g4 rollback of changelist 108709885. *** Reason for rollback *** Broke Street View *** Original change description *** MOE automated commit. Merge pull request #762 from vanniktech/master_clean_upload_script Clean upload script up ------------- Merge pull request #727 from josemontiel/master Implemented CENTER_INSIDE support ------------- Update Downsampler names. ------------- Merge pull request #758 from mullender/glide-issue-738 fix for issue #738 Some images simply do no... *** ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=108748541 --- .../com/bumptech/glide/RequestBuilder.java | 3 + .../load/resource/bitmap/CenterInside.java | 52 +++++++ .../resource/bitmap/DownsampleStrategy.java | 36 ++++- .../load/resource/bitmap/Downsampler.java | 4 +- .../resource/bitmap/TransformationUtils.java | 138 +++++++++++++++--- .../glide/request/BaseRequestOptions.java | 33 ++++- .../glide/request/RequestOptions.java | 13 ++ .../resource/bitmap/CenterInsideTest.java | 118 +++++++++++++++ .../bitmap/DownsampleStrategyTest.java | 6 +- .../load/resource/bitmap/DownsamplerTest.java | 2 +- 10 files changed, 373 insertions(+), 32 deletions(-) create mode 100644 library/src/main/java/com/bumptech/glide/load/resource/bitmap/CenterInside.java create mode 100644 library/src/test/java/com/bumptech/glide/load/resource/bitmap/CenterInsideTest.java diff --git a/library/src/main/java/com/bumptech/glide/RequestBuilder.java b/library/src/main/java/com/bumptech/glide/RequestBuilder.java index 2d35556fa5..c8766199c6 100644 --- a/library/src/main/java/com/bumptech/glide/RequestBuilder.java +++ b/library/src/main/java/com/bumptech/glide/RequestBuilder.java @@ -390,6 +390,9 @@ public Target into(ImageView view) { case CENTER_CROP: requestOptions.optionalCenterCrop(context); break; + case CENTER_INSIDE: + requestOptions.optionalCenterInside(context); + break; case FIT_CENTER: case FIT_START: case FIT_END: diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/CenterInside.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/CenterInside.java new file mode 100644 index 0000000000..daeb15fad6 --- /dev/null +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/CenterInside.java @@ -0,0 +1,52 @@ +package com.bumptech.glide.load.resource.bitmap; + +import android.content.Context; +import android.graphics.Bitmap; +import android.support.annotation.NonNull; + +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; + +import java.security.MessageDigest; + +/** + * Returns the image with its original size if its dimensions match or are smaller + * than the target's, couple with {@link android.widget.ImageView.ScaleType#CENTER_INSIDE} + * in order to center it in Target. If not, then it is scaled so that one of the dimensions of + * the image will be equal to the given dimension and the other will be less than the given + * dimension (maintaining the image's aspect ratio). + */ +public class CenterInside extends BitmapTransformation { + private static final String ID = "com.bumptech.glide.load.resource.bitmap.CenterInside"; + private static final byte[] ID_BYTES = ID.getBytes(CHARSET); + + public CenterInside(Context context) { + super(context); + } + + public CenterInside(BitmapPool bitmapPool) { + super(bitmapPool); + } + + @Override + protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, + int outHeight) { + return TransformationUtils.centerInside(pool, toTransform, outWidth, outHeight); + } + + @Override + public boolean equals(Object o) { + return o instanceof CenterInside; + } + + @Override + public int hashCode() { + return ID.hashCode(); + } + + @Override + public void updateDiskCacheKey(MessageDigest messageDigest) { + messageDigest.update(ID_BYTES); + } +} + + diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategy.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategy.java index 0ab010b53a..c5c2934831 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategy.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategy.java @@ -11,12 +11,13 @@ public abstract class DownsampleStrategy { * requested size. * *

This method will upscale if the requested width and height are greater than the source width - * and height. To avoid upscaling, use {@link #AT_LEAST} or {@link #AT_MOST}. + * and height. To avoid upscaling, use {@link #AT_LEAST}, {@link #AT_MOST} or + * {@link #CENTER_INSIDE}. * *

On pre-KitKat devices, this is equivalent to {@link #AT_MOST} because only power of * two downsampling can be used. */ - public static final DownsampleStrategy CENTER_INSIDE = new CenterInside(); + public static final DownsampleStrategy FIT_CENTER = new FitCenter(); /** * Scales, maintaining the original aspect ratio, so that one of the image's dimensions is @@ -24,7 +25,8 @@ public abstract class DownsampleStrategy { * the requested size. * *

This method will upscale if the requested width and height are greater than the source width - * and height. To avoid upscaling, use {@link #AT_LEAST} or {@link #AT_MOST}. + * and height. To avoid upscaling, use {@link #AT_LEAST}, {@link #AT_MOST}, + * or {@link #CENTER_INSIDE}. * *

On pre-KitKat devices, this is equivalent to {@link #AT_LEAST} because only power of * two downsampling can be used. @@ -43,6 +45,15 @@ public abstract class DownsampleStrategy { */ public static final DownsampleStrategy AT_MOST = new AtMost(); + /** + * Returns the original image if it is smaller than the target, otherwise it will be downscaled + * maintaining its original aspect ratio, so that one of the image's dimensions is exactly equal + * to the requested size and the other is less or equal than the requested size. + * + *

This method will not upscale.

+ */ + public static final DownsampleStrategy CENTER_INSIDE = new CenterInside(); + /** * Performs no downsampling or scaling. */ @@ -86,7 +97,7 @@ public abstract float getScaleFactor(int sourceWidth, int sourceHeight, int requ public abstract SampleSizeRounding getSampleSizeRounding(int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight); - private static class CenterInside extends DownsampleStrategy { + private static class FitCenter extends DownsampleStrategy { @Override public float getScaleFactor(int sourceWidth, int sourceHeight, int requestedWidth, @@ -168,6 +179,23 @@ public SampleSizeRounding getSampleSizeRounding(int sourceWidth, int sourceHeigh } } + private static class CenterInside extends DownsampleStrategy { + + @Override + public float getScaleFactor(int sourceWidth, int sourceHeight, int requestedWidth, + int requestedHeight) { + + return Math.min(1.f, + FIT_CENTER.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight)); + } + + @Override + public SampleSizeRounding getSampleSizeRounding(int sourceWidth, int sourceHeight, + int requestedWidth, int requestedHeight) { + return SampleSizeRounding.QUALITY; + } + } + /** * Indicates whether to prefer to prefer downsampling or scaling to prefer lower memory usage * or higher quality. diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java index 065e9796a9..7db211e775 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java @@ -400,17 +400,19 @@ private static Bitmap decodeStream(InputStream is, BitmapFactory.Options options int sourceHeight = options.outHeight; String outMimeType = options.outMimeType; final Bitmap result; + TransformationUtils.getBitmapDrawableLock().lock(); try { result = BitmapFactory.decodeStream(is, null, options); } catch (IllegalArgumentException e) { throw newIoExceptionForInBitmapAssertion(e, sourceWidth, sourceHeight, outMimeType, options); + } finally { + TransformationUtils.getBitmapDrawableLock().unlock(); } if (options.inJustDecodeBounds) { is.reset(); } - return result; } diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java index 8f5b9248bb..1ab96f376c 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java @@ -20,6 +20,11 @@ import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.util.Preconditions; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + /** * A class with methods to efficiently resize Bitmaps. */ @@ -30,6 +35,18 @@ public final class TransformationUtils { private static final int CIRCLE_CROP_PAINT_FLAGS = PAINT_FLAGS | Paint.ANTI_ALIAS_FLAG; private static final Paint CIRCLE_CROP_SHAPE_PAINT = new Paint(CIRCLE_CROP_PAINT_FLAGS); private static final Paint CIRCLE_CROP_BITMAP_PAINT; + /** + * https://github.com/bumptech/glide/issues/738 On some devices (Moto X with android 5.1) bitmap + * drawing is not thread safe. + * This lock only locks for these specific devices. For other types of devices the lock is always + * available and therefore does not impact performance + */ + private static final Lock BITMAP_DRAWABLE_LOCK = "XT1097".equals(Build.MODEL) + // TODO: Switch to Build.VERSION_CODES.LOLLIPOP_MR1 when apps have updated target API levels. + && Build.VERSION.SDK_INT == 22 + ? new ReentrantLock() + : new NoLock(); + static { CIRCLE_CROP_BITMAP_PAINT = new Paint(CIRCLE_CROP_PAINT_FLAGS); CIRCLE_CROP_BITMAP_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); @@ -39,6 +56,11 @@ private TransformationUtils() { // Utility class. } + + public static Lock getBitmapDrawableLock() { + return BITMAP_DRAWABLE_LOCK; + } + /** * A potentially expensive operation to crop the given Bitmap so that it fills the given * dimensions. This operation is significantly less expensive in terms of memory if a mutable @@ -74,9 +96,7 @@ public static Bitmap centerCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm // We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given. TransformationUtils.setAlpha(inBitmap, result); - Canvas canvas = new Canvas(result); - canvas.drawBitmap(inBitmap, m, DEFAULT_PAINT); - clear(canvas); + applyMatrix(inBitmap, result, m); return result; } @@ -129,15 +149,39 @@ public static Bitmap fitCenter(@NonNull BitmapPool pool, @NonNull Bitmap inBitma Log.v(TAG, "minPct: " + minPercentage); } - Canvas canvas = new Canvas(toReuse); Matrix matrix = new Matrix(); matrix.setScale(minPercentage, minPercentage); - canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT); - clear(canvas); + applyMatrix(inBitmap, toReuse, matrix); return toReuse; } + /** + * If the Bitmap is smaller or equal to the Target it returns the original size, if not then + * {@link #fitCenter(BitmapPool, Bitmap, int, int)} is called instead. + * + * @param pool The BitmapPool obtain a bitmap from. + * @param inBitmap The Bitmap to center. + * @param width The width in pixels of the target. + * @param height The height in pixels of the target. + * @return returns input Bitmap if smaller or equal to target, or toFit if the Bitmap's width or + * height is larger than the given dimensions + */ + public static Bitmap centerInside(@NonNull BitmapPool pool, @NonNull Bitmap inBitmap, int width, + int height) { + if (inBitmap.getWidth() <= width && inBitmap.getHeight() <= height) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "requested target size larger or equal to input, returning input"); + } + return inBitmap; + } else { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "requested target size too big for input, fit centering instead"); + } + return fitCenter(pool, inBitmap, width, height); + } + } + /** * Sets the alpha of the Bitmap we're going to re-use to the alpha of the Bitmap we're going to * transform. This keeps {@link android.graphics.Bitmap#hasAlpha()}} consistent before and after @@ -240,10 +284,7 @@ public static Bitmap rotateImageExif(@NonNull BitmapPool pool, @NonNull Bitmap i matrix.postTranslate(-newRect.left, -newRect.top); - final Canvas canvas = new Canvas(result); - canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT); - clear(canvas); - + applyMatrix(inBitmap, result, matrix); return result; } @@ -275,15 +316,20 @@ public static Bitmap circleCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm Bitmap result = pool.get(destWidth, destHeight, getSafeConfig(toTransform)); setAlphaIfAvailable(result, true /*hasAlpha*/); - Canvas canvas = new Canvas(result); - // Draw a circle - canvas.drawCircle(destRect.left + radius, destRect.top + radius, radius, - CIRCLE_CROP_SHAPE_PAINT); - // Draw the bitmap in the circle - canvas.drawBitmap(toTransform, srcRect, destRect, CIRCLE_CROP_BITMAP_PAINT); - clear(canvas); + BITMAP_DRAWABLE_LOCK.lock(); + try { + Canvas canvas = new Canvas(result); + // Draw a circle + canvas.drawCircle(destRect.left + radius, destRect.top + radius, radius, + CIRCLE_CROP_SHAPE_PAINT); + // Draw the bitmap in the circle + canvas.drawBitmap(toTransform, srcRect, destRect, CIRCLE_CROP_BITMAP_PAINT); + clear(canvas); + } finally { + BITMAP_DRAWABLE_LOCK.unlock(); + } if (!toTransform.equals(inBitmap)) { pool.put(toTransform); @@ -335,10 +381,15 @@ public static Bitmap roundedCorners(@NonNull BitmapPool pool, @NonNull Bitmap in paint.setAntiAlias(true); paint.setShader(shader); RectF rect = new RectF(0, 0, result.getWidth(), result.getHeight()); - Canvas canvas = new Canvas(result); - canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); - canvas.drawRoundRect(rect, roundingRadius, roundingRadius, paint); - clear(canvas); + BITMAP_DRAWABLE_LOCK.lock(); + try { + Canvas canvas = new Canvas(result); + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + canvas.drawRoundRect(rect, roundingRadius, roundingRadius, paint); + clear(canvas); + } finally { + BITMAP_DRAWABLE_LOCK.unlock(); + } if (!toTransform.equals(inBitmap)) { pool.put(toTransform); @@ -356,6 +407,18 @@ private static Bitmap.Config getSafeConfig(Bitmap bitmap) { return bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888; } + private static void applyMatrix(@NonNull Bitmap inBitmap, @NonNull Bitmap targetBitmap, + Matrix matrix) { + BITMAP_DRAWABLE_LOCK.lock(); + try { + Canvas canvas = new Canvas(targetBitmap); + canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT); + clear(canvas); + } finally { + BITMAP_DRAWABLE_LOCK.unlock(); + } + } + // Visible for testing. static void initializeMatrixForRotation(int exifOrientation, Matrix matrix) { switch (exifOrientation) { @@ -387,4 +450,37 @@ static void initializeMatrixForRotation(int exifOrientation, Matrix matrix) { // Do nothing. } } + + private static final class NoLock implements Lock { + @Override + public void lock() { + // do nothing + } + + @Override + public void lockInterruptibly() throws InterruptedException { + // do nothing + } + + @Override + public boolean tryLock() { + return true; + } + + @Override + public boolean tryLock(long time, @NonNull TimeUnit unit) throws InterruptedException { + return true; + } + + @Override + public void unlock() { + // do nothing + } + + @NonNull + @Override + public Condition newCondition() { + throw new UnsupportedOperationException("Should not be called"); + } + } } diff --git a/library/src/main/java/com/bumptech/glide/request/BaseRequestOptions.java b/library/src/main/java/com/bumptech/glide/request/BaseRequestOptions.java index c23a569237..f9df455c9b 100644 --- a/library/src/main/java/com/bumptech/glide/request/BaseRequestOptions.java +++ b/library/src/main/java/com/bumptech/glide/request/BaseRequestOptions.java @@ -18,6 +18,7 @@ import com.bumptech.glide.load.resource.bitmap.BitmapDrawableTransformation; import com.bumptech.glide.load.resource.bitmap.BitmapEncoder; import com.bumptech.glide.load.resource.bitmap.CenterCrop; +import com.bumptech.glide.load.resource.bitmap.CenterInside; import com.bumptech.glide.load.resource.bitmap.CircleCrop; import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy; import com.bumptech.glide.load.resource.bitmap.Downsampler; @@ -511,7 +512,7 @@ public CHILD centerCrop(Context context) { * @see #fitCenter(android.content.Context) */ public CHILD optionalFitCenter(Context context) { - return optionalTransform(context, DownsampleStrategy.CENTER_INSIDE, new FitCenter(context)); + return optionalTransform(context, DownsampleStrategy.FIT_CENTER, new FitCenter(context)); } /** @@ -525,7 +526,35 @@ public CHILD optionalFitCenter(Context context) { * @see #optionalFitCenter(android.content.Context) */ public CHILD fitCenter(Context context) { - return transform(context, DownsampleStrategy.CENTER_INSIDE, new FitCenter(context)); + return transform(context, DownsampleStrategy.FIT_CENTER, new FitCenter(context)); + } + + /** + * Applies {@link com.bumptech.glide.load.resource.bitmap.CenterInside} to all default types, and + * ignores unknown types. + * + *

This will override previous calls to {@link #dontTransform()}. + * + * @param context Any {@link android.content.Context}. + * @see #optionalTransform(Class, com.bumptech.glide.load.Transformation) + * @see #centerInside(Context) (android.content.Context) + */ + public CHILD optionalCenterInside(Context context) { + return optionalTransform(context, DownsampleStrategy.CENTER_INSIDE, new CenterInside(context)); + } + + /** + * Applies {@link com.bumptech.glide.load.resource.bitmap.CenterInside} to all default types and + * throws an exception if asked to transform an unknown type. + * + *

This will override previous calls to {@link #dontTransform()}. + * + * @param context Any {@link android.content.Context}. + * @see #transform(Class, com.bumptech.glide.load.Transformation) + * @see #optionalCenterInside(Context) (android.content.Context) + */ + public CHILD centerInside(Context context) { + return transform(context, DownsampleStrategy.CENTER_INSIDE, new CenterInside(context)); } /** diff --git a/library/src/main/java/com/bumptech/glide/request/RequestOptions.java b/library/src/main/java/com/bumptech/glide/request/RequestOptions.java index 6e8aa1e650..3bf554ecda 100644 --- a/library/src/main/java/com/bumptech/glide/request/RequestOptions.java +++ b/library/src/main/java/com/bumptech/glide/request/RequestOptions.java @@ -26,6 +26,7 @@ public final class RequestOptions extends BaseRequestOptions { private static RequestOptions skipMemoryCacheTrueOptions; private static RequestOptions skipMemoryCacheFalseOptions; private static RequestOptions fitCenterOptions; + private static RequestOptions centerInsideOptions; private static RequestOptions centerCropOptions; private static RequestOptions circleCropOptions; private static RequestOptions noTransformOptions; @@ -131,6 +132,18 @@ public static RequestOptions fitCenterTransform(Context context) { return fitCenterOptions; } + /** + * Returns a {@link RequestOptions} object with {@link #centerInside(Context)} set. + */ + public static RequestOptions centerInsideTransform(Context context) { + if (centerInsideOptions == null) { + centerInsideOptions = new RequestOptions() + .centerInside(context.getApplicationContext()) + .autoLock(); + } + return centerInsideOptions; + } + /** * Returns a {@link RequestOptions} object with {@link #circleCrop(Context)} set. */ diff --git a/library/src/test/java/com/bumptech/glide/load/resource/bitmap/CenterInsideTest.java b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/CenterInsideTest.java new file mode 100644 index 0000000000..3121e7701d --- /dev/null +++ b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/CenterInsideTest.java @@ -0,0 +1,118 @@ +package com.bumptech.glide.load.resource.bitmap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; + +import com.bumptech.glide.load.Transformation; +import com.bumptech.glide.load.engine.Resource; +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPoolAdapter; +import com.bumptech.glide.tests.KeyAssertions; +import com.bumptech.glide.tests.Util; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.shadows.ShadowCanvas; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE, sdk = 18, shadows = { CenterInsideTest.DrawNothingCanvas.class }) +public class CenterInsideTest { + + @Mock Resource resource; + @Mock Transformation transformation; + private BitmapPool pool; + private CenterInside centerInside; + private int bitmapWidth; + private int bitmapHeight; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + bitmapWidth = 100; + bitmapHeight = 100; + Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); + when(resource.get()).thenReturn(bitmap); + + pool = new BitmapPoolAdapter(); + + centerInside = new CenterInside(pool); + } + + @Test + public void testReturnsGivenResourceIfMatchesSizeExactly() { + Resource result = + centerInside.transform(resource, bitmapWidth, bitmapHeight); + + assertEquals(resource, result); + } + + @Test + public void testReturnsGivenResourceIfSmallerThanTarget() { + Resource result = + centerInside.transform(resource, 150, 150); + + assertEquals(resource, result); + } + + @Test + public void testReturnsNewResourceIfLargerThanTarget() { + Resource result = + centerInside.transform(resource, 50, 50); + + assertNotEquals(resource, result); + } + + + @Test + public void testDoesNotRecycleGivenResourceIfMatchesSizeExactly() { + centerInside.transform(resource, bitmapWidth, bitmapHeight); + + verify(resource, never()).recycle(); + } + + @Test + public void testDoesNotRecycleGivenResource() { + centerInside.transform(resource, 50, 50); + + verify(resource, never()).recycle(); + } + + @Test + public void testEquals() throws NoSuchAlgorithmException { + KeyAssertions.assertSame(centerInside, new CenterInside(pool)); + + doAnswer(new Util.WriteDigest("other")).when(transformation) + .updateDiskCacheKey(any(MessageDigest.class)); + KeyAssertions.assertDifferent(centerInside, transformation); + } + + @Implements(Canvas.class) + public static final class DrawNothingCanvas extends ShadowCanvas { + + @Implementation + @Override + public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { + // Do nothing. + } + } +} diff --git a/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategyTest.java b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategyTest.java index f68d1e556b..c6a6240251 100644 --- a/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategyTest.java +++ b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsampleStrategyTest.java @@ -91,11 +91,11 @@ public void testAtLeast_withSourceGreaterInOneDimension_returnsScaleFactorOfSmal @Test public void testCenterInside_scalesImageToFitWithinRequestedBounds() { - assertThat(DownsampleStrategy.CENTER_INSIDE.getScaleFactor(100, 200, 300, 300)) + assertThat(DownsampleStrategy.FIT_CENTER.getScaleFactor(100, 200, 300, 300)) .isEqualTo(300 / 200f); - assertThat(DownsampleStrategy.CENTER_INSIDE.getScaleFactor(270, 480, 724, 440)) + assertThat(DownsampleStrategy.FIT_CENTER.getScaleFactor(270, 480, 724, 440)) .isEqualTo(440 / 480f); - assertThat(DownsampleStrategy.CENTER_INSIDE.getScaleFactor(100, 100, 100, 100)).isEqualTo(1f); + assertThat(DownsampleStrategy.FIT_CENTER.getScaleFactor(100, 100, 100, 100)).isEqualTo(1f); } @Test diff --git a/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsamplerTest.java b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsamplerTest.java index c88e3081a9..7ce96f19c8 100644 --- a/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsamplerTest.java +++ b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/DownsamplerTest.java @@ -112,7 +112,7 @@ public void testCalculateScaling_withAtLeast() { @Test public void testCalculateScaling_withCenterInside() { - DownsampleStrategy strategy = DownsampleStrategy.CENTER_INSIDE; + DownsampleStrategy strategy = DownsampleStrategy.FIT_CENTER; runScaleTest(100, 100, 100, 100, strategy, 100, 100); runScaleTest(200, 200, 100, 100, strategy, 100, 100); runScaleTest(400, 400, 100, 100, strategy, 100, 100);