diff --git a/ThemeProvider/ColorRange.cs b/ThemeProvider/ColorRange.cs index 53e44ab..f80963a 100644 --- a/ThemeProvider/ColorRange.cs +++ b/ThemeProvider/ColorRange.cs @@ -19,10 +19,15 @@ public readonly record struct ColorRange(Color Start, Color End) /// public double Distance => Start.DistanceTo(End); + /// + /// The perceptual (Oklab) distance below which the start and end colors are treated as a single color. + /// + private const double SingleColorDistanceThreshold = 1e-6; + /// /// Indicates whether this range represents a single color (start equals end). /// - public bool IsSingleColor => Distance < double.Epsilon; + public bool IsSingleColor => Distance < SingleColorDistanceThreshold; /// /// Creates a color range from two colors, automatically ordering them diff --git a/ThemeProvider/SemanticColorMapper.cs b/ThemeProvider/SemanticColorMapper.cs index c4daeb1..02311a9 100644 --- a/ThemeProvider/SemanticColorMapper.cs +++ b/ThemeProvider/SemanticColorMapper.cs @@ -177,8 +177,7 @@ private static double CalculateTargetLightnessForSemantic( if (allPriorities.Length == 1) { - double globalCenter = (globalMinLightness + globalMaxLightness) / 2.0; - return meaning == SemanticMeaning.Neutral ? globalCenter : globalCenter; + return (globalMinLightness + globalMaxLightness) / 2.0; } // Calculate position in range (0.0 to 1.0) diff --git a/ThemeProviderDemo/Program.cs b/ThemeProviderDemo/Program.cs index fdc96a0..e6d1ea9 100644 --- a/ThemeProviderDemo/Program.cs +++ b/ThemeProviderDemo/Program.cs @@ -754,19 +754,19 @@ private static IReadOnlyDictionary GetCompleteMappi return cachedCompletePalette; } - private static Vector4 ToImVec4(Color color, float alpha = 1.0f) + private static Vector4 ToImVec4(Color color, float? alpha = null) { Srgb srgb = color.ToSrgb(); - return new Vector4((float)srgb.R, (float)srgb.G, (float)srgb.B, alpha); + return new Vector4((float)srgb.R, (float)srgb.G, (float)srgb.B, alpha ?? (float)color.A); } private static Color AdjustBrightness(Color color, float factor) { - Srgb srgb = color.ToSrgb(); - return Color.FromSrgb( - Math.Clamp(srgb.R * factor, 0.0, 1.0), - Math.Clamp(srgb.G * factor, 0.0, 1.0), - Math.Clamp(srgb.B * factor, 0.0, 1.0), + // Multiplicative brightness is a linear-light operation; scale the linear channels, not the gamma-encoded sRGB ones. + return Color.FromLinear( + Math.Clamp(color.R * factor, 0.0, 1.0), + Math.Clamp(color.G * factor, 0.0, 1.0), + Math.Clamp(color.B * factor, 0.0, 1.0), color.A ); }