Beispiel #1
0
        private SvgElement CreateElement <T>(XmlReader reader, bool fragmentIsDocument, SvgDocument document) where T : SvgDocument, new()
        {
            SvgElement createdElement = null;
            string     elementName    = reader.LocalName;
            string     elementNS      = reader.NamespaceURI;

            //Trace.TraceInformation("Begin CreateElement: {0}", elementName);

            if (elementNS == SvgNamespace.UriString || string.IsNullOrEmpty(elementNS))
            {
                if (elementName == "svg")
                {
                    createdElement = (fragmentIsDocument) ? new T() : new SvgFragment();
                }
                else
                {
#if !USE_SOURCE_GENERATORS
                    ElementInfo validType;
                    if (availableElementsWithoutSvg.TryGetValue(elementName, out validType))
                    {
                        createdElement = (SvgElement)Activator.CreateInstance(validType.ElementType);
                    }
#else
                    if (availableElementsWithoutSvg.TryGetValue(elementName, out var validType))
                    {
                        createdElement = validType.CreateInstance();
                    }
#endif
                    else
                    {
                        createdElement = new SvgUnknownElement(elementName);
                    }
                }

                if (createdElement != null)
                {
                    SetAttributes(createdElement, reader, document);
                }
            }
            else
            {
                // All non svg element (html, ...)
                createdElement = new NonSvgElement(elementName, elementNS);
                SetAttributes(createdElement, reader, document);
            }

            //Trace.TraceInformation("End CreateElement");

            return(createdElement);
        }
Beispiel #2
0
        private SvgElement CreateElement <T>(XmlReader reader, bool fragmentIsDocument, SvgDocument document) where T : SvgDocument, new()
        {
            SvgElement createdElement = null;
            string     elementName    = reader.LocalName;
            string     elementNS      = reader.NamespaceURI;

            //Trace.TraceInformation("Begin CreateElement: {0}", elementName);

            if (elementNS == SvgAttributeAttribute.SvgNamespace || string.IsNullOrEmpty(elementNS))
            {
                if (elementName == "svg")
                {
                    createdElement = (fragmentIsDocument) ? new T() : new SvgFragment();
                }
                else
                {
                    ElementInfo validType;
                    if (AvailableElements.Where(e => !e.ElementName.Equals("svg", StringComparison.OrdinalIgnoreCase))
                        .ToDictionary(e => e.ElementName, e => e).TryGetValue(elementName, out validType))
                    {
                        createdElement = (SvgElement)Activator.CreateInstance(validType.ElementType);
                    }
                    else
                    {
                        createdElement = new SvgUnknownElement(elementName);
                    }
                }

                if (createdElement != null)
                {
                    SetAttributes(createdElement, reader, document);
                }
            }
            else
            {
                // All non svg element (html, ...)
                createdElement = new NonSvgElement(elementName);
                SetAttributes(createdElement, reader, document);
            }

            //Trace.TraceInformation("End CreateElement");

            return(createdElement);
        }
Beispiel #3
0
        private static SvgElement CreateElement <T>(XmlReader reader, bool fragmentIsDocument, SvgDocument document) where T : SvgDocument, new()
        {
            SvgElement createdElement = null;
            string     elementName    = reader.LocalName;
            string     elementNS      = reader.NamespaceURI;

            //Trace.TraceInformation("Begin CreateElement: {0}", elementName);

            if (elementNS == svgNS)
            {
                if (elementName == "svg")
                {
                    createdElement = (fragmentIsDocument) ? new T() : new SvgFragment();
                }
                else
                {
                    ElementInfo validType = AvailableElements.SingleOrDefault(e => e.ElementName == elementName);
                    if (validType != null)
                    {
                        createdElement = (SvgElement)Activator.CreateInstance(validType.ElementType);
                    }
                    else
                    {
                        createdElement = new SvgUnknownElement(elementName);
                    }
                }

                if (createdElement != null)
                {
                    SetAttributes(createdElement, reader, document);
                }
            }
            else
            {
                // All non svg element (html, ...)
                createdElement = new NonSvgElement(elementName);
                SetAttributes(createdElement, reader, document);
            }

            //Trace.TraceInformation("End CreateElement");

            return(createdElement);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        private static T Open <T>(XmlReader reader) where T : SvgDocument, new()
        {
            try
            {
                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);
                        if (ExceptionCaughtIsGdiPlusRelated(exc))
                        {
                            throw;
                        }                                                    // GDI+ errors should be rethrown
                    }
                }

                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)
                        {
                            try
                            {
                                var rootNode = new NonSvgElement();
                                rootNode.Children.Add(svgDocument);

                                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);
                                if (ExceptionCaughtIsGdiPlusRelated(ex))
                                {
                                    throw;
                                }                                                   // GDI+ errors should be rethrown
                            }
                        }
                    }
                }

                if (svgDocument != null)
                {
                    FlushStyles(svgDocument);
                }
                return(svgDocument);
            }
            // GDI+ loading errors will result in TypeInitializationExceptions,
            // for readability we will catch and wrap the error
            catch (Exception e)
            {
                if (ExceptionCaughtIsGdiPlusRelated(e))
                {
                    // Throw only the customized exception if we are sure GDI+ is causing the problem
                    throw new SvgGdiPlusCannotBeLoadedException(e);
                }
                // No wrapping, just rethrow the exception
                throw;
            }
        }