コード例 #1
0
        public void Visit(ISvgUseElement element)
        {
            SvgUseElement useElement = (SvgUseElement)element;
            SvgDocument   document   = useElement.OwnerDocument;
            XmlElement    refEl      = useElement.ReferencedElement;

            if (refEl == null)
            {
                return;
            }

            bool isImported = false;

            // For the external node, the documents are different, and we may not be
            // able to insert this node, so we first import it...
            if (useElement.OwnerDocument != refEl.OwnerDocument)
            {
                XmlElement importedNode =
                    useElement.OwnerDocument.ImportNode(refEl, true) as XmlElement;

                if (importedNode != null)
                {
                    SvgElement importedSvgElement = importedNode as SvgElement;
                    if (importedSvgElement != null)
                    {
                        importedSvgElement.Imported       = true;
                        importedSvgElement.ImportNode     = refEl as SvgElement;
                        importedSvgElement.ImportDocument = refEl.OwnerDocument as SvgDocument;
                    }

                    refEl      = importedNode;
                    isImported = true;
                }
            }
            XmlElement refElParent = (XmlElement)refEl.ParentNode;

            useElement.OwnerDocument.Static = true;
            useElement.CopyToReferencedElement(refEl);
            if (!isImported) // if imported, we do not need to remove it...
            {
                refElParent.RemoveChild(refEl);
            }
            useElement.AppendChild(refEl);

            // Now, render the use element...
            var refElement = useElement?.FirstChild;

            if (refElement is IElementVisitorTarget evt)
            {
                evt.Accept(this);
            }

            useElement.RemoveChild(refEl);
            useElement.RestoreReferencedElement(refEl);
            if (!isImported)
            {
                refElParent.AppendChild(refEl);
            }
            useElement.OwnerDocument.Static = false;
        }
コード例 #2
0
        public override PageElement VisitUseElement(SvgUseElement element)
        {
            if (element.IsRenderingDisabled || string.IsNullOrEmpty(element.Href))
            {
                return(null);
            }
            var tx        = element.X?.Value ?? 0;
            var ty        = element.Y?.Value ?? 0;
            var transform = SvgMatrix.CreateTranslate(tx, ty);

            PushMatrix(transform);
            PushTransformsMatrix(element.Transform);
            PageElement result;
            var         generated = element.GeneratedElement;

            if (generated is SvgSymbolElement symbol)
            {
                var viewportWidth  = element.Width?.Value ?? 0;
                var viewportHeight = element.Height?.Value ?? 0;
                result = EstablishViewportThen(symbol, viewportWidth, viewportHeight,
                                               s => TransformAndVisitElements(s.Transform, s.Children), symbol);
            }
            else
            {
                result = generated.Accept(this);
            }
            PopTransformsMatrix(element.Transform);
            PopMatrix();
            return(result);
        }
コード例 #3
0
        private bool BeginUseElement(SvgUseElement element, out int hashCode)
        {
            hashCode = -1;

            string useId = element.Id;

            if (string.IsNullOrWhiteSpace(useId))
            {
                hashCode = element.OuterXml.GetHashCode();
                if (_useElements.Contains(hashCode))
                {
                    return(false);
                }

                _useElements.Add(hashCode);
            }
            else
            {
                if (_useIdElements.Contains(useId))
                {
                    return(false);
                }
                _useIdElements.Add(useId);
            }

            return(true);
        }
コード例 #4
0
        private void RenderUseElement(ISvgElement svgElement)
        {
            SvgUseElement useElement = (SvgUseElement)svgElement;

            int hashCode = useElement.OuterXml.GetHashCode();

            if (!this.BeginUseElement(hashCode))
            {
                return;
            }

            SvgDocument document = useElement.OwnerDocument;

            XmlElement refEl = useElement.ReferencedElement;

            if (refEl == null)
            {
                this.EndUseElement(hashCode);
                return;
            }

            // For the external node, the documents are different, and we may not be
            // able to insert this node, so we first import it...
            if (useElement.OwnerDocument != refEl.OwnerDocument)
            {
                XmlElement importedNode = useElement.OwnerDocument.ImportNode(refEl, true) as XmlElement;

                if (importedNode != null)
                {
                    SvgElement importedSvgElement = importedNode as SvgElement;
                    if (importedSvgElement != null)
                    {
                        importedSvgElement.Imported       = true;
                        importedSvgElement.ImportNode     = refEl as SvgElement;
                        importedSvgElement.ImportDocument = refEl.OwnerDocument as SvgDocument;
                    }

                    refEl = importedNode;
                }
            }
            else
            {
                // For elements/nodes within the same document, clone it.
                refEl = (XmlElement)refEl.CloneNode(true);
            }
            // Reset any ID on the cloned/copied element to avoid duplication of IDs.
            //           refEl.SetAttribute("id", "");

            useElement.OwnerDocument.Static = true;
            useElement.CopyToReferencedElement(refEl);
            useElement.AppendChild(refEl);

            // Now, render the use element...
            this.RenderElement(svgElement);

            useElement.RemoveChild(refEl);
            useElement.RestoreReferencedElement(refEl);

            this.EndUseElement(hashCode);
        }
コード例 #5
0
        public void TestInternalReference()
        {
            SvgUseElement  elm  = Util.GetXmlElement("<use xlink:href='#foo' /><rect id='foo' width='100' height='100' />", "", "use") as SvgUseElement;
            SvgRectElement rect = elm.OwnerDocument.SelectSingleNode("//*[@id='foo']") as SvgRectElement;

            Assert.IsNotNull(elm.InstanceRoot);
            Assert.AreEqual(elm, elm.InstanceRoot.CorrespondingUseElement);
            Assert.AreEqual(rect, elm.InstanceRoot.CorrespondingElement);
        }
コード例 #6
0
        public void TestXYWidthHeight()
        {
            SvgUseElement elm = Util.GetXmlElement("<use x='1' y='2' width='3' height='4' />", "", "use") as SvgUseElement;

            Assert.AreEqual(1, elm.X.AnimVal.Value);
            Assert.AreEqual(2, elm.Y.AnimVal.Value);
            Assert.AreEqual(3, elm.Width.AnimVal.Value);
            Assert.AreEqual(4, elm.Height.AnimVal.Value);
        }
コード例 #7
0
        private bool BeginUseElement(SvgUseElement element, out int hashCode)
        {
            hashCode = -1;

            if (element.Href != null && !string.IsNullOrWhiteSpace(element.Href.AnimVal))
            {
                var hrefVal   = element.Href.AnimVal;
                int hashStart = hrefVal.IndexOf("#", StringComparison.OrdinalIgnoreCase);
                if (hashStart > -1)
                {
                    var svgRoot = element.OwnerSvgElement;
                    var elemId  = hrefVal.Substring(hashStart + 1).Trim();
                    if (!string.IsNullOrWhiteSpace(elemId) &&
                        elemId.Equals(svgRoot.Id, StringComparison.OrdinalIgnoreCase))
                    {
                        return(false);
                    }
                }
            }

            var refUri = element.UriReference.AbsoluteUri;

            if (!string.IsNullOrWhiteSpace(refUri))
            {
                var context = _renderer.Context;
                if (context != null && context.ContainsUrl(refUri))
                {
                    return(false);
                }

                context.AddUrl(refUri);
            }

            string useId = element.Id;

            if (string.IsNullOrWhiteSpace(useId))
            {
                hashCode = element.OuterXml.GetHashCode();
                if (_useElements.Contains(hashCode))
                {
                    return(false);
                }

                _useElements.Add(hashCode);
            }
            else
            {
                if (_useIdElements.Contains(useId))
                {
                    return(false);
                }
                _useIdElements.Add(useId);
            }

            return(true);
        }
コード例 #8
0
        private bool EndUseElement(SvgUseElement element, int hashCode)
        {
            bool   isRemoved = _useElements.Remove(hashCode);
            string useId     = element.Id;

            if (string.IsNullOrWhiteSpace(useId))
            {
                //int hashCode = element.OuterXml.GetHashCode();

                return(isRemoved);
            }
            return(_useIdElements.Remove(useId));
        }
コード例 #9
0
        private bool BeginUseElement(SvgUseElement element)
        {
            int hashCode = element.OuterXml.GetHashCode();

            if (_useElements.Contains(hashCode))
            {
                return(false);
            }

            _useElements.Add(hashCode);

            return(true);
        }
コード例 #10
0
        private void RenderUseElement(ISvgElement svgElement)
        {
            SvgUseElement useElement = (SvgUseElement)svgElement;

            XmlElement refEl = useElement.ReferencedElement;

            if (refEl == null)
            {
                return;
            }
            XmlElement refElParent = (XmlElement)refEl.ParentNode;

            useElement.OwnerDocument.Static = true;
            useElement.CopyToReferencedElement(refEl);
            refElParent.RemoveChild(refEl);
            useElement.AppendChild(refEl);

            this.RenderElement(svgElement);

            useElement.RemoveChild(refEl);
            useElement.RestoreReferencedElement(refEl);
            refElParent.AppendChild(refEl);
            useElement.OwnerDocument.Static = false;
        }
コード例 #11
0
        private bool EndUseElement(SvgUseElement element, int hashCode)
        {
            var refUri = element.UriReference.AbsoluteUri;

            if (!string.IsNullOrWhiteSpace(refUri))
            {
                var context = _renderer.Context;
                if (context != null && context.ContainsUrl(refUri))
                {
                    context.RemoveUrl(refUri);
                }
            }

            bool   isRemoved = _useElements.Remove(hashCode);
            string useId     = element.Id;

            if (string.IsNullOrWhiteSpace(useId))
            {
                //int hashCode = element.OuterXml.GetHashCode();

                return(isRemoved);
            }
            return(_useIdElements.Remove(useId));
        }
コード例 #12
0
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            WpfDrawingContext context = renderer.Context;

            Geometry  clipGeom  = this.ClipGeometry;
            Transform transform = this.Transform;

            if (transform == null &&
                (_svgElement.FirstChild != null && _svgElement.FirstChild == _svgElement.LastChild))
            {
                try
                {
                    SvgUseElement useElement = (SvgUseElement)_svgElement;

                    // If none of the following attribute exists, an exception is thrown...
                    double x      = useElement.X.AnimVal.Value;
                    double y      = useElement.Y.AnimVal.Value;
                    double width  = useElement.Width.AnimVal.Value;
                    double height = useElement.Height.AnimVal.Value;
                    if (width > 0 && height > 0)
                    {
                        Rect elementBounds = new Rect(x, y, width, height);

                        // Try handling the cases of "symbol" and "svg" sources within the "use"...
                        XmlNode childNode = _svgElement.FirstChild;
                        string  childName = childNode.Name;
                        if (String.Equals(childName, "symbol", StringComparison.OrdinalIgnoreCase))
                        {
                            SvgSymbolElement symbolElement = (SvgSymbolElement)childNode;

                            this.FitToViewbox(context, symbolElement, elementBounds);
                        }
                    }

                    transform = this.Transform;
                }
                catch
                {
                }
            }

            if (transform != null)
            {
                try
                {
                    SvgUseElement useElement = (SvgUseElement)_svgElement;

                    // If none of the following attribute exists, an exception is thrown...
                    double x      = useElement.X.AnimVal.Value;
                    double y      = useElement.Y.AnimVal.Value;
                    double width  = useElement.Width.AnimVal.Value;
                    double height = useElement.Height.AnimVal.Value;
                    if (width > 0 && height > 0)
                    {
                        Rect elementBounds = new Rect(x, y, width, height);

                        // Try handling the cases of "symbol" and "svg" sources within the "use"...
                        XmlNode childNode = _svgElement.FirstChild;
                        string  childName = childNode.Name;
                        if (String.Equals(childName, "symbol", StringComparison.OrdinalIgnoreCase))
                        {
                            SvgSymbolElement symbolElement = (SvgSymbolElement)childNode;

                            this.FitToViewbox(context, symbolElement, elementBounds);
                        }
                    }

                    Transform symbolTransform = this.Transform;
                    if (symbolTransform != null && !symbolTransform.Value.IsIdentity)
                    {
                        TransformGroup combinedTransform = new TransformGroup();

                        combinedTransform.Children.Add(transform);
                        combinedTransform.Children.Add(symbolTransform);

                        transform = combinedTransform;
                    }
                }
                catch
                {
                }
            }

            if (clipGeom != null || transform != null)
            {
                _drawGroup = new DrawingGroup();

                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);

                if (clipGeom != null)
                {
                    _drawGroup.ClipGeometry = clipGeom;
                }

                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }
            }
        }
コード例 #13
0
        private GeometryCollection CreateClippingRegion(SvgClipPathElement clipPath,
                                                        WpfDrawingContext context)
        {
            GeometryCollection geomColl = new GeometryCollection();

            foreach (XmlNode node in clipPath.ChildNodes)
            {
                if (node.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                // Handle a case where the clip element has "use" element as a child...
                if (string.Equals(node.LocalName, "use"))
                {
                    SvgUseElement useElement = (SvgUseElement)node;

                    XmlElement refEl = useElement.ReferencedElement;
                    if (refEl != null)
                    {
                        XmlElement refElParent = (XmlElement)refEl.ParentNode;
                        useElement.OwnerDocument.Static = true;
                        useElement.CopyToReferencedElement(refEl);
                        refElParent.RemoveChild(refEl);
                        useElement.AppendChild(refEl);

                        foreach (XmlNode useChild in useElement.ChildNodes)
                        {
                            if (useChild.NodeType != XmlNodeType.Element)
                            {
                                continue;
                            }

                            SvgStyleableElement element = useChild as SvgStyleableElement;
                            if (element != null && element.RenderingHint == SvgRenderingHint.Shape)
                            {
                                Geometry childPath = CreateGeometry(element, context.OptimizePath);

                                if (childPath != null)
                                {
                                    geomColl.Add(childPath);
                                }
                            }
                        }

                        useElement.RemoveChild(refEl);
                        useElement.RestoreReferencedElement(refEl);
                        refElParent.AppendChild(refEl);
                        useElement.OwnerDocument.Static = false;
                    }
                }
                else
                {
                    SvgStyleableElement element = node as SvgStyleableElement;
                    if (element != null)
                    {
                        if (element.RenderingHint == SvgRenderingHint.Shape)
                        {
                            Geometry childPath = CreateGeometry(element, context.OptimizePath);

                            if (childPath != null)
                            {
                                geomColl.Add(childPath);
                            }
                        }
                        else if (element.RenderingHint == SvgRenderingHint.Text)
                        {
                            GeometryCollection textGeomColl = GetTextClippingRegion(element, context);
                            if (textGeomColl != null)
                            {
                                for (int i = 0; i < textGeomColl.Count; i++)
                                {
                                    geomColl.Add(textGeomColl[i]);
                                }
                            }
                        }
                    }
                }
            }

            return(geomColl);
        }
コード例 #14
0
        private void RenderUseElement(ISvgElement svgElement)
        {
            SvgUseElement useElement = (SvgUseElement)svgElement;

            int hashCode = 0; // useElement.OuterXml.GetHashCode();

            if (!this.BeginUseElement(useElement, out hashCode))
            {
                return;
            }

            SvgDocument document = useElement.OwnerDocument;

            XmlElement refEl = useElement.ReferencedElement;

            if (refEl == null)
            {
                this.EndUseElement(useElement, hashCode);
                return;
            }
            XmlElement refElParent = refEl.ParentNode as XmlElement;
            var        siblingNode = refEl.PreviousSibling;

            if (siblingNode != null && siblingNode.NodeType == XmlNodeType.Whitespace)
            {
                siblingNode = siblingNode.PreviousSibling;
            }

            // For the external node, the documents are different, and we may not be
            // able to insert this node, so we first import it...
            if (useElement.OwnerDocument != refEl.OwnerDocument)
            {
                var importedNode = useElement.OwnerDocument.ImportNode(refEl, true) as XmlElement;

                if (importedNode != null)
                {
                    var importedSvgElement = importedNode as SvgElement;
                    if (importedSvgElement != null)
                    {
                        importedSvgElement.Imported       = true;
                        importedSvgElement.ImportNode     = refEl as SvgElement;
                        importedSvgElement.ImportDocument = refEl.OwnerDocument as SvgDocument;
                    }

                    refEl = importedNode;
                }
            }
            else
            {
                // For elements/nodes within the same document, clone it.
                refEl = (XmlElement)refEl.CloneNode(true);
            }
            // Reset any ID on the cloned/copied element to avoid duplication of IDs.
            //           refEl.SetAttribute("id", "");

            useElement.OwnerDocument.Static = true;
            useElement.CopyToReferencedElement(refEl);

            XmlElement refSiblingEl = null;
            string     useId        = null;

            // Compensate for the parent's class and sibling css loss from cloning...
            if (refElParent != null && refElParent.HasAttribute("class"))
            {
                var parentClass = refElParent.GetAttribute("class");
                if (!string.IsNullOrWhiteSpace(parentClass))
                {
                    var parentEl = document.CreateElement(refElParent.LocalName);
                    parentEl.SetAttribute("class", parentClass);

                    parentEl.AppendChild(refEl);

                    refEl = parentEl;
                }
            }
            else if (refElParent != null && siblingNode != null)
            {
                var siblingEl = siblingNode as XmlElement;
                if (siblingEl != null && siblingEl.HasAttribute("class"))
                {
                    var siblingClass = siblingEl.GetAttribute("class");
                    if (!string.IsNullOrWhiteSpace(siblingClass))
                    {
                        refSiblingEl = (XmlElement)siblingEl.CloneNode(true);

                        useElement.AppendChild(refSiblingEl);
                    }
                }
            }
            else
            {
                //useId = useElement.Id;
                //useElement.SetAttribute("id", "");
            }

            useElement.AppendChild(refEl);

            // Now, render the use element...
            this.RenderElement(svgElement);

            if (refSiblingEl != null)
            {
                useElement.RemoveChild(refSiblingEl);
            }
            useElement.RemoveChild(refEl);
            useElement.RestoreReferencedElement(refEl);

            if (useId != null)
            {
                useElement.SetAttribute("id", useId);
            }

            this.EndUseElement(useElement, hashCode);
        }
コード例 #15
0
 public virtual void VisitUseElement(SvgUseElement element)
 => DefaultVisit(element);
コード例 #16
0
 public override SvgElement VisitUseElement(SvgUseElement element)
 {
     return(base.VisitUseElement(element));
 }
コード例 #17
0
        private SvgRectF GetElementBounds(SvgTransformableElement element, float margin)
        {
            SvgRenderingHint hint = element.RenderingHint;

            if (hint == SvgRenderingHint.Shape || hint == SvgRenderingHint.Text)
            {
                GraphicsPath gp        = GdiRendering.CreatePath(element);
                ISvgMatrix   svgMatrix = element.GetScreenCTM();

                Matrix matrix = new Matrix((float)svgMatrix.A, (float)svgMatrix.B, (float)svgMatrix.C,
                                           (float)svgMatrix.D, (float)svgMatrix.E, (float)svgMatrix.F);
                SvgRectF bounds = SvgConverter.ToRect(gp.GetBounds(matrix));
                bounds = SvgRectF.Inflate(bounds, margin, margin);

                return(bounds);
            }

            SvgUseElement useElement = element as SvgUseElement;

            if (useElement != null)
            {
                SvgTransformableElement refEl = useElement.ReferencedElement as SvgTransformableElement;
                if (refEl == null)
                {
                    return(SvgRectF.Empty);
                }

                XmlElement refElParent = (XmlElement)refEl.ParentNode;
                element.OwnerDocument.Static = true;
                useElement.CopyToReferencedElement(refEl);
                element.AppendChild(refEl);

                SvgRectF bbox = this.GetElementBounds(refEl, margin);

                element.RemoveChild(refEl);
                useElement.RestoreReferencedElement(refEl);
                refElParent.AppendChild(refEl);
                element.OwnerDocument.Static = false;

                return(bbox);
            }

            SvgRectF union = SvgRectF.Empty;
            SvgTransformableElement transformChild;

            foreach (XmlNode childNode in element.ChildNodes)
            {
                if (childNode is SvgDefsElement)
                {
                    continue;
                }
                if (childNode is ISvgTransformable)
                {
                    transformChild = (SvgTransformableElement)childNode;
                    SvgRectF bbox = this.GetElementBounds(transformChild, margin);
                    if (bbox != SvgRectF.Empty)
                    {
                        if (union == SvgRectF.Empty)
                        {
                            union = bbox;
                        }
                        else
                        {
                            union = SvgRectF.Union(union, bbox);
                        }
                    }
                }
            }

            return(union);
        }
コード例 #18
0
        private GraphicsPath CreateClippingRegion(GdiGraphics graphics, SvgClipPathElement clipPath)
        {
            GraphicsPath path = new GraphicsPath();

            foreach (XmlNode node in clipPath.ChildNodes)
            {
                if (node.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                // Handle a case where the clip element has "use" element as a child...
                if (string.Equals(node.LocalName, "use"))
                {
                    SvgUseElement useElement = (SvgUseElement)node;

                    XmlElement refEl = useElement.ReferencedElement;
                    if (refEl != null)
                    {
                        XmlElement refElParent = (XmlElement)refEl.ParentNode;
                        useElement.OwnerDocument.Static = true;
                        useElement.CopyToReferencedElement(refEl);
                        refElParent.RemoveChild(refEl);
                        useElement.AppendChild(refEl);

                        foreach (XmlNode useChild in useElement.ChildNodes)
                        {
                            if (useChild.NodeType != XmlNodeType.Element)
                            {
                                continue;
                            }

                            SvgStyleableElement element = useChild as SvgStyleableElement;
                            if (element != null && element.RenderingHint == SvgRenderingHint.Shape)
                            {
                                GraphicsPath childPath = CreatePath(element);

                                if (childPath != null)
                                {
                                    string clipRule = element.GetPropertyValue("clip-rule");
                                    path.FillMode = (clipRule == "evenodd") ? FillMode.Alternate : FillMode.Winding;

                                    path.AddPath(childPath, true);
                                }
                            }
                        }

                        useElement.RemoveChild(refEl);
                        useElement.RestoreReferencedElement(refEl);
                        refElParent.AppendChild(refEl);
                        useElement.OwnerDocument.Static = false;
                    }
                }
                else
                {
                    SvgStyleableElement element = node as SvgStyleableElement;
                    if (element != null)
                    {
                        if (element.RenderingHint == SvgRenderingHint.Shape)
                        {
                            GraphicsPath childPath = CreatePath(element);

                            if (childPath != null)
                            {
                                string clipRule = element.GetPropertyValue("clip-rule");
                                path.FillMode = (clipRule == "evenodd") ? FillMode.Alternate : FillMode.Winding;

                                path.AddPath(childPath, true);
                            }
                        }
                        else if (element.RenderingHint == SvgRenderingHint.Text)
                        {
                            GdiTextRendering textRendering = new GdiTextRendering(element);
                            textRendering.TextMode = GdiTextMode.Outlining;

                            GdiGraphicsRenderer renderer = new GdiGraphicsRenderer(graphics);

                            textRendering.BeforeRender(renderer);
                            textRendering.Render(renderer);
                            textRendering.AfterRender(renderer);

                            GraphicsPath childPath = textRendering.Path;
                            if (childPath != null)
                            {
                                string clipRule = element.GetPropertyValue("clip-rule");
                                path.FillMode = (clipRule == "evenodd") ? FillMode.Alternate : FillMode.Winding;

                                path.AddPath(childPath, true);
                            }
                        }
                    }
                }
            }

            return(path);
        }
コード例 #19
0
        private bool EndUseElement(SvgUseElement element)
        {
            int hashCode = element.OuterXml.GetHashCode();

            return(_useElements.Remove(hashCode));
        }
コード例 #20
0
ファイル: LinkVisitor.cs プロジェクト: naver/protonow
        private void AggregateChildren(SvgAElement aElement, WpfDrawingContext context, float opacity)
        {
            _isAggregated = false;

            if (aElement == null || aElement.ChildNodes == null)
            {
                return;
            }

            string aggregatedFill = aElement.GetAttribute("fill");
            bool   isFillFound    = !String.IsNullOrEmpty(aggregatedFill);

            SvgStyleableElement paintElement = null;

            if (isFillFound)
            {
                paintElement = aElement;
            }

            XmlNode targetNode = aElement;

            // Check if the children of the link are wrapped in a Group Element...
            if (aElement.ChildNodes.Count == 1)
            {
                SvgGElement groupElement = aElement.ChildNodes[0] as SvgGElement;
                if (groupElement != null)
                {
                    targetNode = groupElement;
                }
            }

            WpfDrawingSettings settings = context.Settings;

            GeometryCollection geomColl = new GeometryCollection();

            foreach (XmlNode node in targetNode.ChildNodes)
            {
                if (node.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                // Handle a case where the clip element has "use" element as a child...
                if (String.Equals(node.LocalName, "use"))
                {
                    SvgUseElement useElement = (SvgUseElement)node;

                    XmlElement refEl = useElement.ReferencedElement;
                    if (refEl != null)
                    {
                        XmlElement refElParent = (XmlElement)refEl.ParentNode;
                        useElement.OwnerDocument.Static = true;
                        useElement.CopyToReferencedElement(refEl);
                        refElParent.RemoveChild(refEl);
                        useElement.AppendChild(refEl);

                        foreach (XmlNode useChild in useElement.ChildNodes)
                        {
                            if (useChild.NodeType != XmlNodeType.Element)
                            {
                                continue;
                            }

                            SvgStyleableElement element = useChild as SvgStyleableElement;
                            if (element != null && element.RenderingHint == SvgRenderingHint.Shape)
                            {
                                Geometry childPath = WpfRendering.CreateGeometry(element,
                                                                                 settings.OptimizePath);

                                if (childPath != null)
                                {
                                    if (isFillFound)
                                    {
                                        string elementFill = element.GetAttribute("fill");
                                        if (!String.IsNullOrEmpty(elementFill) &&
                                            !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase))
                                        {
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        aggregatedFill = element.GetAttribute("fill");
                                        isFillFound    = !String.IsNullOrEmpty(aggregatedFill);
                                        if (isFillFound)
                                        {
                                            paintElement = element;
                                        }
                                    }

                                    geomColl.Add(childPath);
                                }
                            }
                        }

                        useElement.RemoveChild(refEl);
                        useElement.RestoreReferencedElement(refEl);
                        refElParent.AppendChild(refEl);
                        useElement.OwnerDocument.Static = false;
                    }
                }
                //else if (String.Equals(node.LocalName, "g"))
                //{
                //}
                else
                {
                    SvgStyleableElement element = node as SvgStyleableElement;
                    if (element != null && element.RenderingHint == SvgRenderingHint.Shape)
                    {
                        Geometry childPath = WpfRendering.CreateGeometry(element,
                                                                         settings.OptimizePath);

                        if (childPath != null)
                        {
                            if (isFillFound)
                            {
                                string elementFill = element.GetAttribute("fill");
                                if (!String.IsNullOrEmpty(elementFill) &&
                                    !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase))
                                {
                                    return;
                                }
                            }
                            else
                            {
                                aggregatedFill = element.GetAttribute("fill");
                                isFillFound    = !String.IsNullOrEmpty(aggregatedFill);
                                if (isFillFound)
                                {
                                    paintElement = element;
                                }
                            }

                            geomColl.Add(childPath);
                        }
                    }
                }
            }

            if (geomColl.Count == 0 || paintElement == null)
            {
                return;
            }

            _aggregatedFill = paintElement;
            _aggregatedGeom = geomColl;

            _isAggregated = true;
        }
コード例 #21
0
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            WpfDrawingContext context = renderer.Context;

            Geometry  clipGeom  = this.ClipGeometry;
            Transform transform = this.Transform;

            SvgUseElement useElement = (SvgUseElement)_svgElement;

            string elementId = this.GetElementName();

            float opacityValue = -1;

            string opacity = useElement.GetAttribute("opacity");

            if (string.IsNullOrWhiteSpace(opacity))
            {
                opacity = useElement.GetPropertyValue("opacity");
            }
            if (!string.IsNullOrWhiteSpace(opacity))
            {
                opacityValue = (float)SvgNumber.ParseNumber(opacity);
                opacityValue = Math.Min(opacityValue, 1);
                opacityValue = Math.Max(opacityValue, 0);
            }

            _drawGroup = new DrawingGroup();

            DrawingGroup currentGroup = context.Peek();

            if (currentGroup == null)
            {
                throw new InvalidOperationException("An existing group is expected.");
            }

            currentGroup.Children.Add(_drawGroup);
            context.Push(_drawGroup);

            if (clipGeom != null || transform != null || (opacityValue >= 0 && opacityValue < 1) ||
                (!string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId)))
            {
                if (clipGeom != null)
                {
                    _drawGroup.ClipGeometry = clipGeom;
                }

                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }

                if (opacityValue >= 0 && opacityValue < 1)
                {
                    _drawGroup.Opacity = opacityValue;
                }

                if (!string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId))
                {
                    SvgObject.SetName(_drawGroup, elementId);

                    context.RegisterId(elementId);

                    if (context.IncludeRuntime)
                    {
                        SvgObject.SetId(_drawGroup, elementId);
                    }
                }
            }
        }