diff options
| author | Danny Lin <danny@kdrag0n.dev> | 2021-08-30 01:55:31 -0700 |
|---|---|---|
| committer | Danny Lin <danny@kdrag0n.dev> | 2021-08-30 01:56:52 -0700 |
| commit | 379d5f03a35314e44ca00c46821eb7f8dfd300ac (patch) | |
| tree | 6a6f075a0cb8e46a92f05d8471045b282ff0fbcf | |
| parent | 313f8d78c9cc809bf58f6f9fe9649cc951017fb8 (diff) | |
conversion: Move color conversions out of Color companion object
This should allow R8 to remove unused color spaces and graph code if
users avoid automatic conversion.
16 files changed, 49 insertions, 61 deletions
diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/Color.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/Color.kt index 130d4fd..13e26ea 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/Color.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/Color.kt @@ -1,50 +1,9 @@ package dev.kdrag0n.colorkt -import dev.kdrag0n.colorkt.util.conversion.ColorConverter -import dev.kdrag0n.colorkt.util.conversion.ColorType -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph -import dev.kdrag0n.colorkt.util.conversion.UnsupportedConversionException -import kotlin.jvm.JvmStatic - /** * Common interface for all colors. * * This makes no assumptions about the color itself, but implementations are expected to register conversion paths in * the global conversion graph when possible. */ -public interface Color { - public companion object { - private val pathCache = HashMap<Pair<ColorType, ColorType>, List<ColorConverter<Color, Color>>>() - - init { - // All first-party color spaces should be registered in order for conversions to work properly - registerAllColors() - } - - /** - * Convert this color to color space [T]. - * @throws UnsupportedConversionException if no automatic conversion path exists - * @return color as [T] - */ - public inline fun <reified T : Color> Color.convert(): T = this as? T - ?: convert(this, T::class) as T? - ?: throw UnsupportedConversionException("No conversion path from ${this::class} to ${T::class}") - - /** - * Convert [fromColor] to color space [toType]. - * @throws UnsupportedConversionException if no automatic conversion path exists - * @return color as [toType] - */ - @JvmStatic - public fun convert(fromColor: Color, toType: ColorType): Color? { - val pathKey = fromColor::class to toType - val path = pathCache[pathKey] - ?: ConversionGraph.findPath(fromColor::class, toType)?.also { pathCache[pathKey] = it } - ?: return null - - return path.fold(fromColor) { color, converter -> - converter.convert(color) - } - } - } -} +public interface Color diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/util/conversion/ConversionGraph.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/conversion/ConversionGraph.kt index 1f41bc6..bb457d1 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/util/conversion/ConversionGraph.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/conversion/ConversionGraph.kt @@ -1,8 +1,7 @@ -package dev.kdrag0n.colorkt.util.conversion +package dev.kdrag0n.colorkt.conversion import dev.kdrag0n.colorkt.Color import kotlin.jvm.JvmStatic -import kotlin.jvm.JvmSynthetic import kotlin.reflect.KClass internal typealias ColorType = KClass<out Color> @@ -20,10 +19,15 @@ public fun interface ColorConverter<F : Color, T : Color> { /** * Global color conversion graph, used for automatic conversions between different color spaces. */ -// This is public so that users can add custom color spaces. public object ConversionGraph { // Adjacency list: [vertex] = edges private val graph = mutableMapOf<ColorType, MutableList<ConversionEdge>>() + private val pathCache = HashMap<Pair<ColorType, ColorType>, List<ColorConverter<Color, Color>>>() + + init { + // All first-party color spaces should be registered in order for conversions to work properly + registerAllColors() + } /** * Add a conversion from color type F to T, specified as generic types. @@ -58,8 +62,7 @@ public object ConversionGraph { } } - @JvmSynthetic - internal fun findPath(from: ColorType, to: ColorType): List<ColorConverter<Color, Color>>? { + private fun findPath(from: ColorType, to: ColorType): List<ColorConverter<Color, Color>>? { val visited = HashSet<ConversionEdge>() val pathQueue = ArrayDeque(listOf( // Initial path: from node @@ -85,6 +88,32 @@ public object ConversionGraph { return null } + /** + * Convert this color to color space [T]. + * @throws UnsupportedConversionException if no automatic conversion path exists + * @return color as [T] + */ + public inline fun <reified T : Color> Color.convert(): T = this as? T + ?: convert(this, T::class) as T? + ?: throw UnsupportedConversionException("No conversion path from ${this::class} to ${T::class}") + + /** + * Convert [fromColor] to color space [toType]. + * @throws UnsupportedConversionException if no automatic conversion path exists + * @return color as [toType] + */ + @JvmStatic + public fun convert(fromColor: Color, toType: ColorType): Color? { + val pathKey = fromColor::class to toType + val path = pathCache[pathKey] + ?: findPath(fromColor::class, toType)?.also { pathCache[pathKey] = it } + ?: return null + + return path.fold(fromColor) { color, converter -> + converter.convert(color) + } + } + private data class ConversionEdge( val from: ColorType, val to: ColorType, diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ColorConversions.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/conversion/DefaultConversions.kt index 8010cda..48a63bd 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ColorConversions.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/conversion/DefaultConversions.kt @@ -1,4 +1,4 @@ -package dev.kdrag0n.colorkt +package dev.kdrag0n.colorkt.conversion import dev.kdrag0n.colorkt.rgb.LinearSrgb import dev.kdrag0n.colorkt.tristimulus.CieXyz diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/util/conversion/UnsupportedConversionException.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/conversion/UnsupportedConversionException.kt index 1ccbccb..8fa25bb 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/util/conversion/UnsupportedConversionException.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/conversion/UnsupportedConversionException.kt @@ -1,4 +1,4 @@ -package dev.kdrag0n.colorkt.util.conversion +package dev.kdrag0n.colorkt.conversion /** * Exception thrown when there is no automatic conversation path in diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/rgb/LinearSrgb.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/rgb/LinearSrgb.kt index c318ec8..f11df2c 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/rgb/LinearSrgb.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/rgb/LinearSrgb.kt @@ -1,6 +1,6 @@ package dev.kdrag0n.colorkt.rgb -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic import kotlin.jvm.JvmSynthetic diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyz.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyz.kt index 02d549e..5fa187e 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyz.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyz.kt @@ -2,7 +2,7 @@ package dev.kdrag0n.colorkt.tristimulus import dev.kdrag0n.colorkt.Color import dev.kdrag0n.colorkt.rgb.LinearSrgb -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic import kotlin.jvm.JvmSynthetic diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyzAbs.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyzAbs.kt index 1226277..0c7d720 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyzAbs.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/tristimulus/CieXyzAbs.kt @@ -1,7 +1,7 @@ package dev.kdrag0n.colorkt.tristimulus import dev.kdrag0n.colorkt.Color -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import kotlin.jvm.JvmName import kotlin.jvm.JvmOverloads import kotlin.jvm.JvmStatic diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/CieLab.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/CieLab.kt index 1322229..f4c5bcc 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/CieLab.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/CieLab.kt @@ -2,7 +2,7 @@ package dev.kdrag0n.colorkt.ucs.lab import dev.kdrag0n.colorkt.tristimulus.CieXyz import dev.kdrag0n.colorkt.data.Illuminants -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import dev.kdrag0n.colorkt.util.math.cbrt import dev.kdrag0n.colorkt.util.math.cube import kotlin.jvm.JvmName diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Oklab.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Oklab.kt index 782a79f..a7ccbac 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Oklab.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Oklab.kt @@ -2,7 +2,7 @@ package dev.kdrag0n.colorkt.ucs.lab import dev.kdrag0n.colorkt.rgb.LinearSrgb import dev.kdrag0n.colorkt.tristimulus.CieXyz -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import dev.kdrag0n.colorkt.util.math.cbrt import dev.kdrag0n.colorkt.util.math.cube import kotlin.jvm.JvmName diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Srlab2.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Srlab2.kt index 145ee2d..81d133b 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Srlab2.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lab/Srlab2.kt @@ -1,7 +1,7 @@ package dev.kdrag0n.colorkt.ucs.lab import dev.kdrag0n.colorkt.rgb.LinearSrgb -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import dev.kdrag0n.colorkt.util.math.cbrt import dev.kdrag0n.colorkt.util.math.cube import kotlin.jvm.JvmName diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/CieLch.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/CieLch.kt index 3da8c00..bf8c986 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/CieLch.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/CieLch.kt @@ -3,7 +3,7 @@ package dev.kdrag0n.colorkt.ucs.lch import dev.kdrag0n.colorkt.data.Illuminants import dev.kdrag0n.colorkt.tristimulus.CieXyz import dev.kdrag0n.colorkt.ucs.lab.CieLab -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import kotlin.jvm.JvmName import kotlin.jvm.JvmOverloads import kotlin.jvm.JvmStatic diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Oklch.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Oklch.kt index 8425b4f..cff03ae 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Oklch.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Oklch.kt @@ -1,7 +1,7 @@ package dev.kdrag0n.colorkt.ucs.lch import dev.kdrag0n.colorkt.ucs.lab.Oklab -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic import kotlin.jvm.JvmSynthetic diff --git a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Srlch2.kt b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Srlch2.kt index 67e19e3..718cfa7 100644 --- a/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Srlch2.kt +++ b/src/commonMain/kotlin/dev/kdrag0n/colorkt/ucs/lch/Srlch2.kt @@ -1,7 +1,7 @@ package dev.kdrag0n.colorkt.ucs.lch import dev.kdrag0n.colorkt.ucs.lab.Srlab2 -import dev.kdrag0n.colorkt.util.conversion.ConversionGraph +import dev.kdrag0n.colorkt.conversion.ConversionGraph import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic import kotlin.jvm.JvmSynthetic diff --git a/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/ConversionTests.kt b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/ConversionTests.kt index 16b7e03..179270e 100644 --- a/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/ConversionTests.kt +++ b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/ConversionTests.kt @@ -1,11 +1,11 @@ package dev.kdrag0n.colorkt.tests -import dev.kdrag0n.colorkt.Color.Companion.convert import dev.kdrag0n.colorkt.ucs.lab.Oklab import dev.kdrag0n.colorkt.ucs.lab.Oklab.Companion.toOklab import dev.kdrag0n.colorkt.ucs.lch.CieLch import dev.kdrag0n.colorkt.ucs.lch.Oklch import dev.kdrag0n.colorkt.ucs.lch.Oklch.Companion.toOklch +import dev.kdrag0n.colorkt.conversion.ConversionGraph.convert import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/GamutTests.kt b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/GamutTests.kt index b441b3f..c4328be 100644 --- a/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/GamutTests.kt +++ b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/GamutTests.kt @@ -1,6 +1,5 @@ package dev.kdrag0n.colorkt.tests -import dev.kdrag0n.colorkt.Color.Companion.convert import dev.kdrag0n.colorkt.cam.Zcam import dev.kdrag0n.colorkt.cam.Zcam.Companion.toZcam import dev.kdrag0n.colorkt.data.Illuminants @@ -13,6 +12,7 @@ import dev.kdrag0n.colorkt.tristimulus.CieXyzAbs.Companion.DEFAULT_SDR_WHITE_LUM import dev.kdrag0n.colorkt.tristimulus.CieXyzAbs.Companion.toAbs import dev.kdrag0n.colorkt.ucs.lab.CieLab import dev.kdrag0n.colorkt.ucs.lch.Oklch +import dev.kdrag0n.colorkt.conversion.ConversionGraph.convert import kotlin.test.Test import kotlin.test.assertFalse diff --git a/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/OklabTests.kt b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/OklabTests.kt index 06933b4..30266cf 100644 --- a/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/OklabTests.kt +++ b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/OklabTests.kt @@ -1,8 +1,8 @@ package dev.kdrag0n.colorkt.tests -import dev.kdrag0n.colorkt.Color.Companion.convert import dev.kdrag0n.colorkt.tristimulus.CieXyz import dev.kdrag0n.colorkt.ucs.lab.Oklab +import dev.kdrag0n.colorkt.conversion.ConversionGraph.convert import kotlin.test.Test class OklabTests { |
