Example #1
0
    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);
    }