diff --git a/NGraphics/Element.cs b/NGraphics/Element.cs index 7a82ba49..03f48670 100644 --- a/NGraphics/Element.cs +++ b/NGraphics/Element.cs @@ -4,9 +4,18 @@ namespace NGraphics { + // https://www.w3.org/TR/SVG11/painting.html#DisplayProperty + public enum Display + { + Inline, + None, + // do any other matter? + } + public abstract class Element : IDrawable, IEdgeSampleable { - public string Id { get; set; } + public Display Display { get; set; } = Display.Inline; + public string Id { get; set; } public Transform Transform { get; set; } public virtual Pen Pen { get; set; } public virtual Brush Brush { get; set; } @@ -27,6 +36,7 @@ protected virtual void SetCloneData (Element clone) clone.Transform = Transform; clone.Pen = Pen; clone.Brush = Brush; + clone.Display = Display; } protected abstract Element CreateUninitializedClone (); public Element Clone () @@ -44,6 +54,8 @@ public Element Clone () public void Draw (ICanvas canvas) { + if (Display == Display.None) + return; var t = Transform; var pushedState = false; try { diff --git a/NGraphics/SvgReader.cs b/NGraphics/SvgReader.cs index 0811775d..e5cb1002 100644 --- a/NGraphics/SvgReader.cs +++ b/NGraphics/SvgReader.cs @@ -76,28 +76,41 @@ void AddElements (IList list, IEnumerable es, Pen inheritPen, AddElement (list, e, inheritPen, inheritBrush); } + class Style + { + public Display display; + public Pen pen; + public bool hasPen; + public Brush brush; + public bool hasBrush; + public void Apply(Element e) + { + if (e == null) + return; + e.Display = display; + } + } + void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritBrush) { // // Style // Element r = null; - Pen pen = null; - Brush brush = null; - bool hasPen, hasBrush; - ApplyStyle (e.Attributes ().ToDictionary (k => k.Name.LocalName, v => v.Value), ref pen, out hasPen, ref brush, out hasBrush); + Style eStyle = new Style(); + ApplyStyle (e.Attributes ().ToDictionary (k => k.Name.LocalName, v => v.Value), eStyle); var style = ReadString (e.Attribute ("style")); if (!string.IsNullOrWhiteSpace (style)) { - ApplyStyle (style, ref pen, out hasPen, ref brush, out hasBrush); + ApplyStyle (style, eStyle); } - pen = hasPen ? pen : inheritPen; - brush = hasBrush ? brush : inheritBrush; - //var id = ReadString (e.Attribute ("id")); - - // - // Elements - // - switch (e.Name.LocalName) { + if (!eStyle.hasPen) eStyle.pen = inheritPen; + if (!eStyle.hasBrush) eStyle.brush = inheritBrush; + //var id = ReadString (e.Attribute ("id")); + + // + // Elements + // + switch (e.Name.LocalName) { case "text": { var x = ReadNumber (e.Attribute ("x")); @@ -110,7 +123,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB if (fontSize >= 0) font.Size = fontSize; TextAlignment textAlignment = ReadTextAlignment(e); - var txt = new Text (new Rect (new Point (x, y), new Size (double.MaxValue, double.MaxValue)), font, textAlignment, pen, brush); + var txt = new Text (new Rect (new Point (x, y), new Size (double.MaxValue, double.MaxValue)), font, textAlignment, eStyle.pen, eStyle.brush); ReadTextSpans (txt, e); r = txt; } @@ -126,7 +139,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB if (ry == 0) { ry = rx; } - r = new Rectangle (new Rect (new Point (x, y), new Size (width, height)), new Size (rx, ry), pen, brush); + r = new Rectangle (new Rect (new Point (x, y), new Size (width, height)), new Size (rx, ry), eStyle.pen, eStyle.brush); } break; case "ellipse": @@ -135,7 +148,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB var cy = ReadNumber (e.Attribute ("cy")); var rx = ReadNumber (e.Attribute ("rx")); var ry = ReadNumber (e.Attribute ("ry")); - r = new Ellipse (new Point (cx - rx, cy - ry), new Size (2 * rx, 2 * ry), pen, brush); + r = new Ellipse (new Point (cx - rx, cy - ry), new Size (2 * rx, 2 * ry), eStyle.pen, eStyle.brush); } break; case "circle": @@ -143,7 +156,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB var cx = ReadNumber (e.Attribute ("cx")); var cy = ReadNumber (e.Attribute ("cy")); var rr = ReadNumber (e.Attribute ("r")); - r = new Ellipse (new Point (cx - rr, cy - rr), new Size (2 * rr, 2 * rr), pen, brush); + r = new Ellipse (new Point (cx - rr, cy - rr), new Size (2 * rr, 2 * rr), eStyle.pen, eStyle.brush); } break; @@ -151,7 +164,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB { var dA = e.Attribute ("d"); if (dA != null && !string.IsNullOrWhiteSpace (dA.Value)) { - var p = new Path (pen, brush); + var p = new Path (eStyle.pen, eStyle.brush); ReadPath (p, dA.Value); r = p; } @@ -161,7 +174,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB { var pA = e.Attribute ("points"); if (pA != null && !string.IsNullOrWhiteSpace (pA.Value)) { - var path = new Path (pen, brush); + var path = new Path (eStyle.pen, eStyle.brush); ReadPoints (path, pA.Value, true); r = path; } @@ -171,7 +184,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB { var pA = e.Attribute ("points"); if (pA != null && !string.IsNullOrWhiteSpace (pA.Value)) { - var path = new Path (pen, brush); + var path = new Path (eStyle.pen, eStyle.brush); ReadPoints (path, pA.Value, false); r = path; } @@ -183,7 +196,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB var groupId = e.Attribute("id"); if (groupId != null && !string.IsNullOrEmpty(groupId.Value)) g.Id = groupId.Value; - AddElements (g.Children, e.Elements (), pen, brush); + AddElements (g.Children, e.Elements (), eStyle.pen, eStyle.brush); r = g; } break; @@ -194,7 +207,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB XElement useE; if (defs.TryGetValue (href.Trim ().Replace ("#", ""), out useE)) { var useList = new List (); - AddElement (useList, useE, pen, brush); + AddElement (useList, useE, eStyle.pen, eStyle.brush); r = useList.FirstOrDefault (); } } @@ -222,7 +235,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB var x2 = ReadNumber ( e.Attribute("x2") ); var y1 = ReadNumber ( e.Attribute("y1") ); var y2 = ReadNumber ( e.Attribute("y2") ); - var p = new Path (pen, null); + var p = new Path (eStyle.pen, null); p.MoveTo (x1, y1); p.LineTo (x2, y2); r = p; @@ -256,7 +269,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB var systemLanguage = ee.Attribute("systemLanguage"); // currently no support for any of these restrictions if (requiredFeatures == null && requiredExtensions == null && systemLanguage == null) - AddElement (list, ee, pen, brush); + AddElement (list, ee, eStyle.pen, eStyle.brush); } } break; @@ -272,6 +285,7 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB } if (r != null) { + eStyle.Apply(r); r.Transform = ReadTransform (ReadString (e.Attribute ("transform"))); var ida = e.Attribute("id"); if (ida != null && !string.IsNullOrEmpty (ida.Value)) { @@ -283,10 +297,10 @@ void AddElement (IList list, XElement e, Pen inheritPen, Brush inheritB Regex keyValueRe = new Regex (@"\s*([\w-]+)\s*:\s*(.*)"); - void ApplyStyle (string style, ref Pen pen, out bool hasPen, ref Brush brush, out bool hasBrush) + void ApplyStyle (string style, Style eStyle) { var d = ParseStyle(style); - ApplyStyle (d, ref pen, out hasPen, ref brush, out hasBrush); + ApplyStyle (d, eStyle); } Dictionary ParseStyle(string style) @@ -304,33 +318,39 @@ Dictionary ParseStyle(string style) return d; } - string GetString (Dictionary style, string name, string defaultValue = "") - { - string v; - if (style.TryGetValue (name, out v)) - return v; - return defaultValue; - } + string GetString(Dictionary style, string name, string defaultValue = "") + { + string v; + if (style.TryGetValue(name, out v)) + return v; + return defaultValue; + } - Regex fillUrlRe = new Regex (@"url\s*\(\s*#([^\)]+)\)"); + Regex fillUrlRe = new Regex (@"url\s*\(\s*#([^\)]+)\)"); - void ApplyStyle (Dictionary style, ref Pen pen, out bool hasPen, ref Brush brush, out bool hasBrush) + void ApplyStyle (Dictionary style, Style eStyle) { - // - // Pen attributes - // - var strokeWidth = GetString (style, "stroke-width"); + var display = GetString(style, "display"); + if (string.Compare(display, "none", StringComparison.OrdinalIgnoreCase) == 0) + eStyle.display = Display.None; + else if (string.Compare(display, "inline", StringComparison.OrdinalIgnoreCase) == 0) + eStyle.display = Display.Inline; + + // + // Pen attributes + // + var strokeWidth = GetString (style, "stroke-width"); if (!string.IsNullOrWhiteSpace (strokeWidth)) { - if (pen == null) - pen = new Pen (); - pen.Width = ReadNumber (strokeWidth); + if (eStyle.pen == null) + eStyle.pen = new Pen (); + eStyle.pen.Width = ReadNumber (strokeWidth); } var strokeOpacity = GetString (style, "stroke-opacity"); if (!string.IsNullOrWhiteSpace (strokeOpacity)) { - if (pen == null) - pen = new Pen (); - pen.Color = pen.Color.WithAlpha (ReadNumber (strokeOpacity)); + if (eStyle.pen == null) + eStyle.pen = new Pen (); + eStyle.pen.Color = eStyle.pen.Color.WithAlpha (ReadNumber (strokeOpacity)); } // @@ -338,21 +358,21 @@ void ApplyStyle (Dictionary style, ref Pen pen, out bool hasPen, // var stroke = GetString (style, "stroke").Trim (); if (string.IsNullOrEmpty (stroke)) { - // No change - hasPen = false; + // No change + eStyle.hasPen = false; } else if (stroke.Equals("none", StringComparison.OrdinalIgnoreCase)) { - hasPen = true; - pen = null; + eStyle.hasPen = true; + eStyle.pen = null; } else { - hasPen = true; - if (pen == null) - pen = new Pen (); + eStyle.hasPen = true; + if (eStyle.pen == null) + eStyle.pen = new Pen (); Color color; if (Colors.TryParse (stroke, out color)) { - if (pen.Color.Alpha == 1) - pen.Color = color; + if (eStyle.pen.Color.Alpha == 1) + eStyle.pen.Color = color; else - pen.Color = color.WithAlpha (pen.Color.Alpha); + eStyle.pen.Color = color.WithAlpha (eStyle.pen.Color.Alpha); } } @@ -361,9 +381,9 @@ void ApplyStyle (Dictionary style, ref Pen pen, out bool hasPen, // var fillOpacity = GetString (style, "fill-opacity"); if (!string.IsNullOrWhiteSpace (fillOpacity)) { - if (brush == null) - brush = new SolidBrush (); - var sb = brush as SolidBrush; + if (eStyle.brush == null) + eStyle.brush = new SolidBrush (); + var sb = eStyle.brush as SolidBrush; if (sb != null) sb.Color = sb.Color.WithAlpha (ReadNumber (fillOpacity)); } @@ -373,18 +393,18 @@ void ApplyStyle (Dictionary style, ref Pen pen, out bool hasPen, // var fill = GetString (style, "fill").Trim (); if (string.IsNullOrEmpty (fill)) { - // No change - hasBrush = false; + // No change + eStyle.hasBrush = false; } else if (fill.Equals("none", StringComparison.OrdinalIgnoreCase)) { - hasBrush = true; - brush = null; + eStyle.hasBrush = true; + eStyle.brush = null; } else { - hasBrush = true; + eStyle.hasBrush = true; Color color; if (Colors.TryParse (fill, out color)) { - var sb = brush as SolidBrush; + var sb = eStyle.brush as SolidBrush; if (sb == null) { - brush = new SolidBrush (color); + eStyle.brush = new SolidBrush (color); } else { if (sb.Color.Alpha == 1) sb.Color = color; @@ -395,7 +415,7 @@ void ApplyStyle (Dictionary style, ref Pen pen, out bool hasPen, var urlM = fillUrlRe.Match (fill); if (urlM.Success) { var id = urlM.Groups [1].Value.Trim (); - brush = GetGradientBrush(id, null); + eStyle.brush = GetGradientBrush(id, null); } else { throw new NotSupportedException ("Fill " + fill); }