public static void ProcessHoles(RageSvgObject pathData) { if (pathData.Paths.Count < 2) { return; } int j = 0; while (j < pathData.Paths.Count - 1) { var mainSpline = pathData.Paths[j].Spline; var subPaths = new Dictionary <int, ISpline>(); for (int i = j + 1; i < pathData.Paths.Count; i++) { var subSpline = pathData.Paths[i].Spline; if (mainSpline == subSpline) { continue; } subPaths.Add(i, subSpline); } var toRemove = ProcessHoles(mainSpline, subPaths); for (int i = toRemove.Count - 1; i >= 0; i--) { //pathData.Paths[toRemove[i]].Spline.GameObject.name = i + "_Hole_" + toRemove[i]; pathData.Paths[toRemove[i]].Spline.GameObject.SmartDestroy(); pathData.Paths.RemoveAt(toRemove[i]); } j++; } }
private bool ParseSvgStyle(string svgCommand, string svgValue, ref RageSvgObject pathData) { switch (svgCommand) { // TODO: Add style id to the class and store it //case ("id"): // current.gO.name = svgValue; // return true; case ("opacity"): case ("stroke-miterlimit"): case ("stroke-linejoin"): case ("stroke"): case ("stroke-opacity"): case ("stroke-width"): case ("stroke-linecap"): case ("fill"): case ("fill-opacity"): pathData.StyleString += svgCommand + ":" + svgValue + ";"; return(true); // style="fill:none;stroke:#FF0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" case ("style"): if (pathData.StyleString != "") { if (pathData.StyleString[pathData.StyleString.Length - 1] != ';') { pathData.StyleString += ";"; } } pathData.StyleString += svgValue; return(true); } return(false); }
private void ParseStyle(ref RageSvgObject pathData) { if (DebugStyleCreation) { Debug.Log("svgStyle String: " + pathData.StyleString); } ParseRageStyle(ref pathData); pathData.StyleString = ""; }
private void ApplyStyle(RageSvgObject pathData) { //Debug.Log ("path count: "+pathData.PathIdx+1); //ApplyRageStyle(pathData.CurrentPath, pathData.Style); foreach (RageSvgPathElement path in pathData.Paths) { //Debug.Log ("Apply style to: "+ (path == null ? "null" : path.gO.name)); ApplyRageStyle(path, pathData.Style); } }
private void ApplyGradientTransform(string gradientTransformString, RageSvgObject pathData) { if (gradientTransformString == "") { pathData.Gradient.Y1 *= -1; pathData.Gradient.Y2 *= -1; return; } /*Debug.Log(currentGradient.Id + "\nG1 orig pos: " + currentGradient.X1 + " " + currentGradient.Y1);*/ var gradientStop = new Vector2(pathData.Gradient.X1, pathData.Gradient.Y1); gradientStop = ApplyTransform(gradientStop, gradientTransformString); pathData.Gradient.SetStartPos(gradientStop); /*Debug.Log("G1 final pos: " + currentGradient.X1 + " " + currentGradient.Y1);*/ gradientStop = new Vector2(pathData.Gradient.X2, pathData.Gradient.Y2); gradientStop = ApplyTransform(gradientStop, gradientTransformString); pathData.Gradient.SetEndPos(gradientStop); }
private void ParseGradientStop(XmlNode svgEntry, RageSvgObject pathData) { var offset = ""; var stopColor = ""; var stopOpacity = ""; XmlAttributeCollection attributes = svgEntry.Attributes; if (attributes != null) { foreach (XmlAttribute svgAttribute in attributes) { string svgCommand = svgAttribute.Name; string svgValue = svgAttribute.Value; if (DebugStyleCreation) { Debug.Log("Gradient Stop: " + svgCommand + " " + svgValue); } switch (svgCommand) { //<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:1"/> case ("offset"): offset = svgValue; break; case ("stop-color"): stopColor = svgValue.Substring(1); break; case ("stop-opacity"): stopOpacity = svgValue; break; case ("style"): var gradientStyleString = svgValue; foreach (var style in GetSvgStyleCommands(gradientStyleString)) { switch (style.Command) { case ("stop-color"): stopColor = style.Value.Substring(1); break; case ("stop-opacity"): stopOpacity = style.Value; break; } } break; } } } var thisColor = stopColor.ToColor(); if (stopOpacity != "") { thisColor.a = float.Parse(stopOpacity); } //SVG gradient stops are defined in reverse order. // TODO: Reduce the gradient radius according to the valid offsets 'delta' if (float.Parse(offset) < 0.5f) { pathData.Gradient.EndColor = thisColor; } else { pathData.Gradient.StartColor = thisColor; } }
/// <summary> Parses the style string to the 'currentStyle' object that SVG-In uses </summary> /// <param name="styleString"> </param> /// <param name="style"> </param> /// <param name="current"> </param> private void ParseRageStyle(ref RageSvgObject pathData) //string styleString, ref RageSvgStyle style) { { var style = pathData.Style; var styleString = pathData.StyleString; // Parse object example: // "fill:none;stroke:#FF0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" if (string.IsNullOrEmpty(styleString)) { return; } foreach (var styleEntry in GetSvgStyleCommands(styleString)) { switch (styleEntry.Command) { case ("stroke-miterlimit"): if (styleEntry.Value != "0") { style.CornersType = Spline.CornerType.Beak; } break; case ("stroke-linejoin"): style.CornersType = styleEntry.Value == "miter" ? Spline.CornerType.Beak : Spline.CornerType.Default; break; case ("stroke-linecap"): // if (style.Value == "round") currentStyle.Corners = RageSpline.Corner.Default; break; case ("opacity"): style.FillColor1Alpha = styleEntry.Value.SvgToFloat(); style.OutlineAlpha = styleEntry.Value.SvgToFloat(); break; case "fill": if (styleEntry.Value == "none" || styleEntry.Value == "transparent") { style.HasFill = false; break; } style.HasFill = true; // default for all color parameter types if (styleEntry.Value[0] == '#') { style.FillColor1 = styleEntry.Value.Substring(1).ToColor(); break; } if (styleEntry.Value.StartsWith("url")) // eg.: url(#SVGID_1_) { var length = styleEntry.Value.Length - 6; //-5 + (-1) var gradientId = styleEntry.Value.Substring(5, length); // Debug.Log("gradient Id to Search: " + gradientId); RageSvgGradient gradient; if (_gradients.TryGetValue(gradientId, out gradient)) // Note: For dictionaries, TryGetValue is much faster than GetKey { style.HasGradient = true; // style.FillType = Spline.FillType.Gradient; style.RageSvgGradient = gradient; } break; } style.FillColor1 = styleEntry.Value.KeywordToHex().ToColor(); // Tries parsing a named color break; case "stroke": if (styleEntry.Value == "none" || styleEntry.Value == "transparent") { style.HasOutline = false; // current.Style.OutlineType = Spline.OutlineType.None; break; } style.OutlineColor1 = styleEntry.Value[0] == '#' ? styleEntry.Value.Substring(1).ToColor() : styleEntry.Value.KeywordToHex().ToColor(); style.HasOutline = true; break; case "stroke-width": // if there's a measurement unit, remove the trailing alphabetic characters (eg.: px, en) var width = styleEntry.Value.TrimTrailingAlphas(); style.OutlineWidth = width.SvgToFloat(); if (DebugMeshCreation) { Debug.Log("stroke width ===> " + width); } break; case "stroke-opacity": style.OutlineAlpha = styleEntry.Value.SvgToFloat(); // current.Style.HasOutline = !Mathfx.Approximately(current.Style.OutlineWidth,0f); break; case "fill-opacity": style.FillColor1Alpha = styleEntry.Value.SvgToFloat(); break; } } if (DebugStyleCreation) { Debug.Log("### After Parse Style ###" + "\n>>> Current Fill: " + style.FillType + " :: Color: " + style.FillColor1 + " :: Has Fill? " + style.HasFill); } }
private void ParseGradient(XmlNode svgEntry, RageSvgObject pathData, RageSvgGradient.GradientType gradientType, bool subPath, int level) { // Initializes a new Gradient pathData.Gradient = RageSvgGradient.NewInstance(); pathData.Gradient.Type = gradientType; float radius = 0f; var gradientTransformString = ""; XmlAttributeCollection attributes = svgEntry.Attributes; if (attributes != null) { foreach (XmlAttribute svgAttribute in attributes) { string svgCommand = svgAttribute.Name; string svgValue = svgAttribute.Value; // Parse valid Svg style commands, if any found, iterate // if (ParseSvgStyle(svgCommand, svgValue)) continue; switch (svgCommand) { //<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="170.0791" y1="85.0396" x2="170.0791" y2="28.3472"> case ("id"): pathData.Gradient.Id = svgValue; break; case ("xlink:href"): ParseGradientLink(ref pathData.Gradient, svgValue.Substring(1)); break; case ("x1"): pathData.Gradient.X1 = svgValue.SvgToFloat(); break; case ("y1"): pathData.Gradient.Y1 = svgValue.SvgToFloat(); break; case ("x2"): pathData.Gradient.X2 = svgValue.SvgToFloat(); break; case ("y2"): pathData.Gradient.Y2 = svgValue.SvgToFloat(); break; case ("cx"): pathData.Gradient.X2 = svgValue.SvgToFloat(); break; case ("cy"): pathData.Gradient.Y2 = svgValue.SvgToFloat(); break; case ("fx"): pathData.Gradient.X1 = svgValue.SvgToFloat(); break; case ("fy"): pathData.Gradient.Y1 = svgValue.SvgToFloat(); break; case ("r"): radius = svgValue.SvgToFloat(); break; case ("gradientTransform"): gradientTransformString = svgValue; break; } } } if (!(Mathfx.Approximately(radius, 0f))) { pathData.Gradient.X2 = pathData.Gradient.X1 + radius; pathData.Gradient.Y2 = pathData.Gradient.Y2 + radius; } if (DebugStyleCreation) { Debug.Log("######### Gradient children Count: " + svgEntry.ChildNodes.Count); } if (svgEntry.ChildNodes.Count != 0) { level++; foreach (XmlNode childNode in svgEntry.ChildNodes) { ParseSvg(childNode, pathData, subPath, level); } } ApplyGradientTransform(gradientTransformString, pathData); if (_gradients.ContainsKey(pathData.Gradient.Id)) { return; } if (DebugStyleCreation) { Debug.Log("Gradient entry added: " + pathData.Gradient.Id); } // After all "stop" child nodes are parsed, actually add the new dictionary item _gradients.Add(pathData.Gradient.Id, pathData.Gradient); }