private static bool IsValidColor(string color) { color = color.Trim(); return(color.StartsWith("#", StringComparison.Ordinal) || Regex.IsMatch(color, @"[\/\\*|\-|\+].*#") || // Test case when there is color math involved: like @light-blue: @nice-blue + #111; ColorParser.TryParseColor(color, ColorParser.Options.AllowNames | ColorParser.Options.LooseParsing) != null); }
/// <summary> /// Create the brush for the given attribute name /// </summary> private GraphicBrush CreateBrush(XElement element, string name, bool setDefault, GraphicPath graphicPath, Matrix currentTransformationMatrix, double parentOpacity) { var strVal = cssStyleCascade.GetProperty(name); // 1: there is no value in the cascade if (string.IsNullOrEmpty(strVal)) { if (setDefault) { var alphad = GetAlpha(name, parentOpacity); return(new GraphicSolidColorBrush { Color = Color.FromArgb((byte)(alphad * 255), 0x00, 0x00, 0x00) }); } return(null); } strVal = strVal.Trim(); // 2: "none" is specified if (strVal == "none") { return(null); } var alpha = GetAlpha(name, parentOpacity); // 3: an url is specified if (strVal.StartsWith("url(", StringComparison.OrdinalIgnoreCase)) { int endUri = strVal.IndexOf(")", StringComparison.OrdinalIgnoreCase); var uri = strVal.Substring(4, endUri - 4); uri = uri.Trim(); var id = uri.Substring(1); var bounds = graphicPath.Geometry.Bounds; return(CreateGradientBrush(id, alpha, currentTransformationMatrix, bounds)); } // 4: use the current color if (strVal == "currentColor") { return(CreateBrush(element, "color", setDefault, graphicPath, currentTransformationMatrix, parentOpacity)); } // 5: try color formats of different flavours (hex, rgb, name) var success = ColorParser.TryParseColor(strVal, alpha, out Color color); if (success) { return(new GraphicSolidColorBrush { Color = color }); } return(null); }
public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { FunctionColor function = (FunctionColor)item; if (!function.IsValid) { yield break; } ColorModel model = ColorParser.TryParseColor(function.Text, ColorParser.Options.AllowAlpha); if (model != null) { // Don't convert RGBA and HSLA to HEX or named color if (model.Alpha == 1) { if (ColorConverterSmartTagAction.GetNamedColor(model.Color) != null) { yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Name)); } yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.RgbHex3)); } if (model.Format == ColorFormat.Rgb) { yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Hsl)); } else if (model.Format == ColorFormat.Hsl) { yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Rgb)); } } }
public IEnumerable <ITagSpan <ColorTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (WebEditor.Host == null || spans.Count == 0 || spans[0].Length == 0 || spans[0].Length >= _buffer.CurrentSnapshot.Length) { yield break; } var tree = CssEditorDocument.FromTextBuffer(_buffer).Tree; IEnumerable <ParseItem> items = GetColors(tree, spans[0]); foreach (var item in items.Where(i => (i.Start + i.Length) <= _buffer.CurrentSnapshot.Length)) { SnapshotSpan span = new SnapshotSpan(_buffer.CurrentSnapshot, item.Start, item.Length); ColorModel colorModel = ColorParser.TryParseColor(item, ColorParser.Options.AllowAlpha | ColorParser.Options.AllowNames); // Fix up for rebeccapurple adornment as it isn't parsed by ColorParser currently if (colorModel == null && item.Text == "rebeccapurple") { // as per http://lists.w3.org/Archives/Public/www-style/2014Jun/0312.html colorModel = ColorParser.TryParseColor("#663399", ColorParser.Options.AllowAlpha | ColorParser.Options.AllowNames); } if (colorModel != null) { yield return(new TagSpan <ColorTag>(span, new ColorTag(colorModel.Color))); } } }
private static string GetChannelExpression(Match match, char channel) { var color = ColorParser.TryParseColor(match.Value, ColorParser.Options.AllowNames | ColorParser.Options.LooseParsing); int num = 0; if (color == null && !int.TryParse(match.Value, out num)) { return(null); } else if (color != null) { if (channel == 'R') { return(color.Color.R.ToString(CultureInfo.CurrentCulture)); } if (channel == 'G') { return(color.Color.G.ToString(CultureInfo.CurrentCulture)); } return(color.Color.B.ToString(CultureInfo.CurrentCulture)); } return(Math.Min(num, 255).ToString(CultureInfo.CurrentCulture)); }
public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { HexColorValue hex = (HexColorValue)item; if (!item.IsValid) { yield break; } ColorModel model = ColorParser.TryParseColor(hex.Text, ColorParser.Options.None); if (model != null) { if (ColorConverterSmartTagAction.GetNamedColor(model.Color) != null) { yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Name)); } if (model.Format == ColorFormat.RgbHex6) { model.Format = ColorFormat.RgbHex3; string hex3 = ColorFormatter.FormatColor(model, ColorFormat.RgbHex3); if (hex3.Length == 4) { yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.RgbHex3)); } } yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Rgb)); yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Hsl)); } }
/// <summary> /// Get common gradient properties for linear and radial gradient /// </summary> private void GetCommonGradientProperties(XElement gradientElem, double opacity, GraphicGradientBrush gradientBrush) { var gradientUnitsAttribute = gradientElem.Attribute("gradientUnits"); if (gradientUnitsAttribute != null) { switch (gradientUnitsAttribute.Value) { case "userSpaceOnUse": gradientBrush.MappingMode = GraphicBrushMappingMode.Absolute; break; case "objectBoundingBox": gradientBrush.MappingMode = GraphicBrushMappingMode.RelativeToBoundingBox; break; } } foreach (var stopElem in gradientElem.Elements(svgNamespace + "stop")) { cssStyleCascade.PushStyles(stopElem); var stop = new GraphicGradientStop(); gradientBrush.GradientStops.Add(stop); double retVal; (_, retVal) = doubleParser.GetNumberPercent(stopElem, "offset", 0); stop.Position = retVal; var stopOpacity = cssStyleCascade.GetNumberPercentFromTop("stop-opacity", 1); var colorAttr = cssStyleCascade.GetPropertyFromTop("stop-color"); if (colorAttr != null && ColorParser.TryParseColor(colorAttr, opacity * stopOpacity, out Color color)) { stop.Color = color; } else { stop.Color = Colors.Black; } cssStyleCascade.Pop(); } }
private static IEnumerable <ColorModel> GetApplicableColors(string propertyName) { List <ParseItem> items = new List <ParseItem>(); //bool hasCustomItems = false; foreach (var item in _directives.Where(d => d.IsValid)) { // Global if (item.Keyword.Text == "global") { var visitor = new CssItemCollector <Declaration>(); item.Accept(visitor); items.AddRange(visitor.Items); } // Specific //else if (item.Keyword.Text == "specific") //{ // var visitor = new CssItemCollector<Declaration>(); // item.Accept(visitor); // var decs = visitor.Items.Where(d => propertyName.StartsWith(d.PropertyName.Text)); // if (decs.Any()) // { // items.AddRange(decs); // hasCustomItems = true; // } //} //// Catch all //else if (!hasCustomItems && item.Keyword.Text == "unspecified") //{ // var visitor = new CssItemCollector<Declaration>(); // item.Accept(visitor); // items.AddRange(visitor.Items); //} } foreach (Declaration declaration in items) { ColorModel model = ColorParser.TryParseColor(declaration.Values[0].Text, ColorParser.Options.AllowAlpha | ColorParser.Options.AllowNames); if (model != null) { yield return(model); } } }
public IEnumerable<ITagSpan<ColorTag>> GetTags(NormalizedSnapshotSpanCollection spans) { if (WebEditor.Host == null || spans.Count == 0 || spans[0].Length == 0 || spans[0].Length >= _buffer.CurrentSnapshot.Length) yield break; var tree = CssEditorDocument.FromTextBuffer(_buffer).Tree; IEnumerable<ParseItem> items = GetColors(tree, spans[0]); foreach (var item in items.Where(i => (i.Start + i.Length) <= _buffer.CurrentSnapshot.Length)) { SnapshotSpan span = new SnapshotSpan(_buffer.CurrentSnapshot, item.Start, item.Length); ColorModel colorModel = ColorParser.TryParseColor(item, ColorParser.Options.AllowAlpha | ColorParser.Options.AllowNames); if (colorModel != null) { yield return new TagSpan<ColorTag>(span, new ColorTag(colorModel.Color)); } } }
public IEnumerable <ITagSpan <ColorTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0 || spans[0].Length == 0 || spans[0].Length >= _buffer.CurrentSnapshot.Length || !EnsureInitialized()) { yield break; } IEnumerable <ParseItem> items = GetColors(spans[0]); foreach (var item in items.Where(i => (i.Start + i.Length) <= _buffer.CurrentSnapshot.Length)) { SnapshotSpan span = new SnapshotSpan(_buffer.CurrentSnapshot, item.Start, item.Length); ColorModel colorModel = ColorParser.TryParseColor(item, ColorParser.Options.AllowAlpha | ColorParser.Options.AllowNames); if (colorModel != null) { yield return(new TagSpan <ColorTag>(span, new ColorTag(colorModel.Color))); } } }
private string[] Flatten(string variableValue, List <string> alreadyProcessed, ref bool hasColorValue) { var invalid = ">>INVALID<<"; while (_colorVariableRegex.IsMatch(variableValue)) { variableValue = _colorVariableRegex.Replace(variableValue, new MatchEvaluator(match => { if (alreadyProcessed.Contains(match.Value) || !_variableList.Any(v => v.Name == match.Value)) { return(invalid); } return(_variableList.Where(v => v.Name == match.Value).FirstOrDefault().Value); })); if (variableValue.Contains(invalid)) { return(null); } } var parsedItems = variableValue.Split(_grammerCharacters); if (parsedItems.Any(i => ColorParser.TryParseColor(i, ColorParser.Options.AllowNames | ColorParser.Options.LooseParsing) != null)) { hasColorValue = true; } var retValue = new[] { _colorTokenRegex.Replace(variableValue, new MatchEvaluator(match => GetChannelExpression(match, 'R') ?? invalid)), _colorTokenRegex.Replace(variableValue, new MatchEvaluator(match => GetChannelExpression(match, 'G') ?? invalid)), _colorTokenRegex.Replace(variableValue, new MatchEvaluator(match => GetChannelExpression(match, 'B') ?? invalid)) }; return(retValue.Any(v => v.Contains(invalid)) ? null : retValue); }
private static bool HandleHex(Direction direction, HexColorValue item, ITextSnapshot snapshot) { var model = ColorParser.TryParseColor(item.Text, ColorParser.Options.None); if (model != null) { var span = new SnapshotSpan(snapshot, item.Start, item.Length); if (direction == Direction.Down && model.HslLightness > 0) { model.Format = Editor.ColorFormat.RgbHex3; UpdateSpan(span, Editor.ColorFormatter.FormatColor(model.Darken(), model.Format), "Darken color"); } else if (direction == Direction.Up && model.HslLightness < 1) { model.Format = Editor.ColorFormat.RgbHex3; UpdateSpan(span, Editor.ColorFormatter.FormatColor(model.Brighten(), model.Format), "Brighten color"); } return(true); } return(false); }
public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { TokenItem token = (TokenItem)item; if (!token.IsValid || token.TokenType != CssTokenType.Identifier || token.FindType <Declaration>() == null) { yield break; } var color = Color.FromName(token.Text); if (color.IsNamedColor) { ColorModel model = ColorParser.TryParseColor(token.Text, ColorParser.Options.AllowNames); if (model != null) { yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.RgbHex3)); yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Rgb)); yield return(new ColorConverterSmartTagAction(itemTrackingSpan, model, ColorFormat.Hsl)); } } }
private List <string> Flatten(string variableValue, List <string> variables, ref bool hasColorValue) { if (variableValue == null) { return(null); } var retValue = new List <StringBuilder> { new StringBuilder(), new StringBuilder(), new StringBuilder() }; var token = new StringBuilder(); for (int i = 0; i < variableValue.Length; i++) { var character = variableValue[i]; if (i == variableValue.Length - 1 || (_operators.Contains(character) && token.Length > 0 && variableValue[i - 1] == ' ')) { if (i == variableValue.Length - 1) { token.Append(character); } if (_variableSigns.Contains(token[0])) { if (variables.Contains(token.ToString())) { return(null); } variables.Add(token.ToString()); var list = _variableList.Where(v => v.Name == token.ToString()).FirstOrDefault(); if (list == null) { return(null); } var flattenedValue = Flatten(list.Value, variables, ref hasColorValue); if (flattenedValue == null) { return(null); } retValue[0].Append(flattenedValue[0]); retValue[1].Append(flattenedValue[1]); retValue[2].Append(flattenedValue[2]); } else { var color = ColorParser.TryParseColor(token.ToString(), ColorParser.Options.AllowNames | ColorParser.Options.LooseParsing); int num = 0; if (color == null && !int.TryParse(token.ToString(), out num)) { return(null); } else if (color != null) { hasColorValue = true; retValue[0].Append(color.Color.R); retValue[1].Append(color.Color.G); retValue[2].Append(color.Color.B); } else { num = Math.Min(num, 255); retValue[0].Append(num); retValue[1].Append(num); retValue[2].Append(num); } } if (i < variableValue.Length - 1) { retValue[0].Append(character); retValue[1].Append(character); retValue[2].Append(character); } token.Clear(); } else if (character != ' ') { token.Append(character); } } return(retValue.Select(b => b.ToString()).ToList()); }