Loading app/ui/src/main/java/com/fsck/k9/activity/misc/ContactPictureLoader.java +7 −65 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 <a href="http://developer.android.com/design/style/color.html">Color palette used</a> */ 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. Loading @@ -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) { Loading Loading @@ -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<FallbackGlideParams, Bitmap> { private final Context context; Loading @@ -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); } Loading app/ui/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt 0 → 100644 +69 −0 Original line number Diff line number Diff line 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() ) } } app/ui/src/test/java/com/fsck/k9/activity/misc/ContactPictureLoaderTest.javadeleted 100644 → 0 +0 −95 Original line number Diff line number Diff line 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("<c@d.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("C", result); } @Test public void calcUnknownContactLetter_withAsciiName() { Address address = new Address("abcd <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("A", result); } @Test public void calcUnknownContactLetter_withLstroke() { Address address = new Address("Łatynka <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("Ł", result); } @Test public void calcUnknownContactLetter_withChinese() { Address address = new Address("千里之行﹐始于足下 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("千", result); } @Test public void calcUnknownContactLetter_withCombinedGlyphs() { Address address = new Address("\u0061\u0300 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("\u0041\u0300", result); } @Test public void calcUnknownContactLetter_withSurrogatePair() { Address address = new Address("\uD800\uDFB5 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("\uD800\uDFB5", result); } @Test public void calcUnknownContactLetter_ignoresSpace() { Address address = new Address(" abcd <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("A", result); } @Test public void calcUnknownContactLetter_ignoresUsePunctuation() { Address address = new Address("-a <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("A", result); } @Test public void calcUnknownContactLetter_ignoresMatchEmoji() { Address address = new Address("\uD83D\uDE00 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("?", result); } } Loading
app/ui/src/main/java/com/fsck/k9/activity/misc/ContactPictureLoader.java +7 −65 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 <a href="http://developer.android.com/design/style/color.html">Color palette used</a> */ 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. Loading @@ -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) { Loading Loading @@ -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<FallbackGlideParams, Bitmap> { private final Context context; Loading @@ -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); } Loading
app/ui/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt 0 → 100644 +69 −0 Original line number Diff line number Diff line 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() ) } }
app/ui/src/test/java/com/fsck/k9/activity/misc/ContactPictureLoaderTest.javadeleted 100644 → 0 +0 −95 Original line number Diff line number Diff line 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("<c@d.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("C", result); } @Test public void calcUnknownContactLetter_withAsciiName() { Address address = new Address("abcd <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("A", result); } @Test public void calcUnknownContactLetter_withLstroke() { Address address = new Address("Łatynka <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("Ł", result); } @Test public void calcUnknownContactLetter_withChinese() { Address address = new Address("千里之行﹐始于足下 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("千", result); } @Test public void calcUnknownContactLetter_withCombinedGlyphs() { Address address = new Address("\u0061\u0300 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("\u0041\u0300", result); } @Test public void calcUnknownContactLetter_withSurrogatePair() { Address address = new Address("\uD800\uDFB5 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("\uD800\uDFB5", result); } @Test public void calcUnknownContactLetter_ignoresSpace() { Address address = new Address(" abcd <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("A", result); } @Test public void calcUnknownContactLetter_ignoresUsePunctuation() { Address address = new Address("-a <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("A", result); } @Test public void calcUnknownContactLetter_ignoresMatchEmoji() { Address address = new Address("\uD83D\uDE00 <a@b.com>"); String result = ContactPictureLoader.calcUnknownContactLetter(address); assertEquals("?", result); } }