ref: c47403765e3fe723e11c9627d8f876a2ba1763f9
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 104 105 |
// 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 -> R.drawable.cablecar_black LineType.CABLE_CAR -> R.drawable.cabletram_black LineType.FUNICULAR -> R.drawable.funicular_black LineType.MONORAIL -> R.drawable.monorail_black LineType.UNKNOWN -> R.drawable.vehicle_black LineType.PLANE -> R.drawable.plane_black LineType.WALK -> R.drawable.walk_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 } } |