using System; using System.Numerics; namespace LightlessSync.UI.Style { internal static class Luminance { public static float BrightnessThreshold { get; set; } = 0.4f; public static float HighlightBoostMax { get; set; } = 0.1f; public static float SmoothFactor { get; set; } = 0.15f; private static float Brightness(Vector4 color) => Math.Max(color.X, Math.Max(color.Y, color.Z)); public static float ComputeHighlight(Vector4? textColor, Vector4? glowColor) { float brightnessText = textColor.HasValue ? Brightness(textColor.Value) : 1f; float brightnessGlow = glowColor.HasValue ? Brightness(glowColor.Value) : 1f; if (brightnessText >= BrightnessThreshold || brightnessGlow >= BrightnessThreshold) return 0f; float deficit = Math.Min(BrightnessThreshold - brightnessText, BrightnessThreshold - brightnessGlow); float factor = Math.Clamp(deficit / BrightnessThreshold, 0f, 1f); factor = MathF.Pow(factor, 2.0f); return factor * HighlightBoostMax; } public static Vector4 BackgroundContrast(Vector4? textColor, Vector4? glowColor, Vector4 backgroundColor, ref Vector4 currentBg) { if (!textColor.HasValue && !glowColor.HasValue) return backgroundColor; float brightnessText = textColor.HasValue ? Brightness(textColor.Value) : 0f; float brightnessGlow = glowColor.HasValue ? Brightness(glowColor.Value) : 0f; float fgBrightness = Math.Max(brightnessText, brightnessGlow); float bgBrightness = Brightness(backgroundColor); float diff = Math.Abs(bgBrightness - fgBrightness); bool shouldBeDark = fgBrightness > 0.5f; Vector4 targetBg; if (diff >= BrightnessThreshold) { targetBg = backgroundColor; } else { targetBg = shouldBeDark ? new Vector4(0.05f, 0.05f, 0.05f, backgroundColor.W) : new Vector4(0.95f, 0.95f, 0.95f, backgroundColor.W); } float t = Math.Clamp(SmoothFactor, 0f, 1f); currentBg = t <= 0f ? targetBg : Vector4.Lerp(currentBg, targetBg, t); return currentBg; } } }