diff --git a/app/ui/src/main/java/com/fsck/k9/activity/misc/ContactPictureLoader.java b/app/ui/src/main/java/com/fsck/k9/activity/misc/ContactPictureLoader.java index 2933468c5..9db6842da 100644 --- a/app/ui/src/main/java/com/fsck/k9/activity/misc/ContactPictureLoader.java +++ b/app/ui/src/main/java/com/fsck/k9/activity/misc/ContactPictureLoader.java @@ -8,13 +8,8 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.Rect; import android.net.Uri; import android.support.annotation.Nullable; -import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import android.widget.ImageView; @@ -35,6 +30,7 @@ import com.bumptech.glide.load.resource.transcode.BitmapToGlideDrawableTranscode import com.bumptech.glide.request.FutureTarget; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.target.Target; +import com.fsck.k9.contacts.ContactLetterBitmapCreator; import com.fsck.k9.contacts.ContactLetterExtractor; import com.fsck.k9.helper.Contacts; import com.fsck.k9.mail.Address; @@ -47,35 +43,12 @@ public class ContactPictureLoader { */ private static final int PICTURE_SIZE = 40; - private static final ContactLetterExtractor CONTACT_LETTER_EXTRACTOR = new ContactLetterExtractor(); - private final Context context; + private final ContactLetterBitmapCreator contactLetterBitmapCreator; private Contacts mContactsHelper; private int mPictureSizeInPx; - private int mDefaultBackgroundColor; - - /** - * @see Color palette used - */ - private final static int CONTACT_DUMMY_COLORS_ARGB[] = { - 0xff33B5E5, - 0xffAA66CC, - 0xff99CC00, - 0xffFFBB33, - 0xffFF4444, - 0xff0099CC, - 0xff9933CC, - 0xff669900, - 0xffFF8800, - 0xffCC0000 - }; - - @VisibleForTesting - protected static String calcUnknownContactLetter(Address address) { - return CONTACT_LETTER_EXTRACTOR.extractContactLetter(address); - } /** * Constructor. @@ -94,8 +67,8 @@ public class ContactPictureLoader { float scale = resources.getDisplayMetrics().density; mPictureSizeInPx = (int) (PICTURE_SIZE * scale); - mDefaultBackgroundColor = defaultBackgroundColor; - + ContactLetterExtractor contactLetterExtractor = new ContactLetterExtractor(); + contactLetterBitmapCreator = new ContactLetterBitmapCreator(contactLetterExtractor, defaultBackgroundColor); } public void loadContactPicture(final Address address, final ImageView imageView) { @@ -188,39 +161,6 @@ public class ContactPictureLoader { return loadIgnoringErors(bitmapTarget); } - private int calcUnknownContactColor(Address address) { - if (mDefaultBackgroundColor != 0) { - return mDefaultBackgroundColor; - } - - int val = address.hashCode(); - int colorIndex = (val & Integer.MAX_VALUE) % CONTACT_DUMMY_COLORS_ARGB.length; - return CONTACT_DUMMY_COLORS_ARGB[colorIndex]; - } - - private Bitmap drawTextAndBgColorOnBitmap(Bitmap bitmap, FallbackGlideParams params) { - Canvas canvas = new Canvas(bitmap); - - int rgb = calcUnknownContactColor(params.address); - bitmap.eraseColor(rgb); - - String letter = calcUnknownContactLetter(params.address); - - Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setStyle(Style.FILL); - paint.setARGB(255, 255, 255, 255); - paint.setTextSize(mPictureSizeInPx * 3 / 4); // just scale this down a bit - Rect rect = new Rect(); - paint.getTextBounds(letter, 0, 1, rect); - float width = paint.measureText(letter); - canvas.drawText(letter, - (mPictureSizeInPx / 2f) - (width / 2f), - (mPictureSizeInPx / 2f) + (rect.height() / 2f), paint); - - return bitmap; - } - private class FallbackGlideBitmapDecoder implements ResourceDecoder { private final Context context; @@ -235,7 +175,9 @@ public class ContactPictureLoader { if (bitmap == null) { bitmap = Bitmap.createBitmap(mPictureSizeInPx, mPictureSizeInPx, Bitmap.Config.ARGB_8888); } - drawTextAndBgColorOnBitmap(bitmap, source); + + Address address = source.address; + contactLetterBitmapCreator.drawBitmap(bitmap, mPictureSizeInPx, address); return BitmapResource.obtain(bitmap, pool); } diff --git a/app/ui/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt b/app/ui/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt new file mode 100644 index 000000000..5e13c011e --- /dev/null +++ b/app/ui/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt @@ -0,0 +1,69 @@ +package com.fsck.k9.contacts + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Rect +import com.fsck.k9.mail.Address + +/** + * Draw a `Bitmap` containing the "contact letter" obtained by [ContactLetterExtractor]. + * + * @param defaultBackgroundColor The ARGB value to be used as background color for the fallback picture. `0` to use a + * dynamically calculated background color. + */ +class ContactLetterBitmapCreator( + private val letterExtractor: ContactLetterExtractor, + private val defaultBackgroundColor: Int +) { + fun drawBitmap(bitmap: Bitmap, pictureSizeInPx: Int, address: Address): Bitmap { + val canvas = Canvas(bitmap) + + val backgroundColor = calcUnknownContactColor(address) + bitmap.eraseColor(backgroundColor) + + val letter = letterExtractor.extractContactLetter(address) + + val paint = Paint().apply { + isAntiAlias = true + style = Paint.Style.FILL + setARGB(255, 255, 255, 255) + textSize = (pictureSizeInPx * 3 / 4).toFloat() // just scale this down a bit + } + + val rect = Rect() + paint.getTextBounds(letter, 0, 1, rect) + + val width = paint.measureText(letter) + canvas.drawText(letter, + pictureSizeInPx / 2f - width / 2f, + pictureSizeInPx / 2f + rect.height() / 2f, paint) + + return bitmap + } + + private fun calcUnknownContactColor(address: Address): Int { + if (defaultBackgroundColor != 0) { + return defaultBackgroundColor + } + + val hash = address.hashCode() + val colorIndex = (hash and Integer.MAX_VALUE) % BACKGROUND_COLORS.size + return BACKGROUND_COLORS[colorIndex] + } + + companion object { + private val BACKGROUND_COLORS = intArrayOf( + 0xff33B5E5L.toInt(), + 0xffAA66CCL.toInt(), + 0xff99CC00L.toInt(), + 0xffFFBB33L.toInt(), + 0xffFF4444L.toInt(), + 0xff0099CCL.toInt(), + 0xff9933CCL.toInt(), + 0xff669900L.toInt(), + 0xffFF8800L.toInt(), + 0xffCC0000L.toInt() + ) + } +} diff --git a/app/ui/src/test/java/com/fsck/k9/activity/misc/ContactPictureLoaderTest.java b/app/ui/src/test/java/com/fsck/k9/activity/misc/ContactPictureLoaderTest.java deleted file mode 100644 index 30a9dddbf..000000000 --- a/app/ui/src/test/java/com/fsck/k9/activity/misc/ContactPictureLoaderTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.fsck.k9.activity.misc; - - -import com.fsck.k9.RobolectricTest; -import com.fsck.k9.mail.Address; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - - -public class ContactPictureLoaderTest extends RobolectricTest { - - @Test - public void calcUnknownContactLetter_withNoNameUsesAddress() { - Address address = new Address(""); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("C", result); - } - - @Test - public void calcUnknownContactLetter_withAsciiName() { - Address address = new Address("abcd "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("A", result); - } - - @Test - public void calcUnknownContactLetter_withLstroke() { - Address address = new Address("Łatynka "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("Ł", result); - } - - - @Test - public void calcUnknownContactLetter_withChinese() { - Address address = new Address("千里之行﹐始于足下 "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("千", result); - } - - @Test - public void calcUnknownContactLetter_withCombinedGlyphs() { - Address address = new Address("\u0061\u0300 "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("\u0041\u0300", result); - } - - @Test - public void calcUnknownContactLetter_withSurrogatePair() { - Address address = new Address("\uD800\uDFB5 "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("\uD800\uDFB5", result); - } - - @Test - public void calcUnknownContactLetter_ignoresSpace() { - Address address = new Address(" abcd "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("A", result); - } - - - @Test - public void calcUnknownContactLetter_ignoresUsePunctuation() { - Address address = new Address("-a "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("A", result); - } - - @Test - public void calcUnknownContactLetter_ignoresMatchEmoji() { - Address address = new Address("\uD83D\uDE00 "); - - String result = ContactPictureLoader.calcUnknownContactLetter(address); - - assertEquals("?", result); - } -}