mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2026-03-01 13:46:10 -05:00
136 lines
4.8 KiB
Kotlin
136 lines
4.8 KiB
Kotlin
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 <code>LetterTileProvider</code>
|
|
* @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
|
|
}
|
|
}
|
|
} |