public static void AddEllipse(XElement svgElement, Group avGroup, List <string> warnings) { if (ConvertEllipseElementToPathData(svgElement, warnings) is string pathData) { var clipGroup = ClipConverter.ConvertClipPathAttribute(svgElement, avGroup, warnings); var avPath = new Path(); var ignoreAttributes = new List <string> { "cx", "cy", "rx", "ry" }; CommonAttributes.ProcessAttributes(svgElement, avPath, ignoreAttributes, warnings); avPath.SetAndroidAttributeValue("pathData", pathData); if (clipGroup != avGroup) { CommonAttributes.SetTransforms(svgElement, clipGroup, warnings); clipGroup.Add(avPath); } else { CommonAttributes.SetTransforms(svgElement, avPath, warnings); avGroup.Add(avPath); } } }
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); }
static void SetCommonGradientAttributes(XElement svgGradient, XElement hrefElement, BaseGradient avGradient, List <string> warnings) { var typeName = svgGradient.Name; if (GetAttribute("gradientUnits", svgGradient, hrefElement) is XAttribute unitsAttribute) { avGradient.UserSpaceUnits = unitsAttribute.Value == "userSpaceOnUse"; } if (GetAttribute("gradientTransform", svgGradient, hrefElement) is XAttribute transformAttribute) { CommonAttributes.SetTransforms(svgGradient, avGradient, warnings); } if (GetAttribute("spreadMethod", svgGradient, hrefElement) is XAttribute spreadMethodAttribute) { switch (spreadMethodAttribute.Value) { case "pad": avGradient.SetAndroidAttributeValue("tileMode", "clamp"); break; case "reflect": avGradient.SetAndroidAttributeValue("tileMode", "mirror"); break; case "repeat": avGradient.SetAndroidAttributeValue("tileMode", "repeat"); break; default: warnings.AddWarning("Ignoring 'spreadMethod' attribute in SVG " + typeName + " because value '" + spreadMethodAttribute.Value + "' is not supported."); break; } } var stops = hrefElement?.Elements(Namespace.Svg + "stop").ToList() ?? new List <XElement>(); stops.AddRange(svgGradient.Elements(Namespace.Svg + "stop")); foreach (var stop in stops) { var color = Color.Black; var styles = new Dictionary <string, string>(); if (stop.Attribute("style") is XAttribute styleAttribute) { var parts = styleAttribute.Value.Split(';'); foreach (var style in parts) { var styleParts = style.Split(':'); if (styleParts.Length > 1) { styles.Add(styleParts[0], styleParts[1]); } } } if (stop.Attribute("stop-color") is XAttribute colorAttribute) { color = colorAttribute.Value.ToColor(); } else if (styles.TryGetValue("stop-color", out string colorText)) { color = colorText.ToColor(); } string opacityText = null; if (stop.Attribute("stop-opacity") is XAttribute opacityAttribute) { opacityText = opacityAttribute.Value; } else if (styles.ContainsKey("stop-opacity")) { //styles.TryGetValue("stop-opacity", out opacityText); opacityText = styles["stop-opacity"]; } if (!string.IsNullOrWhiteSpace(opacityText)) { bool percent = false; if (opacityText.EndsWith("%")) { percent = true; opacityText.Trim('%'); } if (float.TryParse(opacityText, out float value)) { if (percent) { value /= 100f; } int alpha = (int)Math.Round(255 * value); color = Color.FromArgb(alpha, color.R, color.G, color.B); } else { warnings.AddWarning("Ignoring opacity because could not parse stop-opaticy in " + stop + "."); } } string offsetText = "0"; if (stop.Attribute("offset") is XAttribute offsetAttribute) { offsetText = offsetAttribute.Value; } else if (styles.ContainsKey("offset")) { offsetText = styles["offset"]; } avGradient.Add(new GradientItem(offsetText, color.ToHexString())); } }