ref: 343255d5c2e7108dd510ca9e7707d2d3d67e0bc6
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 92 93 94 95 96 97 98 99 100 101 102 103 |
// SPDX-FileCopyrightText: Adam Evyčędo // // SPDX-License-Identifier: GPL-3.0-or-later 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.cbrt 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.METRO -> R.drawable.metro_black LineType.RAIL -> R.drawable.train_black LineType.FERRY -> R.drawable.ferry_black LineType.CABLE_TRAM -> TODO() LineType.CABLE_CAR -> TODO() LineType.FUNICULAR -> TODO() LineType.MONORAIL -> R.drawable.monorail_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(), cbrt(radiusToPow - abs(x * x * x)).toFloat() ) for (x in radius downTo -radius) path.lineTo( x.toFloat(), -cbrt(radiusToPow - abs(x * x * x)).toFloat() ) path.close() val matrix = Matrix() matrix.postTranslate((left + radius), (top + radius)) path.transform(matrix) return path } } |