Ejemplo n.º 1
0
        private static T Open <T>(XmlReader reader) where T : SvgDocument, new()
        {
            if (!SkipGdiPlusCapabilityCheck)
            {
                EnsureSystemIsGdiPlusCapable(); //Validate whether the GDI+ can be loaded, this will yield an exception if not
            }
            var        elementStack = new Stack <SvgElement>();
            bool       elementEmpty;
            SvgElement element = null;
            SvgElement parent;
            T          svgDocument    = null;
            var        elementFactory = new SvgElementFactory();

            var styles = new List <ISvgNode>();

            while (reader.Read())
            {
                try
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        // Does this element have a value or children
                        // (Must do this check here before we progress to another node)
                        elementEmpty = reader.IsEmptyElement;
                        // Create element
                        if (elementStack.Count > 0)
                        {
                            element = elementFactory.CreateElement(reader, svgDocument);
                        }
                        else
                        {
                            svgDocument = elementFactory.CreateDocument <T>(reader);
                            element     = svgDocument;
                        }

                        // Add to the parents children
                        if (elementStack.Count > 0)
                        {
                            parent = elementStack.Peek();
                            if (parent != null && element != null)
                            {
                                parent.Children.Add(element);
                                parent.Nodes.Add(element);
                            }
                        }

                        // Push element into stack
                        elementStack.Push(element);

                        // Need to process if the element is empty
                        if (elementEmpty)
                        {
                            goto case XmlNodeType.EndElement;
                        }

                        break;

                    case XmlNodeType.EndElement:

                        // Pop the element out of the stack
                        element = elementStack.Pop();

                        if (element.Nodes.OfType <SvgContentNode>().Any())
                        {
                            element.Content = (from e in element.Nodes select e.Content).Aggregate((p, c) => p + c);
                        }
                        else
                        {
                            element.Nodes.Clear();     // No sense wasting the space where it isn't needed
                        }

                        if (element is SvgUnknownElement unknown && unknown.ElementName == "style")
                        {
                            styles.Add(unknown);
                        }
                        break;

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                    case XmlNodeType.SignificantWhitespace:
                        element = elementStack.Peek();
                        element.Nodes.Add(new SvgContentNode()
                        {
                            Content = reader.Value
                        });
                        break;

                    case XmlNodeType.EntityReference:
                        reader.ResolveEntity();
                        element = elementStack.Peek();
                        element.Nodes.Add(new SvgContentNode()
                        {
                            Content = reader.Value
                        });
                        break;
                    }
                }
                catch (Exception exc)
                {
                    Trace.TraceError(exc.Message);
                }
            }

            if (styles.Any())
            {
                var cssTotal  = styles.Select((s) => s.Content).Aggregate((p, c) => p + Environment.NewLine + c);
                var cssParser = new Parser();
                var sheet     = cssParser.Parse(cssTotal);

                foreach (var rule in sheet.StyleRules)
                {
                    try
                    {
                        var rootNode = new NonSvgElement();
                        rootNode.Children.Add(svgDocument);

                        var elemsToStyle = rootNode.QuerySelectorAll(rule.Selector.ToString(), elementFactory);
                        foreach (var elem in elemsToStyle)
                        {
                            foreach (var decl in rule.Declarations)
                            {
                                elem.AddStyle(decl.Name, decl.Term.ToString(), rule.Selector.GetSpecificity());
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceWarning(ex.Message);
                    }
                }
            }

            svgDocument?.FlushStyles(true);
            return(svgDocument);
        }
Ejemplo n.º 2
0
        private static T Open <T>(XmlReader reader) where T : SvgDocument, new()
        {
            var        elementStack = new Stack <SvgElement>();
            bool       elementEmpty;
            SvgElement element = null;
            SvgElement parent;
            T          svgDocument = null;

            var styles = new List <ISvgNode>();

            while (reader.Read())
            {
                try
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        // Does this element have a value or children
                        // (Must do this check here before we progress to another node)
                        elementEmpty = reader.IsEmptyElement;
                        // Create element
                        if (elementStack.Count > 0)
                        {
                            element = SvgElementFactory.CreateElement(reader, svgDocument);
                        }
                        else
                        {
                            svgDocument = SvgElementFactory.CreateDocument <T>(reader);
                            element     = svgDocument;
                        }

                        // Add to the parents children
                        if (elementStack.Count > 0)
                        {
                            parent = elementStack.Peek();
                            if (parent != null && element != null)
                            {
                                parent.Children.Add(element);
                                parent.Nodes.Add(element);
                            }
                        }

                        // Push element into stack
                        elementStack.Push(element);

                        // Need to process if the element is empty
                        if (elementEmpty)
                        {
                            goto case XmlNodeType.EndElement;
                        }

                        break;

                    case XmlNodeType.EndElement:

                        // Pop the element out of the stack
                        element = elementStack.Pop();

                        if (element.Nodes.OfType <SvgContentNode>().Any())
                        {
                            element.Content = (from e in element.Nodes select e.Content).Aggregate((p, c) => p + c);
                        }
                        else
                        {
                            element.Nodes.Clear();     // No sense wasting the space where it isn't needed
                        }

                        var unknown = element as SvgUnknownElement;
                        if (unknown != null && unknown.ElementName == "style")
                        {
                            styles.Add(unknown);
                        }
                        break;

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                        element = elementStack.Peek();
                        element.Nodes.Add(new SvgContentNode()
                        {
                            Content = reader.Value
                        });
                        break;

                    case XmlNodeType.EntityReference:
                        reader.ResolveEntity();
                        element = elementStack.Peek();
                        element.Nodes.Add(new SvgContentNode()
                        {
                            Content = reader.Value
                        });
                        break;
                    }
                }
                catch (Exception exc)
                {
                    Trace.TraceError(exc.Message);
                }
            }

            if (styles.Any())
            {
                var cssTotal  = styles.Select((s) => s.Content).Aggregate((p, c) => p + Environment.NewLine + c);
                var cssParser = new Parser();
                var sheet     = cssParser.Parse(cssTotal);
                AggregateSelectorList      aggList;
                IEnumerable <BaseSelector> selectors;
                IEnumerable <SvgElement>   elemsToStyle;

                foreach (var rule in sheet.StyleRules)
                {
                    aggList = rule.Selector as AggregateSelectorList;
                    if (aggList != null && aggList.Delimiter == ",")
                    {
                        selectors = aggList;
                    }
                    else
                    {
                        selectors = Enumerable.Repeat(rule.Selector, 1);
                    }

                    foreach (var selector in selectors)
                    {
                        elemsToStyle = svgDocument.QuerySelectorAll(rule.Selector.ToString());
                        foreach (var elem in elemsToStyle)
                        {
                            foreach (var decl in rule.Declarations)
                            {
                                elem.AddStyle(decl.Name, decl.Term.ToString(), rule.Selector.GetSpecificity());
                            }
                        }
                    }
                }
            }

            if (svgDocument != null)
            {
                FlushStyles(svgDocument);
            }
            return(svgDocument);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Opens an SVG document from the specified <see cref="Stream"/> and adds the specified entities.
        /// </summary>
        /// <param name="stream">The <see cref="Stream"/> containing the SVG document to open.</param>
        /// <param name="entities">Custom entity definitions.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="stream"/> parameter cannot be <c>null</c>.</exception>
        public static T Open <T>(Stream stream, Dictionary <string, string> entities) where T : SvgDocument, new()
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            //Trace.TraceInformation("Begin Read");

            using (var reader = new SvgTextReader(stream, entities))
            {
                var        elementStack = new Stack <SvgElement>();
                var        value        = new StringBuilder();
                bool       elementEmpty;
                SvgElement element = null;
                SvgElement parent;
                T          svgDocument = null;
                reader.XmlResolver        = new SvgDtdResolver();
                reader.WhitespaceHandling = WhitespaceHandling.None;

                while (reader.Read())
                {
                    try
                    {
                        switch (reader.NodeType)
                        {
                        case XmlNodeType.Element:
                            // Does this element have a value or children
                            // (Must do this check here before we progress to another node)
                            elementEmpty = reader.IsEmptyElement;
                            // Create element
                            if (elementStack.Count > 0)
                            {
                                element = SvgElementFactory.CreateElement(reader, svgDocument);
                            }
                            else
                            {
                                svgDocument = SvgElementFactory.CreateDocument <T>(reader);
                                element     = svgDocument;
                            }

                            if (element == null)
                            {
                                continue;
                            }

                            // Add to the parents children
                            if (elementStack.Count > 0)
                            {
                                parent = elementStack.Peek();
                                parent.Children.Add(element);
                            }

                            // Push element into stack
                            elementStack.Push(element);

                            // Need to process if the element is empty
                            if (elementEmpty)
                            {
                                goto case XmlNodeType.EndElement;
                            }

                            break;

                        case XmlNodeType.EndElement:
                            // Skip if no element was created and is not the closing tag for the last
                            // known element
                            if (element == null && reader.LocalName != elementStack.Peek().ElementName)
                            {
                                continue;
                            }
                            // Pop the element out of the stack
                            element = elementStack.Pop();

                            if (value.Length > 0)
                            {
                                element.Content = value.ToString();
                                // Reset content value for new element
                                value = new StringBuilder();
                            }
                            break;

                        case XmlNodeType.CDATA:
                        case XmlNodeType.Text:
                            value.Append(reader.Value);
                            break;
                        }
                    }
                    catch (Exception exc)
                    {
                        Trace.TraceError(exc.Message);
                    }
                }

                //Trace.TraceInformation("End Read");
                return(svgDocument);
            }
        }
Ejemplo n.º 4
0
        private static T Open <T>(XmlReader reader) where T : SvgDocument, new()
        {
            var        elementStack = new Stack <SvgElement>();
            bool       elementEmpty;
            SvgElement element = null;
            SvgElement parent;
            T          svgDocument    = null;
            var        elementFactory = new SvgElementFactory();

            var styles = new List <ISvgNode>();

            while (reader.Read())
            {
                try
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        // Does this element have a value or children
                        // (Must do this check here before we progress to another node)
                        elementEmpty = reader.IsEmptyElement;
                        // Create element
                        if (elementStack.Count > 0)
                        {
                            element = elementFactory.CreateElement(reader, svgDocument);
                        }
                        else
                        {
                            svgDocument = elementFactory.CreateDocument <T>(reader);
                            element     = svgDocument;
                        }

                        // Add to the parents children
                        if (elementStack.Count > 0)
                        {
                            parent = elementStack.Peek();
                            if (parent != null && element != null)
                            {
                                parent.Children.Add(element);
                                parent.Nodes.Add(element);
                            }
                        }

                        // Push element into stack
                        elementStack.Push(element);

                        // Need to process if the element is empty
                        if (elementEmpty)
                        {
                            goto case XmlNodeType.EndElement;
                        }

                        break;

                    case XmlNodeType.EndElement:

                        // Pop the element out of the stack
                        element = elementStack.Pop();

                        if (element.Nodes.OfType <SvgContentNode>().Any())
                        {
                            element.Content = (from e in element.Nodes select e.Content).Aggregate((p, c) => p + c);
                        }
                        else
                        {
                            element.Nodes.Clear();     // No sense wasting the space where it isn't needed
                        }

                        var unknown = element as SvgUnknownElement;
                        if (unknown != null && unknown.ElementName == "style")
                        {
                            styles.Add(unknown);
                        }
                        break;

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                        element = elementStack.Peek();
                        element.Nodes.Add(new SvgContentNode()
                        {
                            Content = reader.Value
                        });
                        break;

                    case XmlNodeType.EntityReference:
                        reader.ResolveEntity();
                        element = elementStack.Peek();
                        element.Nodes.Add(new SvgContentNode()
                        {
                            Content = reader.Value
                        });
                        break;
                    }
                }
                catch (Exception exc)
                {
                    Trace.TraceError(exc.Message);
                }
            }

            return(svgDocument);
        }