diff --git a/app/src/main/java/protect/card_locker/LetterBitmap.java b/app/src/main/java/protect/card_locker/LetterBitmap.java
deleted file mode 100644
index 73ae8d79e..000000000
--- a/app/src/main/java/protect/card_locker/LetterBitmap.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package protect.card_locker;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.text.TextPaint;
-import android.util.Log;
-
-import androidx.core.graphics.PaintCompat;
-
-/**
- * Original from https://github.com/andOTP/andOTP/blob/master/app/src/main/java/org/shadowice/flocke/andotp/Utilities/LetterBitmap.java
- * which was originally from http://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail
- * Used to create a {@link Bitmap} that contains a letter used in the English
- * alphabet or digit, if there is no letter or digit available, a default image
- * is shown instead.
- */
-class LetterBitmap {
- /**
- * The letter bitmap
- */
- private final Bitmap mBitmap;
- /**
- * The background color of the letter bitmap
- */
- private final Integer mColor;
-
- /**
- * Constructor for LetterTileProvider
- *
- * @param context The {@link Context} to use
- * @param displayName The name used to create the letter for the tile
- * @param key The key used to generate the background color for the tile
- * @param tileLetterFontSize The font size used to display the letter
- * @param width The desired width of the tile
- * @param height The desired height of the tile
- * @param backgroundColor (optional) color to use for background.
- * @param textColor (optional) color to use for text.
- */
- public LetterBitmap(Context context, String displayName, String key, int tileLetterFontSize,
- int width, int height, Integer backgroundColor, Integer textColor) {
- TextPaint paint = new TextPaint();
-
- if (textColor != null) {
- paint.setColor(textColor);
- } else {
- paint.setColor(Color.WHITE);
- }
-
- paint.setTextAlign(Paint.Align.CENTER);
- paint.setAntiAlias(true);
- paint.setTextSize(tileLetterFontSize);
- paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
-
- if (backgroundColor == null) {
- mColor = getDefaultColor(context, key);
- } else {
- mColor = backgroundColor;
- }
-
- mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- String firstChar = displayName.substring(0, 1).toUpperCase();
- int firstCharEnd = 2;
- while (firstCharEnd <= displayName.length()) {
- // Test for the longest render-able string
- // But ignore containing only a-Z0-9 to not render things like ffi as a single character
- String test = displayName.substring(0, firstCharEnd);
- if (!isAlphabetical(test) && PaintCompat.hasGlyph(paint, test)) {
- firstChar = test;
- }
- firstCharEnd++;
- }
-
- Log.d("LetterBitmap", "using sequence " + firstChar + " to render first char which has length " + firstChar.length());
-
- final Canvas c = new Canvas();
- c.setBitmap(mBitmap);
- c.drawColor(mColor);
-
- Rect bounds = new Rect();
- paint.getTextBounds(firstChar, 0, firstChar.length(), bounds);
- c.drawText(firstChar,
- 0, firstChar.length(),
- width / 2.0f, (height - (bounds.bottom + bounds.top)) / 2.0f
- , paint);
-
- }
-
- /**
- * @return A {@link Bitmap} that contains a letter used in the English
- * alphabet or digit, if there is no letter or digit available, a
- * default image is shown instead
- */
- public Bitmap getLetterTile() {
- return mBitmap;
- }
-
- /**
- * @return background color used for letter title.
- */
- public int getBackgroundColor() {
- return mColor;
- }
-
- /**
- * @param key The key used to generate the tile color
- * @return A new or previously chosen color for key used as the
- * tile background color
- */
- private static int pickColor(String key, TypedArray colors) {
- // String.hashCode() is not supposed to change across java versions, so
- // this should guarantee the same key always maps to the same color
- final int color = Math.abs(key.hashCode()) % colors.length();
- return colors.getColor(color, Color.BLACK);
- }
-
- private static boolean isAlphabetical(String string) {
- return string.matches("[a-zA-Z0-9]*");
- }
-
- /**
- * Determine the color which the letter tile will use if no default
- * color is provided.
- */
- public static int getDefaultColor(Context context, String key) {
- final Resources res = context.getResources();
-
- TypedArray colors = res.obtainTypedArray(R.array.letter_tile_colors);
- int color = pickColor(key, colors);
- colors.recycle();
-
- return color;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/protect/card_locker/LetterBitmap.kt b/app/src/main/java/protect/card_locker/LetterBitmap.kt
new file mode 100644
index 000000000..6ac73931c
--- /dev/null
+++ b/app/src/main/java/protect/card_locker/LetterBitmap.kt
@@ -0,0 +1,136 @@
+package protect.card_locker
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Rect
+import android.graphics.Typeface
+import android.text.TextPaint
+import android.util.Log
+import androidx.core.graphics.PaintCompat
+import java.util.Locale
+import kotlin.math.abs
+
+/**
+ * Original from https://github.com/andOTP/andOTP/blob/master/app/src/main/java/org/shadowice/flocke/andotp/Utilities/LetterBitmap.java
+ * which was originally from http://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail
+ * Used to create a {@link Bitmap} that contains a letter used in the English
+ * alphabet or digit, if there is no letter or digit available, a default image
+ * is shown instead.
+ *
+ * @constructor Constructor for LetterTileProvider
+ * @param context The {@link Context} to use
+ * @param displayName The name used to create the letter for the tile
+ * @param key The key used to generate the background color for the tile
+ * @param tileLetterFontSize The font size used to display the letter
+ * @param width The desired width of the tile
+ * @param height The desired height of the tile
+ * @param backgroundColor (optional) color to use for background.
+ * @param textColor (optional) color to use for text.
+ */
+class LetterBitmap(
+ context: Context, displayName: String, key: String, tileLetterFontSize: Int,
+ width: Int, height: Int, backgroundColor: Int?, textColor: Int?
+) {
+ /**
+ * A {@link Bitmap} that contains a letter used in the English
+ * alphabet or digit, if there is no letter or digit available, a
+ * default image is shown instead
+ */
+ private val letterTile: Bitmap
+
+ /**
+ * The background color of the letter bitmap
+ */
+ private val mColor: Int
+
+ init {
+ val paint = TextPaint().apply {
+ color = textColor ?: Color.WHITE
+ textAlign = Paint.Align.CENTER
+ isAntiAlias = true
+ textSize = tileLetterFontSize.toFloat()
+ typeface = Typeface.defaultFromStyle(Typeface.BOLD)
+ }
+
+ mColor = backgroundColor ?: getDefaultColor(context, key)
+
+ this.letterTile = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+
+ var firstChar = displayName.substring(0, 1).uppercase(Locale.getDefault())
+ var firstCharEnd = 2
+ while (firstCharEnd <= displayName.length) {
+ // Test for the longest render-able string
+ // But ignore containing only a-Z0-9 to not render things like ffi as a single character
+ val test = displayName.substring(0, firstCharEnd)
+ if (!isAlphabetical(test) && PaintCompat.hasGlyph(paint, test)) {
+ firstChar = test
+ }
+ firstCharEnd++
+ }
+
+ Log.d(
+ "LetterBitmap",
+ "using sequence $firstChar to render first char which has length ${firstChar.length}"
+ )
+
+ Canvas().apply {
+ setBitmap(this@LetterBitmap.letterTile)
+ drawColor(mColor)
+
+ val bounds = Rect()
+ paint.getTextBounds(firstChar, 0, firstChar.length, bounds)
+ drawText(
+ firstChar,
+ 0, firstChar.length,
+ width / 2.0f, (height - (bounds.bottom + bounds.top)) / 2.0f,
+ paint
+ )
+ }
+ }
+
+ val backgroundColor: Int
+ /**
+ * @return background color used for letter title.
+ */
+ get() = mColor
+
+ fun getLetterTile(): Bitmap {
+ return letterTile
+ }
+
+ companion object {
+ /**
+ * @param key The key used to generate the tile color
+ * @return A new or previously chosen color for `key` used as the
+ * tile background color
+ */
+ private fun pickColor(key: String, colors: TypedArray): Int {
+ // String.hashCode() is not supposed to change across java versions, so
+ // this should guarantee the same key always maps to the same color
+ val color = abs(key.hashCode()) % colors.length()
+ return colors.getColor(color, Color.BLACK)
+ }
+
+ private fun isAlphabetical(string: String): Boolean {
+ return string.matches("[a-zA-Z0-9]*".toRegex())
+ }
+
+ /**
+ * Determine the color which the letter tile will use if no default
+ * color is provided.
+ */
+ fun getDefaultColor(context: Context, key: String): Int {
+ val res = context.resources
+
+ val colors = res.obtainTypedArray(R.array.letter_tile_colors)
+ val color: Int = pickColor(key, colors)
+ colors.recycle()
+
+ return color
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java
index 2703dca10..1d46955f9 100644
--- a/app/src/main/java/protect/card_locker/Utils.java
+++ b/app/src/main/java/protect/card_locker/Utils.java
@@ -143,7 +143,7 @@ public class Utils {
int pixelSize = context.getResources().getDimensionPixelSize(R.dimen.tileLetterImageSize);
if (backgroundColor == null) {
- backgroundColor = LetterBitmap.getDefaultColor(context, store);
+ backgroundColor = LetterBitmap.Companion.getDefaultColor(context, store);
}
return new LetterBitmap(context, store, store,
@@ -1129,7 +1129,7 @@ public class Utils {
}
public static int getHeaderColor(Context context, LoyaltyCard loyaltyCard) {
- return loyaltyCard.headerColor != null ? loyaltyCard.headerColor : LetterBitmap.getDefaultColor(context, loyaltyCard.store);
+ return loyaltyCard.headerColor != null ? loyaltyCard.headerColor : LetterBitmap.Companion.getDefaultColor(context, loyaltyCard.store);
}
public static String checksum(InputStream input) throws IOException {