예제 #1
0
        public static Value Darken(IEnumerable<Value> parameters, IPosition position)
        {
            if (parameters.Count() != 2)
            {
                Current.RecordError(ErrorType.Compiler, position, "Darken expects a color parameter, and a percentage");
                return ExcludeFromOutputValue.Singleton;
            }

            var color = parameters.ElementAt(0);
            var percent = parameters.ElementAt(1);

            if (!(color is ColorValue))
            {
                Current.RecordError(ErrorType.Compiler, position, "Darken expects a color as its first parameter, found [" + color + "]");
                return ExcludeFromOutputValue.Singleton;
            }

            if (!(percent is NumberWithUnitValue))
            {
                Current.RecordError(ErrorType.Compiler, position, "Darken expects a percentage as its second parameter, found [" + percent + "]");
                return ExcludeFromOutputValue.Singleton;
            }

            var colorV = (ColorValue)color;
            var percentV = (NumberWithUnitValue)percent;

            if (percentV.Unit != Unit.Percent)
            {
                Current.RecordError(ErrorType.Compiler, position, "Darken expects a percentage as its second parameter, found [" + percent + "]");
                return ExcludeFromOutputValue.Singleton;
            }

            var hsl = ConvertToHSL(colorV, position);
            if (hsl == null) return ExcludeFromOutputValue.Singleton;

            var h = new NumberValue(hsl.Item1);
            var s = new NumberWithUnitValue(hsl.Item2 * 100m, Unit.Percent);

            var l = decimal.Round(hsl.Item3 - percentV.Value / 100m, 2);
            if (l < 0m) l = 0m;

            return new HSLColorValue(h, s, new NumberWithUnitValue(l * 100m, Unit.Percent));
        }
예제 #2
0
        public static Value Round(IEnumerable<Value> parameters, IPosition position)
        {
            if (parameters.Count() < 1 || parameters.Count() > 2)
            {
                Current.RecordError(ErrorType.Compiler, position, "Round expects 1 or 2 numeric parameters");
                return ExcludeFromOutputValue.Singleton;
            }

            if (parameters.Any(a => a is ExcludeFromOutputValue)) return ExcludeFromOutputValue.Singleton;
            if (parameters.Any(a => a is NotFoundValue)) return NotFoundValue.Default.BindToPosition(position.Start, position.Stop, position.FilePath);

            var toRound = parameters.ElementAt(0);
            Value precision = new NumberValue(0);

            if (parameters.Count() == 2)
            {
                precision = parameters.ElementAt(1);
            }

            if (!(toRound is NumberValue))
            {
                Current.RecordError(ErrorType.Compiler, position, "Round expects a number, with optional unit, as its first parameter; found [" + toRound + "]");
                return ExcludeFromOutputValue.Singleton;
            }

            if (!(precision is NumberValue) || precision is NumberWithUnitValue)
            {
                Current.RecordError(ErrorType.Compiler, position, "Round expects a number, without a unit, as its second parameter; found [" + precision + "]");
                return ExcludeFromOutputValue.Singleton;
            }

            var nPrecision = ((NumberValue)precision).Value;

            if ((int)nPrecision != nPrecision)
            {
                Current.RecordError(ErrorType.Compiler, position, "Round expects an integer as its second parameter, found [" + nPrecision + "]");
                return ExcludeFromOutputValue.Singleton;
            }

            if (toRound is NumberWithUnitValue)
            {
                var wUnit = (NumberWithUnitValue)toRound;

                return new NumberWithUnitValue(decimal.Round(wUnit.Value, (int)nPrecision, MidpointRounding.AwayFromZero), wUnit.Unit);
            }

            var woUnit = (NumberValue)toRound;

            return new NumberValue(decimal.Round(woUnit.Value, (int)nPrecision, MidpointRounding.AwayFromZero));
        }
예제 #3
0
        private static void TryMinifyNumberWithUnit(NumberWithUnitValue value, ReadOnlyDictionary<Unit, decimal> possibleConversions, ref NumberWithUnitValue smallest)
        {
            if (!possibleConversions.ContainsKey(value.Unit)) return;

            var min = MinifyNumberValue(value);

            var ret = new NumberWithUnitValue(min.Value, value.Unit);
            string retStr;
            using (var buffer = new StringWriter())
            {
                ret.Write(buffer);
                retStr = buffer.ToString();
            }

            var inBasic = min.Value * possibleConversions[value.Unit];

            foreach (var unit in possibleConversions.Keys)
            {
                var conversion = possibleConversions[unit];

                var maxPrecision = inBasic / conversion;

                // 5 decimal points seems like an acceptable level of precision; webkit seems to agree
                var inUnit = decimal.Round(maxPrecision, 5);

                var asNum = new NumberValue(inUnit);
                var minified = MinifyNumberValue(asNum);

                var newMin = new NumberWithUnitValue(minified.Value, unit);
                string newMinStr;

                using (var buffer = new StringWriter())
                {
                    newMin.Write(buffer);
                    newMinStr = buffer.ToString();
                }

                if (newMinStr.Length < retStr.Length)
                {
                    ret = newMin;
                    retStr = newMinStr;
                }
            }

            smallest = ret;
        }
예제 #4
0
        public static Value Gray(IEnumerable<Value> parameters, IPosition position)
        {
            if (parameters.Count() != 1)
            {
                Current.RecordError(ErrorType.Compiler, position, "Gray expects 1 color parameter");
                return ExcludeFromOutputValue.Singleton;
            }

            var param = parameters.ElementAt(0);

            if (param is ExcludeFromOutputValue) return ExcludeFromOutputValue.Singleton;
            if (param is NotFoundValue) return NotFoundValue.Default.BindToPosition(position.Start, position.Start, position.FilePath);

            if (!(param is ColorValue))
            {
                Current.RecordError(ErrorType.Compiler, position, "Gray expects a color value, found [" + param + "]");
                return ExcludeFromOutputValue.Singleton;
            }

            var parts = ConvertToRGB((ColorValue)param, position);
            if (parts == null) return ExcludeFromOutputValue.Singleton;

            var newPart = new NumberValue(decimal.Round((parts.Item1 + parts.Item2 + parts.Item3) / 3.0m, 2));

            if(param is RGBAColorValue)
            {
                var alpha = ((RGBAColorValue)param).Alpha;

                // Need to keep the alpah component in this case
                return new RGBAColorValue(newPart, newPart, newPart, alpha);
            }

            return new RGBColorValue(newPart, newPart, newPart);
        }
예제 #5
0
        private static NumberValue MinifyNumberValue(NumberValue value)
        {
            var asStr = value.Value.ToString();
            if (asStr.Contains('.'))
            {
                asStr = asStr.TrimEnd('0');
                asStr = asStr.TrimEnd('.');
            }

            asStr = asStr.TrimStart('0');

            if (asStr.Length == 0) asStr = "0";

            return new NumberValue(decimal.Parse(asStr));
        }