All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.com.bkahlert.kommons.test.UnicodeFont.kt Maven / Gradle / Ivy

package com.bkahlert.kommons.test

import kotlin.streams.asSequence

internal enum class UnicodeFont(
    private val capitalLetters: IntArray,
    private val smallLetters: IntArray,
    private val digits: IntArray? = null,
) {
    Bold("๐€".."๐™", "๐š".."๐ณ", "๐ŸŽ".."๐Ÿ—"),
    Italic(("๐ด".."๐‘").toIntArray(), "๐‘Ž๐‘๐‘๐‘‘๐‘’๐‘“๐‘”โ„Ž๐‘–๐‘—๐‘˜๐‘™๐‘š๐‘›๐‘œ๐‘๐‘ž๐‘Ÿ๐‘ ๐‘ก๐‘ข๐‘ฃ๐‘ค๐‘ฅ๐‘ฆ๐‘ง".codePoints),
    BoldItalic("๐‘จ".."๐’", "๐’‚".."๐’›"),
    Script("๐’œโ„ฌ๐’ž๐’Ÿโ„ฐโ„ฑ๐’ขโ„‹โ„๐’ฅ๐’ฆโ„’โ„ณ๐’ฉ๐’ช๐’ซ๐’ฌโ„›๐’ฎ๐’ฏ๐’ฐ๐’ฑ๐’ฒ๐’ณ๐’ด๐’ต".codePoints, "๐’ถ๐’ท๐’ธ๐’นโ„ฏ๐’ปโ„Š๐’ฝ๐’พ๐’ฟ๐“€๐“๐“‚๐“ƒโ„ด๐“…๐“†๐“‡๐“ˆ๐“‰๐“Š๐“‹๐“Œ๐“๐“Ž๐“".codePoints),
    BoldScript("๐“".."๐“ฉ", "๐“ช".."๐”ƒ"),
    Fraktur("๐”„๐”…โ„ญ๐”‡๐”ˆ๐”‰๐”Šโ„Œโ„‘๐”๐”Ž๐”๐”๐”‘๐”’๐”“๐””โ„œ๐”–๐”—๐”˜๐”™๐”š๐”›๐”œโ„จ".codePoints, ("๐”ž".."๐”ท").toIntArray()),
    BoldFraktur("๐•ฌ".."๐–…", "๐–†".."๐–Ÿ"),
    DoubleStruck("๐”ธ๐”นโ„‚๐”ป๐”ผ๐”ฝ๐”พโ„๐•€๐•๐•‚๐•ƒ๐•„โ„•๐•†โ„™โ„šโ„๐•Š๐•‹๐•Œ๐•๐•Ž๐•๐•โ„ค".codePoints, ("๐•’".."๐•ซ").toIntArray(), ("๐Ÿ˜".."๐Ÿก").toIntArray()),
    SansSerif("๐– ".."๐–น", "๐–บ".."๐—“", "๐Ÿข".."๐Ÿซ"),
    SansSerifBold("๐—”".."๐—ญ", "๐—ฎ".."๐˜‡", "๐Ÿฌ".."๐Ÿต"),
    SansSerifItalic("๐˜ˆ".."๐˜ก", "๐˜ข".."๐˜ป"),
    SansSerifBoldItalic("๐˜ผ".."๐™•", "๐™–".."๐™ฏ"),
    Monospace("๐™ฐ".."๐š‰", "๐šŠ".."๐šฃ", "๐Ÿถ".."๐Ÿฟ"),
    ;

    init {
        check(capitalLetters.size == 26) { "26 capital letters needed" }
        check(smallLetters.size == 26) { "26 small letters needed" }
        digits?.also { check(it.size == 10) { "either no or 10 digits needed" } }
    }

    constructor(capitalLetters: IntRange, smallLetters: IntRange, digits: IntRange? = null) : this(
        capitalLetters.toIntArray(), smallLetters.toIntArray(), digits?.toIntArray(),
    )

    fun convertCodePointOrNull(codePoint: Int): Int? =
        capitalLetters.getOrNull(codePoint - capitalLetterACodePoint)
            ?: smallLetters.getOrNull(codePoint - smallLetterACodePoint)
            ?: digits?.getOrNull(codePoint - digitZeroCodePoint)

    fun format(text: String, onFailure: (codePoint: Int) -> Int = { it }): String {
        return buildString {
            text.codePoints().forEach {
                val codePoint = convertCodePointOrNull(it) ?: onFailure(it)
                appendCodePoint(codePoint)
            }
        }
    }

    companion object {
        const val capitalLetterACodePoint = 'A'.code
        const val smallLetterACodePoint = 'a'.code
        const val digitZeroCodePoint = '0'.code
    }
}

private val String.codePoints: IntArray get() = codePoints().asSequence().toList().toIntArray()
private val String.codePoint: Int get() = codePoints.single()
private operator fun String.rangeTo(other: String): IntRange = codePoint..other.codePoint
private fun IntRange.toIntArray(): IntArray = toList().toIntArray()




© 2015 - 2025 Weber Informatics LLC | Privacy Policy