private static Tuple<decimal, decimal, decimal> ConvertToHSL(ColorValue param, IPosition position) { if (param is HSLColorValue) { var hsl = (HSLColorValue)param; decimal h,s,l; h = ((NumberValue)hsl.Hue).Value; s = ((NumberValue)hsl.Saturation).Value; l = ((NumberValue)hsl.Lightness).Value; return Tuple.Create(h, s, l); } decimal r, g, b; r = g = b = -1; if (param is RGBColorValue) { var rgb = (RGBColorValue)param; if (!(ConvertColorPart(rgb.Red, position, out r) & ConvertColorPart(rgb.Green, position, out g) & ConvertColorPart(rgb.Blue, position, out b))) { return null; } } if (param is RGBAColorValue) { var rgba = (RGBAColorValue)param; if (!(ConvertColorPart(rgba.Red, position, out r) & ConvertColorPart(rgba.Green, position, out g) & ConvertColorPart(rgba.Blue, position, out b))) { return null; } } if (param is HexTripleColorValue) { var hex3 = (HexTripleColorValue)param; r = hex3.Red; g = hex3.Green; b = hex3.Blue; } if (param is HexSextupleColorValue) { var hex6 = (HexSextupleColorValue)param; r = hex6.Red; g = hex6.Green; b = hex6.Blue; } if (param is NamedColorValue) { var named = (NamedColorValue)param; r = ((int)named.Color >> 16) & 0xFF; g = ((int)named.Color >> 8) & 0xFF; b = ((int)named.Color >> 0) & 0xFF; } if (r == -1) { Current.RecordError(ErrorType.Compiler, position, "Couldn't convert [" + param + "] to HSL"); return null; } r /= 255m; g /= 255m; b /= 255m; var max = Math.Max(Math.Max(r, g), b); var min = Math.Min(Math.Min(r, g), b); decimal hue, saturation; hue = saturation = 0; var lightness = (max + min) / 2; var d = max - min; if (d != 0) { saturation = lightness >= 0.5m ? d / (2m - d) : d / (max + min); if (max == r) { hue = (g < b ? 6m : 0m) + (g - b) / d; } if (max == g) { hue = 2m + (b - r) / d; } if (max == b) { hue = 4m + (r - g) / d; } hue /= 6m; } hue *= 360; hue = decimal.Round(hue, 2, MidpointRounding.AwayFromZero); saturation = decimal.Round(saturation, 2, MidpointRounding.AwayFromZero); lightness = decimal.Round(lightness, 2, MidpointRounding.AwayFromZero); return Tuple.Create(hue, saturation, lightness); }
private static Tuple<decimal, decimal, decimal> ConvertToRGB(ColorValue param, IPosition position) { decimal r, g, b; if (param is RGBColorValue) { var rgb = (RGBColorValue)param; if (!(ConvertColorPart(rgb.Red, position, out r) & ConvertColorPart(rgb.Green, position, out g) & ConvertColorPart(rgb.Blue, position, out b))) { return null; } return Tuple.Create(r, g, b); } if (param is RGBAColorValue) { var rgba = (RGBAColorValue)param; if (!(ConvertColorPart(rgba.Red, position, out r) & ConvertColorPart(rgba.Green, position, out g) & ConvertColorPart(rgba.Blue, position, out b))) { return null; } return Tuple.Create(r, g, b); } if (param is HexTripleColorValue) { var hex3 = (HexTripleColorValue)param; r = hex3.Red; g = hex3.Green; b = hex3.Blue; return Tuple.Create(r, g, b); } if (param is HexSextupleColorValue) { var hex6 = (HexSextupleColorValue)param; r = hex6.Red; g = hex6.Green; b = hex6.Blue; return Tuple.Create(r, g, b); } if (param is NamedColorValue) { var named = (NamedColorValue)param; r = ((int)named.Color >> 16) & 0xFF; g = ((int)named.Color >> 8) & 0xFF; b = ((int)named.Color >> 0) & 0xFF; return Tuple.Create(r, g, b); } decimal h, s, l; h = s = l = -1; if (param is HSLColorValue) { var hsl = (HSLColorValue)param; h = ((NumberValue)hsl.Hue).Value; s = ((NumberValue)hsl.Saturation).Value; l = ((NumberValue)hsl.Lightness).Value; } if (h == -1) { Current.RecordError(ErrorType.Compiler, position, "Couldn't convert [" + param + "] to RGB"); return null; } r = g = b = -1; var c = (1 - Math.Abs(2 * l - 1)) * s; var hPrime = h / 60m; var x = c * (1 - Math.Abs(hPrime % 2 - 1)); if (hPrime >= 0 && hPrime < 1) { r = c; g = x; b = 0; } if (hPrime >= 1 && hPrime < 2) { r = x; g = c; b = 0; } if (hPrime >= 2 && hPrime < 3) { r = 0; g = c; b = x; } if (hPrime >= 3 && hPrime < 4) { r = 0; g = x; b = c; } if (hPrime >= 4 && hPrime < 5) { r = x; g = 0; b = c; } if (hPrime >= 5 && hPrime < 6) { r = c; g = 0; b = x; } var m = l - 0.5m * c; r = (r + m) * 255m; g = (g + m) * 255m; b = (b + m) * 255m; r = decimal.Round(r, 2, MidpointRounding.AwayFromZero); g = decimal.Round(g, 2, MidpointRounding.AwayFromZero); b = decimal.Round(b, 2, MidpointRounding.AwayFromZero); return Tuple.Create(r, g, b); }
private static ColorValue MinifyColor(ColorValue value) { // There's no lossless conversion for RGBA values if (value is RGBAColorValue) return value; // The smallest form of a color will *always* be the hex version or the named color version // So lets build the sextuple hex version var red = (byte)((NumberValue)BuiltInFunctions.Red(new[] { value }, Position.NoSite)).Value; var green = (byte)((NumberValue)BuiltInFunctions.Green(new[] { value }, Position.NoSite)).Value; var blue = (byte)((NumberValue)BuiltInFunctions.Blue(new[] { value }, Position.NoSite)).Value; string hex; using (var buffer = new StringWriter()) { (new HexSextupleColorValue(red, green, blue)).Write(buffer); hex = buffer.ToString().Substring(1); } var asNum = int.Parse(hex, System.Globalization.NumberStyles.HexNumber); string asNamed = null; if (Enum.IsDefined(typeof(NamedColor), asNum)) { asNamed = Enum.GetName(typeof(NamedColor), (NamedColor)asNum); } if (asNamed.HasValue() && asNamed.Length < 7) { return new NamedColorValue((NamedColor)asNum); } if (red.ToString("x").Distinct().Count() == 1 && green.ToString("x").Distinct().Count() == 1 && blue.ToString("x").Distinct().Count() == 1) { return new HexTripleColorValue(red, green, blue); } return new HexSextupleColorValue(red, green, blue); }