コード例 #1
0
ファイル: Converter.cs プロジェクト: hefujie1988/AssetBuilder
        public static AndroidVector.Vector ConvertSvg(XDocument svgDocument, List <string> warnings)
        {
            var svgElement = svgDocument.Root;

            if (svgDocument.Root.Name != Namespace.Svg + "svg")
            {
                throw new ArgumentException("document must have <svg> root");
            }

            var vector = new AndroidVector.Vector();

            AndroidVector.Group avGroup = vector;
            float width = 0, height = 0;

            if (svgElement.Attribute("width") is XAttribute widthAttribute && AttributeExtensions.TryGetValueInPx(widthAttribute, out width))
            {
                vector.Width = new AndroidVector.UnitizedFloat(width, AndroidVector.Unit.Px);
            }
コード例 #2
0
        public static AndroidVector.Group AddClipPathElement(this XElement svgElement, AndroidVector.Group avGroup, List <string> warnings)
        {
            string typeName = svgElement.Name.LocalName;

            avGroup = ClipConverter.ConvertClipPathAttribute(svgElement, avGroup, warnings);
            CommonAttributes.ProcessAttributes(svgElement, avGroup, null, warnings);
            var avClip = new AndroidVector.ClipPath();

            foreach (var child in svgElement.Elements())
            {
                if (child.Name == Namespace.Svg + "use")
                {
                    float tx = 0, ty = 0;
                    if (child.Attribute("x") is XAttribute xAttribute)
                    {
                        AttributeExtensions.TryGetValueInPx(xAttribute, out tx);
                    }
                    if (child.Attribute("y") is XAttribute yAttribute)
                    {
                        AttributeExtensions.TryGetValueInPx(yAttribute, out ty);
                    }
                    if (tx != 0 || ty != 0)
                    {
                        avGroup.SvgTransforms.Add(Matrix.CreateTranslate(tx, ty));
                    }

                    if (child.Attribute(Namespace.xlinkNs + "href") is XAttribute hrefAttribute)
                    {
                        if (hrefAttribute.Value.StartsWith("#"))
                        {
                            var href = hrefAttribute.Value.Trim(new char[] { '#', ' ' });
                            var root = child.GetRoot();
                            if (root.Descendants().Where(e => e.Attribute("id")?.Value == href).FirstOrDefault() is XElement useElement)
                            {
                                if (useElement.Name == Namespace.Svg + "clipPath")
                                {
                                    avGroup = ClipConverter.ConvertClipPathAttribute(useElement, avGroup, warnings);
                                    CommonAttributes.ProcessAttributes(useElement, avGroup, new List <string> {
                                        "x", "y"
                                    }, warnings);
                                    AddClipPathElement(useElement, avGroup, warnings);
                                }
                                else if (GeometryConverter.ConvertElementToPathData(useElement, warnings) is string pathData)
                                {
                                    avClip.PathData += pathData;
                                    warnings.AddWarning("A union of two (or more) clippaths has been found.  If these clippaths overlap, you're likely not going to like the result.  Suggestion:  Use a vector image editor (like InkScape) to alter your union of clippaths to be one path, without crossing segments.");
                                }
                                else
                                {
                                    warnings.AddWarning("Ignoring <" + useElement.Name.LocalName + " id='" + useElement.Attribute("id")?.Value + "'> inside of <" + child.Name.LocalName + " id='" + child.Attribute("id")?.Value + "' xlink:href='" + hrefAttribute.Value + "' because could not find element referenced by xlink:href attribute.");
                                }
                            }
                            else
                            {
                                warnings.AddWarning("Ignoring <use id='" + svgElement.Attribute("id")?.Value + "' xlink:href='" + hrefAttribute.Value + "' because could not find element referenced by xlink:href attribute.");
                            }
                        }
                        else
                        {
                            warnings.AddWarning("Ignoring <use id='" + svgElement.Attribute("id")?.Value + "' xlink:href='" + hrefAttribute.Value + "' because xlink:href attribute is not a local anchor.");
                        }
                    }
                    else
                    {
                        warnings.AddWarning("Ignoring <use id='" + svgElement.Attribute("id")?.Value + "'> because cannot find xlink:href attribute.");
                    }
                    //    var tmpGroup = new AndroidVector.Group();
                }
                else if (GeometryConverter.ConvertElementToPathData(child, warnings) is string pathData)
                {
                    avClip.PathData += pathData;
                }
            }

            if (!string.IsNullOrWhiteSpace(avClip.PathData))
            {
                CommonAttributes.SetTransforms(svgElement, avClip, warnings);
                avGroup.Add(avClip);
            }

            return(avGroup);
        }
コード例 #3
0
        //TODO: Process clip paths after all of the SVG has been converted (just like gradients)
        public static AndroidVector.Group ConvertClipPathAttribute(this XElement svgElement, AndroidVector.Group avGroup, List <string> warnings)
        {
            if (svgElement.Attribute("clip-path") is XAttribute svgAttribute)
            {
                var svgAttributeValue = svgAttribute.Value.Trim();
                if (svgAttributeValue == "inherit")
                {
                    var parent = svgAttribute.Parent.Parent;
                    while (parent != null)
                    {
                        if (parent.Attribute(svgAttribute.Name) is XAttribute parentAttribute && parentAttribute.Value.Trim() != "inherit")
                        {
                            svgAttributeValue = parentAttribute.Value.Trim();
                            return(avGroup);
                        }
                    }
                }

                if (svgElement.Name != Namespace.Svg + "g" || svgElement.Name != Namespace.Svg + "clipPath")
                {
                    avGroup = Converter.NestGroup(avGroup);
                }

                if (svgAttributeValue.StartsWith("url("))
                {
                    if (!svgAttributeValue.StartsWith("url(#"))
                    {
                        throw new Exception("Only anchor URLs are supported at this time.");
                    }

                    var iri = svgAttributeValue.Substring("url(#".Length).Trim(')').Trim();
                    if (svgElement.GetRoot() is XElement root)
                    {
                        if (root.Descendants(Namespace.Svg + "clipPath").FirstOrDefault(e => e.Attribute("id").Value == iri) is XElement svgClipPathElement)
                        {
                            //AndroidVector.Group result = avGroup is AndroidVector.Group ? avGroup : new AndroidVector.Group();
                            avGroup = AddClipPathElement(svgClipPathElement, avGroup, warnings);
                            return(avGroup);
                        }
                        warnings.AddWarning("Ignoring clip-path because no element found to complete clipPath link to " + svgAttributeValue + ".");
                        return(avGroup);
                    }
                    throw new Exception("could not find document root");
                }
                else if (GeometryConverter.ConvertCssShapeToPathData(svgElement, svgAttributeValue, warnings) is string pathData)
                {
                    avGroup.Add(new ClipPath(pathData));
                }
                else
                {
                    warnings.AddWarning("Ignoring clip-path attribute because could not interpret value : " + svgAttributeValue + ".");
                }
            }
            return(avGroup);
        }