From 20ffa77b3b2456ebd284406f97354f4192518c5f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 2 Aug 2026 02:42:35 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20relative=20lumin?= =?UTF-8?q?ance=20calculation=20with=20LUT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced the on-the-fly math calculation `.pow(2.4)` in `relativeLuminance` with a pre-computed 256-element Lookup Table (LUT). Because ARGB components only have 256 possible integer values (0-255), this is a highly effective and deterministic optimization. Co-authored-by: himattm <6266621+himattm@users.noreply.github.com> --- .../kotlin/halogen/ContrastValidator.kt | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/halogen-core/src/commonMain/kotlin/halogen/ContrastValidator.kt b/halogen-core/src/commonMain/kotlin/halogen/ContrastValidator.kt index 1158b97..710e118 100644 --- a/halogen-core/src/commonMain/kotlin/halogen/ContrastValidator.kt +++ b/halogen-core/src/commonMain/kotlin/halogen/ContrastValidator.kt @@ -85,6 +85,16 @@ internal object ContrastValidator { return if (issues.isEmpty()) ValidationResult.Pass else ValidationResult.Fail(issues) } + // Precompute sRGB linearization LUT to avoid expensive pow() calls on the fly + private val LINEARIZED_LUT: DoubleArray = DoubleArray(256) { rgbComponent -> + val normalized = rgbComponent / 255.0 + if (normalized <= 0.04045) { + normalized / 12.92 + } else { + ((normalized + 0.055) / 1.055).pow(2.4) + } + } + /** * Compute the relative luminance of an ARGB color. * @@ -95,9 +105,9 @@ internal object ContrastValidator { * - L = 0.2126 * R + 0.7152 * G + 0.0722 * B. */ fun relativeLuminance(argb: Int): Double { - val r = linearize(((argb shr 16) and 0xFF) / 255.0) - val g = linearize(((argb shr 8) and 0xFF) / 255.0) - val b = linearize((argb and 0xFF) / 255.0) + val r = LINEARIZED_LUT[(argb shr 16) and 0xFF] + val g = LINEARIZED_LUT[(argb shr 8) and 0xFF] + val b = LINEARIZED_LUT[argb and 0xFF] return 0.2126 * r + 0.7152 * g + 0.0722 * b } @@ -119,12 +129,4 @@ internal object ContrastValidator { fun meetsAA(foreground: Int, background: Int): Boolean { return contrastRatio(foreground, background) >= AA_RATIO } - - private fun linearize(component: Double): Double { - return if (component <= 0.04045) { - component / 12.92 - } else { - ((component + 0.055) / 1.055).pow(2.4) - } - } }