Bimba.git

ref: 4e51fbe3b15b8a54f2382838cb437683c3cecb5c

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
	}
}