ref: fruchtfleisch
app/src/main/java/xyz/apiote/bimba/czwek/repo/LineAbstract.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
package xyz.apiote.bimba.czwek.repo import android.content.Context import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color import android.graphics.Matrix import android.graphics.Paint import android.graphics.Path import androidx.appcompat.content.res.AppCompatResources import androidx.core.graphics.drawable.toBitmap import xyz.apiote.bimba.czwek.R import xyz.apiote.bimba.czwek.dpToPixel import xyz.apiote.bimba.czwek.dpToPixelI import kotlin.math.abs import kotlin.math.pow interface LineAbstract { fun textColour(c: Colour): Int { val black = relativeLuminance(Colour(0u, 0u, 0u)) + .05 val white = relativeLuminance(Colour(255u, 255u, 255u)) + .05 val colour = relativeLuminance(c) + .05 return if ((white / colour) > (colour / black)) { Color.WHITE } else { Color.BLACK } } private fun relativeLuminance(colour: Colour): Double { val r = fromSRGB(colour.R.toDouble() / 0xff) val g = fromSRGB(colour.G.toDouble() / 0xff) val b = fromSRGB(colour.B.toDouble() / 0xff) return 0.2126 * r + 0.7152 * g + 0.0722 * b } private fun fromSRGB(part: Double): Double { return if (part <= 0.03928) { part / 12.92 } else { ((part + 0.055) / 1.055).pow(2.4) } } fun icon(context: Context, type: LineType, colour: Colour, scale: Float): Bitmap { val drawingBitmap = Bitmap.createBitmap( dpToPixelI(24f / scale), dpToPixelI(24f / scale), Bitmap.Config.ARGB_8888 ) val canvas = Canvas(drawingBitmap) canvas.drawPath(getSquirclePath( dpToPixel(.8f / scale), dpToPixel(.8f / scale), dpToPixelI(11.2f / scale) ), Paint().apply { color = textColour(colour) }) canvas.drawPath(getSquirclePath( dpToPixel(1.6f / scale), dpToPixel(1.6f / scale), dpToPixelI(10.4f / scale) ), Paint().apply { color = colour.toInt() }) val iconID = when (type) { LineType.BUS -> R.drawable.bus_black LineType.TRAM -> R.drawable.tram_black LineType.TROLLEYBUS -> R.drawable.trolleybus_black LineType.UNKNOWN -> R.drawable.vehicle_black } val icon = AppCompatResources.getDrawable(context, iconID)?.mutate()?.apply { setTint(textColour(colour)) }?.toBitmap(dpToPixelI(19.2f / scale), dpToPixelI(19.2f / scale), Bitmap.Config.ARGB_8888) canvas.drawBitmap( icon!!, dpToPixel(2.4f / scale), dpToPixel(2.4f / scale), Paint() ) return drawingBitmap } private fun getSquirclePath( left: Float, top: Float, radius: Int ): Path { val radiusToPow = (radius * radius * radius).toDouble() val path = Path() path.moveTo(-radius.toFloat(), 0f) for (x in -radius..radius) path.lineTo( x.toFloat(), Math.cbrt(radiusToPow - abs(x * x * x)).toFloat() ) for (x in radius downTo -radius) path.lineTo( x.toFloat(), -Math.cbrt(radiusToPow - abs(x * x * x)).toFloat() ) path.close() val matrix = Matrix() matrix.postTranslate((left + radius), (top + radius)) path.transform(matrix) return path } } |