Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }