public static List<List<Vector2>> CreateStroke(List<Vector2> inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
 {
     if(inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
         return null;
     
     return CreateStroke(new List<List<Vector2>>(){inputShapes}, paintable, closePath);
 }
Example #2
0
 public static Mesh CreateStrokeSimple(SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
 {
     return(CreateStrokeSimple(new List <List <Vector2> >()
     {
         new List <Vector2>(SVGGraphics.position_buffer.ToArray())
     }, paintable, closePath));
 }
Example #3
0
        public static Mesh CreateStrokeSimple(List <List <Vector2> > inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
        {
            if (inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
            {
                return(null);
            }

            AddInputShape(inputShapes);

            Color color = GetStrokeColor(paintable);

            float strokeWidth = paintable.strokeWidth;

            if (inputShapes.Count > 1)
            {
                CombineInstance[] combineInstances = new CombineInstance[inputShapes.Count];
                for (int i = 0; i < inputShapes.Count; i++)
                {
                    combineInstances[i]      = new CombineInstance();
                    combineInstances[i].mesh = SVGMeshUtils.VectorLine(inputShapes[i].ToArray(), color, color, strokeWidth, 0f, closePath);
                }

                Mesh mesh = new Mesh();
                mesh.CombineMeshes(combineInstances, true, false);
                return(mesh);
            }
            else
            {
                return(SVGMeshUtils.VectorLine(inputShapes[0].ToArray(), color, color, strokeWidth, 0f, closePath));
            }
        }
 public static Color GetStrokeColor(SVGPaintable paintable)
 {   
     Color color = paintable.strokeColor.Value.color;
     color.a *= paintable.strokeOpacity * paintable.opacity;
     paintable.svgFill = new SVGFill(color, FILL_BLEND.OPAQUE, FILL_TYPE.SOLID);
     if(color.a != 1f) paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
     return color;
 }
Example #5
0
        public static void AddLayer(string name, List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, bool isStroke = false)
        {
            SVGLayer layer;

            if (SVGSimplePath.CreatePolygon(inputShapes, paintable, matrix, out layer, isStroke))
            {
                layer.name = name;
                layers.Add(layer);
            }
        }
 public SVGPolygonElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
 {
     this._attrList = node.attributes;
     this._paintable = new SVGPaintable(inheritPaintable, node);
     this._listPoints = ExtractPoints(this._attrList.GetValue("points"));
     this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));
     
     Rect viewport = _paintable.viewport;
     this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
     paintable.SetViewport(viewport);
 }
Example #7
0
        public SVGPathElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            _attrList            = node.attributes;
            _paintable           = new SVGPaintable(inheritPaintable, node);
            currentTransformList = new SVGTransformList(_attrList.GetValue("transform"));
            Rect viewport = _paintable.viewport;

            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
            paintable.SetViewport(viewport);
            Initial();
        }
        public SVGPathElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            _attrList = node.attributes;
            _paintable = new SVGPaintable(inheritPaintable, node);
            currentTransformList = new SVGTransformList(_attrList.GetValue("transform"));
            Rect viewport = _paintable.viewport;
            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
            paintable.SetViewport(viewport);

            Initial();
        }
Example #9
0
        public SVGPolygonElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            this._attrList            = node.attributes;
            this._paintable           = new SVGPaintable(inheritPaintable, node);
            this._listPoints          = ExtractPoints(this._attrList.GetValue("points"));
            this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));

            Rect viewport = _paintable.viewport;

            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
            paintable.SetViewport(viewport);
        }
Example #10
0
        public static Color GetStrokeColor(SVGPaintable paintable)
        {
            Color color = paintable.strokeColor.Value.color;

            color.a          *= paintable.strokeOpacity * paintable.opacity;
            paintable.svgFill = new SVGFill(color, FILL_BLEND.OPAQUE, FILL_TYPE.SOLID);
            if (color.a != 1f)
            {
                paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
            }
            return(color);
        }
Example #11
0
        public static Mesh CreateStrokeMesh(List <Vector2> inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
        {
            if (inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
            {
                return(null);
            }

            return(CreateStrokeMesh(new List <List <Vector2> >()
            {
                inputShapes
            }, paintable, closePath));
        }
Example #12
0
        public static bool CreatePolygon(List <Vector2> inputShape, SVGPaintable paintable, SVGMatrix matrix, out SVGLayer layer, bool isStroke = false)
        {
            if (inputShape == null || inputShape.Count == 0)
            {
                layer = new SVGLayer();
                return(false);
            }

            return(CreatePolygon(new List <List <Vector2> >()
            {
                inputShape
            }, paintable, matrix, out layer, isStroke));
        }
        public SVGCircleElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            this._attrList = node.attributes;
            this._paintable = new SVGPaintable(inheritPaintable, node);
            this._cx = new SVGLength(attrList.GetValue("cx"));
            this._cy = new SVGLength(attrList.GetValue("cy"));
            this._r = new SVGLength(attrList.GetValue("r"));
            this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));

            Rect viewport = _paintable.viewport;
            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(this._attrList, ref viewport, false)));
            paintable.SetViewport(viewport);
        }
Example #14
0
        public static Mesh CreatePolygon(List <Vector2> inputShapes, SVGPaintable paintable, SVGMatrix matrix, out Mesh antialiasingMesh)
        {
            if (inputShapes == null || inputShapes.Count == 0)
            {
                antialiasingMesh = null;
                return(null);
            }

            return(CreatePolygon(new List <List <Vector2> >()
            {
                inputShapes
            }, paintable, matrix, out antialiasingMesh));
        }
Example #15
0
        public SVGCircleElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            this._attrList            = node.attributes;
            this._paintable           = new SVGPaintable(inheritPaintable, node);
            this._cx                  = new SVGLength(attrList.GetValue("cx"));
            this._cy                  = new SVGLength(attrList.GetValue("cy"));
            this._r                   = new SVGLength(attrList.GetValue("r"));
            this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));

            Rect viewport = _paintable.viewport;

            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(this._attrList, ref viewport, false)));
            paintable.SetViewport(viewport);
        }
 public SVGLineElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
 {
     this._attrList = node.attributes;
     this._paintable = new SVGPaintable(inheritPaintable, node);
     this._x1 = new SVGLength(attrList.GetValue("x1"));
     this._y1 = new SVGLength(attrList.GetValue("y1"));
     this._x2 = new SVGLength(attrList.GetValue("x2"));
     this._y2 = new SVGLength(attrList.GetValue("y2"));
     this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));
     
     Rect viewport = _paintable.viewport;
     this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
     paintable.SetViewport(viewport);
 }
Example #17
0
        public SVGLineElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            this._attrList            = node.attributes;
            this._paintable           = new SVGPaintable(inheritPaintable, node);
            this._x1                  = new SVGLength(attrList.GetValue("x1"));
            this._y1                  = new SVGLength(attrList.GetValue("y1"));
            this._x2                  = new SVGLength(attrList.GetValue("x2"));
            this._y2                  = new SVGLength(attrList.GetValue("y2"));
            this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));

            Rect viewport = _paintable.viewport;

            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
            paintable.SetViewport(viewport);
        }
Example #18
0
        public SVGRectElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            this._attrList            = node.attributes;
            this._paintable           = new SVGPaintable(inheritPaintable, node);
            this._x                   = new SVGLength(attrList.GetValue("x"));
            this._y                   = new SVGLength(attrList.GetValue("y"));
            this._width               = new SVGLength(attrList.GetValue("width"));
            this._height              = new SVGLength(attrList.GetValue("height"));
            this._rx                  = new SVGLength(attrList.GetValue("rx"));
            this._ry                  = new SVGLength(attrList.GetValue("ry"));
            this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));

            Rect viewport = _paintable.viewport;

            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
            paintable.SetViewport(viewport);
        }
Example #19
0
        public static SVGShape[] GetShapes(List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, bool isStroke = false)
        {
            SVGShape[] shapes = null;;
            SVGShape   shape;
            SVGShape   antialiasingShape;

            if (SVGSimplePath.CreatePolygon(inputShapes, paintable, matrix, out shape, out antialiasingShape, isStroke, _antialiasing))
            {
                if (_antialiasing)
                {
                    shapes = new SVGShape[] { shape, antialiasingShape };
                }
                else
                {
                    shapes = new SVGShape[] { shape };
                }
            }

            return(shapes);
        }
Example #20
0
        public static Mesh CreateStrokeMesh(List <List <Vector2> > inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
        {
            if (inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
            {
                return(null);
            }

            List <StrokeSegment[]> segments = new List <StrokeSegment[]>();

            for (int i = 0; i < inputShapes.Count; i++)
            {
                if (inputShapes[i] == null || inputShapes[i].Count < 2)
                {
                    continue;
                }

                segments.Add(GetSegments(inputShapes[i]));
            }

            return(SVGLineUtils.StrokeMesh(segments, paintable.strokeWidth, GetStrokeColor(paintable), GetStrokeLineJoin(paintable.strokeLineJoin), GetStrokeLineCap(paintable.strokeLineCap), paintable.miterLimit, paintable.dashArray, paintable.dashOffset, closePath, SVGGraphics.roundQuality));
        }
Example #21
0
 public SVGGroupElement(SVGParser xmlImp,
                        SVGTransformList inheritTransformList,
                        SVGPaintable inheritPaintable) : base(xmlImp, inheritTransformList, inheritPaintable)
 {
     _name = attributeList.GetValue("id");
 }
        public static List<List<Vector2>> CreateStroke(List<List<Vector2>> inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
        {
            if(inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
                return null;

            List<StrokeSegment[]> segments = new List<StrokeSegment[]>();
            for(int i = 0; i < inputShapes.Count; i++)
            {
                if(inputShapes[i] == null || inputShapes[i].Count < 2)
                    continue;
                
                segments.Add(GetSegments(inputShapes[i]));
            }

            return SVGLineUtils.StrokeShape(segments, paintable.strokeWidth, Color.black, GetStrokeLineJoin(paintable.strokeLineJoin), GetStrokeLineCap(paintable.strokeLineCap), paintable.miterLimit, paintable.dashArray, paintable.dashOffset, closePath, SVGGraphics.roundQuality);
        }
Example #23
0
        public static bool CreatePolygon(List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, out SVGLayer layer, bool isStroke = false)
        {
            layer = new SVGLayer();
            if (inputShapes == null || inputShapes.Count == 0)
            {
                return(false);
            }

            List <List <Vector2> > simplifiedShapes = new List <List <Vector2> >();
            PolyFillType           fillType         = PolyFillType.pftNonZero;

            if (paintable.fillRule == SVGFillRule.EvenOdd)
            {
                fillType = PolyFillType.pftEvenOdd;
            }
            simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType);
            if (simplifiedShapes == null || simplifiedShapes.Count == 0)
            {
                return(false);
            }

            AddInputShape(simplifiedShapes);

            Rect bounds   = GetRect(simplifiedShapes);
            Rect viewport = paintable.viewport;

            if (!isStroke)
            {
                switch (paintable.GetPaintType())
                {
                case SVGPaintMethod.SolidFill:
                {
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                case SVGPaintMethod.LinearGradientFill:
                {
                    SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = linearGradBrush.fill;
                }
                break;

                case SVGPaintMethod.RadialGradientFill:
                {
                    SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = radialGradBrush.fill;
                }
                break;

                case SVGPaintMethod.ConicalGradientFill:
                {
                    SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = conicalGradBrush.fill;
                }
                break;

                case SVGPaintMethod.PathDraw:
                {
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                default:
                    break;
                }
            }
            else
            {
                Color color = paintable.strokeColor.Value.color;
                color.a          *= paintable.strokeOpacity;
                paintable.svgFill = new SVGFill(color, FILL_BLEND.OPAQUE, FILL_TYPE.SOLID);
                if (color.a != 1f)
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
                paintable.svgFill.color = color;
            }

            LibTessDotNet.Tess            tesselation = new LibTessDotNet.Tess();
            LibTessDotNet.ContourVertex[] path;
            int pathLength;

            for (int i = 0; i < simplifiedShapes.Count; i++)
            {
                if (simplifiedShapes[i] == null)
                {
                    continue;
                }

                pathLength = simplifiedShapes[i].Count;
                path       = new LibTessDotNet.ContourVertex[pathLength];
                Vector2 position;
                for (int j = 0; j < pathLength; j++)
                {
                    position         = simplifiedShapes[i][j];
                    path[j].Position = new LibTessDotNet.Vec3 {
                        X = position.x, Y = position.y, Z = 0f
                    };
                }
                tesselation.AddContour(path, SVGImporter.LibTessDotNet.ContourOrientation.Clockwise);
            }

            tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);

            int meshVertexCount = tesselation.Vertices.Length;

            layer.vertices = new Vector2[meshVertexCount];

            for (int i = 0; i < meshVertexCount; i++)
            {
                layer.vertices[i] = new Vector2(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y) * SVGAssetImport.meshScale;
            }

            int numTriangles = tesselation.ElementCount;

            layer.triangles = new int[numTriangles * 3];
            for (int i = 0; i < numTriangles; i++)
            {
                layer.triangles[i * 3]     = tesselation.Elements[i * 3];
                layer.triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1];
                layer.triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2];
            }

            layer.fill         = paintable.svgFill;
            layer.fill.opacity = paintable.opacity;
            if (layer.fill.opacity < 1f && layer.fill.blend == FILL_BLEND.OPAQUE)
            {
                layer.fill.blend = FILL_BLEND.ALPHA_BLENDED;
            }

            if (layer.fill.fillType == FILL_TYPE.GRADIENT && layer.fill.gradientColors != null)
            {
                layer.fill.color = Color.white;
            }
            else if (layer.fill.fillType == FILL_TYPE.TEXTURE)
            {
                layer.fill.color = Color.white;
            }

            viewport.x         *= SVGAssetImport.meshScale;
            viewport.y         *= SVGAssetImport.meshScale;
            viewport.size      *= SVGAssetImport.meshScale;
            layer.fill.viewport = viewport;

            if (layer.fill.transform != null)
            {
                SVGMatrix scaleMatrix = SVGMatrix.Identity().Scale(SVGAssetImport.meshScale);
                layer.fill.transform = scaleMatrix.Multiply(layer.fill.transform);
                layer.fill.transform = layer.fill.transform.Multiply(scaleMatrix.Inverse());
            }

            Vector2 boundsMin = bounds.min * SVGAssetImport.meshScale;
            Vector2 boundsMax = bounds.max * SVGAssetImport.meshScale;

            layer.bounds = new Rect(boundsMin.x,
                                    boundsMin.y,
                                    boundsMax.x - boundsMin.x,
                                    boundsMax.y - boundsMin.y);

            return(true);
        }
Example #24
0
        protected static void WriteUVGradientCoordinates(ref Vector2[] uv, Vector3[] vertices, SVGPaintable svgPaintable, Rect bounds)
        {
            SVGFill svgFill = svgPaintable.svgFill;

            if (svgFill.fillType == FILL_TYPE.GRADIENT)
            {
                int meshVertexCount = vertices.Length;

                uv = new Vector2[meshVertexCount];
                Vector2   uvPoint          = Vector2.zero;
                SVGMatrix svgFillTransform = GetFillTransform(svgPaintable, bounds);
                Rect      viewport         = svgPaintable.viewport;
                for (int i = 0; i < meshVertexCount; i++)
                {
                    uvPoint.x = vertices [i].x;
                    uvPoint.y = vertices [i].y;
                    uvPoint   = svgFillTransform.Transform(uvPoint);

                    uv [i].x = (uvPoint.x - viewport.x) / viewport.width;
                    uv [i].y = (uvPoint.y - viewport.y) / viewport.height;
                }
            }
        }
Example #25
0
        protected static void WriteUVGradientIndexType(ref Vector2[] uv, int meshVertexCount, SVGPaintable svgPaintable)
        {
            SVGFill svgFill = svgPaintable.svgFill;

            if (svgFill.fillType == FILL_TYPE.GRADIENT && svgFill.gradientColors != null)
            {
                Vector2 gradientUV = new Vector2(svgFill.gradientColors.index, (int)svgFill.gradientType);
                uv = new Vector2[meshVertexCount];
                for (int i = 0; i < meshVertexCount; i++)
                {
                    uv [i].x = gradientUV.x;
                    uv [i].y = gradientUV.y;
                }
            }
        }
Example #26
0
        /*
         * public static Mesh CreateStrokeMesh(List<Vector2> inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
         * {
         *  if(inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
         *      return null;
         *
         *  return CreateStrokeMesh(new List<List<Vector2>>(){inputShapes}, paintable, closePath);
         * }
         *
         * public static Mesh CreateStrokeMesh(List<List<Vector2>> inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
         * {
         *  if(inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
         *      return null;
         *
         *  List<StrokeSegment[]> segments = new List<StrokeSegment[]>();
         *  for(int i = 0; i < inputShapes.Count; i++)
         *  {
         *      if(inputShapes[i] == null || inputShapes[i].Count < 2)
         *          continue;
         *
         *      segments.Add(GetSegments(inputShapes[i]));
         *  }
         *
         *  return SVGLineUtils.StrokeMesh(segments, paintable.strokeWidth, GetStrokeColor(paintable), GetStrokeLineJoin(paintable.strokeLineJoin), GetStrokeLineCap(paintable.strokeLineCap), paintable.miterLimit, paintable.dashArray, paintable.dashOffset, closePath, SVGGraphics.roundQuality);
         * }
         */
        /*
         * public static Mesh CreateStrokeSimple(SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
         * {
         *  return CreateStrokeSimple(new List<List<Vector2>>(){new List<Vector2>(SVGGraphics.position_buffer.ToArray())}, paintable, closePath);
         * }
         */
        public static Mesh CreateStrokeSimple(List <List <Vector2> > inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
        {
            if (inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
            {
                return(null);
            }

            AddInputShape(inputShapes);

            Color color = GetStrokeColor(paintable);

            float strokeWidth = paintable.strokeWidth;

            if (inputShapes.Count > 1)
            {
                CombineInstance[] combineInstances = new CombineInstance[inputShapes.Count];
                for (int i = 0; i < inputShapes.Count; i++)
                {
                    combineInstances[i] = new CombineInstance();
                    SVGShape svgLayer = new SVGShape();
                    if (SVGMeshUtils.VectorLine(inputShapes[i].ToArray(), out svgLayer, color, color, strokeWidth, 0f, closePath))
                    {
                        Mesh      localMesh     = new Mesh();
                        int       totalVertices = svgLayer.vertices.Length;
                        Vector3[] vertices      = new Vector3[totalVertices];
                        for (int j = 0; j < totalVertices; j++)
                        {
                            vertices[j] = svgLayer.vertices[j];
                        }
                        localMesh.vertices       = vertices;
                        localMesh.triangles      = svgLayer.triangles;
                        localMesh.colors32       = svgLayer.colors;
                        combineInstances[i].mesh = localMesh;
                    }
                }

                Mesh mesh = new Mesh();
                mesh.CombineMeshes(combineInstances, true, false);
                return(mesh);
            }
            else
            {
                SVGShape svgLayer = new SVGShape();
                if (SVGMeshUtils.VectorLine(inputShapes[0].ToArray(), out svgLayer, color, color, strokeWidth, 0f, closePath))
                {
                    Mesh      localMesh     = new Mesh();
                    int       totalVertices = svgLayer.vertices.Length;
                    Vector3[] vertices      = new Vector3[totalVertices];
                    for (int j = 0; j < totalVertices; j++)
                    {
                        vertices[j] = svgLayer.vertices[j];
                    }
                    localMesh.vertices  = vertices;
                    localMesh.triangles = svgLayer.triangles;
                    localMesh.colors32  = svgLayer.colors;

                    return(localMesh);
                }
                return(null);
            }
        }
        public static Mesh CreateStrokeSimple(List<List<Vector2>> inputShapes, SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
        {
            if(inputShapes == null || inputShapes.Count == 0 || paintable == null || paintable.strokeWidth <= 0f)
                return null;

            AddInputShape(inputShapes);

            Color color = GetStrokeColor(paintable);            

            float strokeWidth = paintable.strokeWidth;
            if(inputShapes.Count > 1)
            {
                CombineInstance[] combineInstances = new CombineInstance[inputShapes.Count];
                for(int i = 0; i < inputShapes.Count; i++)
                {
                    combineInstances[i] = new CombineInstance();
                    combineInstances[i].mesh = SVGMeshUtils.VectorLine(inputShapes[i].ToArray(), color, color, strokeWidth, 0f, closePath);
                }

                Mesh mesh = new Mesh();
                mesh.CombineMeshes(combineInstances, true, false);
                return mesh;
            } else {
                return SVGMeshUtils.VectorLine(inputShapes[0].ToArray(), color, color, strokeWidth, 0f, closePath);
            }
        }
 public static Mesh CreateStrokeSimple(SVGPaintable paintable, ClosePathRule closePath = ClosePathRule.NEVER)
 {
     return CreateStrokeSimple(new List<List<Vector2>>(){new List<Vector2>(SVGGraphics.position_buffer.ToArray())}, paintable, closePath);
 }
Example #29
0
        public SVGPaintable(SVGPaintable inheritPaintable, Node node)
        {
            InitDefaults();

            if (inheritPaintable != null)
            {
                this._visibility      = inheritPaintable.visibility;
                this._display         = inheritPaintable.display;
                this._clipRule        = inheritPaintable.clipRule;
                this._viewport        = inheritPaintable._viewport;
                this._fillRule        = inheritPaintable._fillRule;
                this._cssStyle        = inheritPaintable._cssStyle;
                this._clipPathList    = CloneClipPathList(inheritPaintable._clipPathList);
                this._linearGradList  = inheritPaintable._linearGradList;
                this._radialGradList  = inheritPaintable._radialGradList;
                this._conicalGradList = inheritPaintable._conicalGradList;
            }

            if (inheritPaintable != null)
            {
                if (IsFillX() == false)
                {
                    if (inheritPaintable.IsLinearGradiantFill())
                    {
                        this._gradientID = inheritPaintable.gradientID;
                    }
                    else if (inheritPaintable.IsRadialGradiantFill())
                    {
                        this._gradientID = inheritPaintable.gradientID;
                    }
                    else
                    {
                        this._fillColor = inheritPaintable.fillColor;
                    }
                }

                if (!IsStroke() && inheritPaintable.IsStroke())
                {
                    this._strokeColor = inheritPaintable.strokeColor;
                }

                if (_strokeLineCap == SVGStrokeLineCapMethod.Unknown)
                {
                    _strokeLineCap = inheritPaintable.strokeLineCap;
                }

                if (_strokeLineJoin == SVGStrokeLineJoinMethod.Unknown)
                {
                    _strokeLineJoin = inheritPaintable.strokeLineJoin;
                }

                if (isStrokeWidth == false)
                {
                    this._strokeWidth.NewValueSpecifiedUnits(inheritPaintable.strokeWidth);
                }
            }

            Initialize(node.attributes);
            ReadCSS(node);

            if (inheritPaintable != null)
            {
                _opacity       *= inheritPaintable._opacity;
                _fillOpacity   *= inheritPaintable._fillOpacity;
                _strokeOpacity *= inheritPaintable._strokeOpacity;
            }
        }
Example #30
0
        public static Mesh CreatePolygon(List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, out Mesh antialiasingMesh)
        {
            antialiasingMesh = null;
            if (inputShapes == null || inputShapes.Count == 0)
            {
                return(null);
            }

            List <List <Vector2> > simplifiedShapes = new List <List <Vector2> >();

            PolyFillType fillType = PolyFillType.pftNonZero;

            if (paintable.fillRule == SVGFillRule.EvenOdd)
            {
                fillType = PolyFillType.pftEvenOdd;
            }

            simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType);
            if (simplifiedShapes == null || simplifiedShapes.Count == 0)
            {
                return(null);
            }

            AddInputShape(simplifiedShapes);

            Rect bounds = GetRect(simplifiedShapes);

            switch (paintable.GetPaintType())
            {
            case SVGPaintMethod.SolidGradientFill:
            {
                Color        color     = Color.black;
                SVGColorType colorType = paintable.fillColor.Value.colorType;
                if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                {
                    color.a          *= paintable.fillOpacity;
                    paintable.svgFill = new SVGFill(color);
                }
                else
                {
                    color             = paintable.fillColor.Value.color;
                    color.a          *= paintable.fillOpacity;
                    paintable.svgFill = new SVGFill(color);
                }

                paintable.svgFill.fillType = FILL_TYPE.SOLID;
                if (color.a == 1)
                {
                    paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                }
                else
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
            }
            break;

            case SVGPaintMethod.LinearGradientFill:
            {
                SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix);
                paintable.svgFill = linearGradBrush.fill;
            }
            break;

            case SVGPaintMethod.RadialGradientFill:
            {
                SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix);
                paintable.svgFill = radialGradBrush.fill;
            }
            break;

            case SVGPaintMethod.ConicalGradientFill:
            {
                SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix);
                paintable.svgFill = conicalGradBrush.fill;
            }
            break;

            case SVGPaintMethod.PathDraw:
            {
                Color        color     = Color.black;
                SVGColorType colorType = paintable.fillColor.Value.colorType;
                if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                {
                    color.a          *= paintable.strokeOpacity;
                    paintable.svgFill = new SVGFill(color);
                }
                else
                {
                    color             = paintable.fillColor.Value.color;
                    color.a          *= paintable.strokeOpacity;
                    paintable.svgFill = new SVGFill(color);
                }

                paintable.svgFill.fillType = FILL_TYPE.SOLID;
                if (color.a == 1)
                {
                    paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                }
                else
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
            }
            break;

            default:
                break;
            }

            LibTessDotNet.Tess            tesselation = new LibTessDotNet.Tess();
            LibTessDotNet.ContourVertex[] path;
            int pathLength;

            for (int i = 0; i < simplifiedShapes.Count; i++)
            {
                if (simplifiedShapes[i] == null)
                {
                    continue;
                }

                pathLength = simplifiedShapes[i].Count;
                path       = new LibTessDotNet.ContourVertex[pathLength];
                Vector2 position;
                for (int j = 0; j < pathLength; j++)
                {
                    position         = simplifiedShapes[i][j];
                    path[j].Position = new LibTessDotNet.Vec3 {
                        X = position.x, Y = position.y, Z = 0f
                    };
                }
                tesselation.AddContour(path);
            }

            tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);

            Mesh mesh            = new Mesh();
            int  meshVertexCount = tesselation.Vertices.Length;

            Vector3[] vertices = new Vector3[meshVertexCount];
            Vector2[] uv       = null;
            Vector2[] uv2      = null;

            for (int i = 0; i < meshVertexCount; i++)
            {
                vertices[i] = new Vector3(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y, 0f);
            }

            int numTriangles = tesselation.ElementCount;

            int[] triangles = new int[numTriangles * 3];
            for (int i = 0; i < numTriangles; i++)
            {
                triangles[i * 3]     = tesselation.Elements[i * 3];
                triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1];
                triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2];
            }

            SVGFill svgFill   = paintable.svgFill;
            Color32 fillColor = Color.white;

            if (svgFill.fillType != FILL_TYPE.GRADIENT && svgFill.gradientColors == null)
            {
                fillColor = svgFill.color;
            }

            antialiasingMesh = CreateAntialiasing(simplifiedShapes, fillColor, -SVGAssetImport.antialiasingWidth, false, SVGImporter.Utils.ClosePathRule.ALWAYS);

            Color32[] colors32 = new Color32[meshVertexCount];

            for (int i = 0; i < meshVertexCount; i++)
            {
                colors32 [i].r = fillColor.r;
                colors32 [i].g = fillColor.g;
                colors32 [i].b = fillColor.b;
                colors32 [i].a = fillColor.a;
            }

            if (antialiasingMesh != null)
            {
                Vector3[] antialiasingVertices = antialiasingMesh.vertices;
                Vector2[] antialiasingUV       = antialiasingMesh.uv;
                Vector2[] antialiasingUV2      = antialiasingMesh.uv2;
                WriteUVGradientCoordinates(ref antialiasingUV, antialiasingVertices, paintable, bounds);
                WriteUVGradientIndexType(ref antialiasingUV2, antialiasingVertices.Length, paintable);
                antialiasingMesh.uv  = antialiasingUV;
                antialiasingMesh.uv2 = antialiasingUV2;
            }

            WriteUVGradientCoordinates(ref uv, vertices, paintable, bounds);
            WriteUVGradientIndexType(ref uv2, meshVertexCount, paintable);

            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            if (colors32 != null)
            {
                mesh.colors32 = colors32;
            }
            if (uv != null)
            {
                mesh.uv = uv;
            }
            if (uv2 != null)
            {
                mesh.uv2 = uv2;
            }

            return(mesh);
        }
        protected static void WriteUVGradientCoordinates(ref Vector2[] uv, Vector3[] vertices, SVGPaintable svgPaintable, Rect bounds)
        {
            SVGFill svgFill = svgPaintable.svgFill;
            if(svgFill.fillType == FILL_TYPE.GRADIENT)
            {
                int meshVertexCount = vertices.Length;

                uv = new Vector2[meshVertexCount];
                Vector2 uvPoint = Vector2.zero;
                SVGMatrix svgFillTransform = GetFillTransform(svgPaintable, bounds);                
                Rect viewport = svgPaintable.viewport;
                for (int i = 0; i < meshVertexCount; i++)
                {
                    uvPoint.x = vertices [i].x;
                    uvPoint.y = vertices [i].y;
                    uvPoint = svgFillTransform.Transform(uvPoint);
                    
                    uv [i].x = (uvPoint.x - viewport.x) / viewport.width;
                    uv [i].y = (uvPoint.y - viewport.y) / viewport.height;
                }
            }
        }
Example #32
0
        //const float defaultViewportScale = 800f;
        private static SVGMatrix GetFillTransform(SVGPaintable svgPaintable, Rect bounds)
        {
            SVGFill   svgFill        = svgPaintable.svgFill;
            SVGMatrix transform      = new SVGMatrix();
            SVGMatrix gradientMatrix = svgFill.gradientTransform;

            Rect viewport = svgPaintable.viewport;

            if (svgFill.fillType == FILL_TYPE.GRADIENT)
            {
                switch (svgFill.gradientType)
                {
                case GRADIENT_TYPE.LINEAR:
                {
                    Vector2 startPoint = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds);
                    Vector2 endPoint   = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds);

                    Vector2 gradientVector   = endPoint - startPoint;
                    Vector2 normalizedVector = Vector2.zero;

                    float   angle   = Mathf.Atan2(gradientVector.y, gradientVector.x) * Mathf.Rad2Deg;
                    Vector2 posDiff = Vector2.Lerp(startPoint, endPoint, 0.5f);

                    float magnitude = gradientVector.magnitude;

                    if (magnitude != 0f)
                    {
                        normalizedVector.x = viewport.width / magnitude;
                        normalizedVector.y = viewport.height / magnitude;
                    }

                    transform = transform.Translate(viewport.center);
                    transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y);
                    transform = transform.Rotate(-angle);
                    transform = transform.Translate(-posDiff);

                    transform = transform.Multiply(gradientMatrix.Inverse());
                    transform = transform.Multiply(svgFill.transform.Inverse());

                    break;
                }

                case GRADIENT_TYPE.RADIAL:
                {
                    Vector2 point  = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds);
                    float   radius = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds).x;
                    if (svgFill.gradientEndX.unitType == SVGLengthType.Percentage)
                    {
                        radius *= 0.5f;
                    }

                    float radiusTimesTwo = radius * 2f;

                    Vector2 normalizedVector = Vector2.zero;

                    if (radiusTimesTwo != 0f)
                    {
                        normalizedVector.x = viewport.width / radiusTimesTwo;
                        normalizedVector.y = viewport.height / radiusTimesTwo;
                    }

                    transform = transform.Translate(viewport.center);
                    transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y);
                    transform = transform.Translate(-point);

                    transform = transform.Multiply(gradientMatrix.Inverse());
                    transform = transform.Multiply(svgFill.transform.Inverse());

                    break;
                }

                case GRADIENT_TYPE.CONICAL:
                {
                    Vector2 point  = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds);
                    float   radius = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds).x;
                    if (svgFill.gradientEndX.unitType == SVGLengthType.Percentage)
                    {
                        radius *= 0.5f;
                    }

                    float radiusTimesTwo = radius * 2f;

                    Vector2 normalizedVector = Vector2.zero;

                    if (radiusTimesTwo != 0f)
                    {
                        normalizedVector.x = viewport.width / radiusTimesTwo;
                        normalizedVector.y = viewport.height / radiusTimesTwo;
                    }

                    transform = transform.Translate(viewport.center);
                    transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y);
                    transform = transform.Translate(-point);

                    transform = transform.Multiply(gradientMatrix.Inverse());
                    transform = transform.Multiply(svgFill.transform.Inverse());

                    break;
                }
                }
            }

            return(transform);
        }
        //const float defaultViewportScale = 800f;
        private static SVGMatrix GetFillTransform(SVGPaintable svgPaintable, Rect bounds)
        {
            SVGFill svgFill = svgPaintable.svgFill;
            SVGMatrix transform = new SVGMatrix();
            SVGMatrix gradientMatrix = svgFill.gradientTransform;

            Rect viewport = svgPaintable.viewport;

            if (svgFill.fillType == FILL_TYPE.GRADIENT)
            {
                switch (svgFill.gradientType)
                {
                    case GRADIENT_TYPE.LINEAR:
                    {
                        Vector2 startPoint = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds);
                        Vector2 endPoint = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds);

                        Vector2 gradientVector = endPoint - startPoint;        
                        Vector2 normalizedVector = Vector2.zero;

                        float angle = Mathf.Atan2(gradientVector.y, gradientVector.x) * Mathf.Rad2Deg;
                        Vector2 posDiff = Vector2.Lerp(startPoint, endPoint, 0.5f);

                        float magnitude = gradientVector.magnitude;

                        if(magnitude != 0f)
                        {
                            normalizedVector.x = viewport.width / magnitude;
                            normalizedVector.y = viewport.height / magnitude;
                        }

                        transform = transform.Translate(viewport.center);
                        transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y);
                        transform = transform.Rotate(-angle);
                        transform = transform.Translate(-posDiff);

                        transform = transform.Multiply(gradientMatrix.Inverse());
                        transform = transform.Multiply(svgFill.transform.Inverse());

                        break;
                    }
                    case GRADIENT_TYPE.RADIAL:
                    {
                        Vector2 point = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds);
                        float radius = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds).x;
                        if(svgFill.gradientEndX.unitType == SVGLengthType.Percentage) radius *= 0.5f;

                        float radiusTimesTwo = radius * 2f;

                        Vector2 normalizedVector = Vector2.zero;

                        if(radiusTimesTwo != 0f)
                        {
                            normalizedVector.x = viewport.width / radiusTimesTwo;
                            normalizedVector.y = viewport.height / radiusTimesTwo;
                        }

                        transform = transform.Translate(viewport.center);
                        transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y);
                        transform = transform.Translate(-point);
                        
                        transform = transform.Multiply(gradientMatrix.Inverse());
                        transform = transform.Multiply(svgFill.transform.Inverse());

                        break;
                    }
                    case GRADIENT_TYPE.CONICAL:
                    {
                        Vector2 point = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds);
                        float radius = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds).x;
                        if(svgFill.gradientEndX.unitType == SVGLengthType.Percentage) radius *= 0.5f;

                        float radiusTimesTwo = radius * 2f;
                        
                        Vector2 normalizedVector = Vector2.zero;
                        
                        if(radiusTimesTwo != 0f)
                        {
                            normalizedVector.x = viewport.width / radiusTimesTwo;
                            normalizedVector.y = viewport.height / radiusTimesTwo;
                        }
                        
                        transform = transform.Translate(viewport.center);
                        transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y);
                        transform = transform.Translate(-point);
                        
                        transform = transform.Multiply(gradientMatrix.Inverse());
                        transform = transform.Multiply(svgFill.transform.Inverse());
                        
                        break;
                    }
                }
            }
            
            return transform;
        }
        public static Mesh CreatePolygon(List<Vector2> inputShapes, SVGPaintable paintable, SVGMatrix matrix, out Mesh antialiasingMesh)
        {        
            if(inputShapes == null || inputShapes.Count == 0)
            {
                antialiasingMesh = null;
                return null;
            }

            return CreatePolygon(new List<List<Vector2>>(){inputShapes}, paintable, matrix, out antialiasingMesh);
        }
        public SVGPaintable(SVGPaintable inheritPaintable, Node node)
        {
            InitDefaults();

            if(inheritPaintable != null)
            {
                this._visibility = inheritPaintable.visibility;
                this._display = inheritPaintable.display;
                this._clipRule = inheritPaintable.clipRule;
                this._viewport = inheritPaintable._viewport;
                this._fillRule = inheritPaintable._fillRule;
                this._cssStyle = inheritPaintable._cssStyle;
                this._clipPathList = CloneClipPathList(inheritPaintable._clipPathList);
                this._linearGradList = inheritPaintable._linearGradList;
                this._radialGradList = inheritPaintable._radialGradList;
                this._conicalGradList = inheritPaintable._conicalGradList;
            }

            Initialize(node.attributes);

            if(inheritPaintable != null)
            {
                if (IsFillX() == false)
                {
                    if (inheritPaintable.IsLinearGradiantFill())
                    {
                        this._gradientID = inheritPaintable.gradientID;
                    } else if (inheritPaintable.IsRadialGradiantFill())
                    {
                        this._gradientID = inheritPaintable.gradientID;
                    } else
                        this._fillColor = inheritPaintable.fillColor;
                }

                if (!IsStroke() && inheritPaintable.IsStroke())
                {
                    this._strokeColor = inheritPaintable.strokeColor;
                }

                if (_strokeLineCap == SVGStrokeLineCapMethod.Unknown)
                {
                    _strokeLineCap = inheritPaintable.strokeLineCap;
                }

                if (_strokeLineJoin == SVGStrokeLineJoinMethod.Unknown)
                {
                    _strokeLineJoin = inheritPaintable.strokeLineJoin;
                }

                if (isStrokeWidth == false)
                    this._strokeWidth.NewValueSpecifiedUnits(inheritPaintable.strokeWidth);

                _opacity *= inheritPaintable._opacity;
                _fillOpacity *= inheritPaintable._fillOpacity;
                _strokeOpacity *= inheritPaintable._strokeOpacity;
            }

            ReadCSS(node);
        }
Example #36
0
        public static bool CreatePolygon(List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, out SVGShape layer, out SVGShape antialiasingLayer, bool isStroke = false, bool antialiasing = false)
        {
            layer             = new SVGShape();
            antialiasingLayer = new SVGShape();

            if (inputShapes == null || inputShapes.Count == 0)
            {
                return(false);
            }

            List <List <Vector2> > simplifiedShapes = new List <List <Vector2> >();
            PolyFillType           fillType         = PolyFillType.pftNonZero;

            if (paintable.fillRule == SVGFillRule.EvenOdd)
            {
                fillType = PolyFillType.pftEvenOdd;
            }
            simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType);
            if (simplifiedShapes == null || simplifiedShapes.Count == 0)
            {
                return(false);
            }

            AddInputShape(simplifiedShapes);

            Rect bounds   = GetRect(simplifiedShapes);
            Rect viewport = paintable.viewport;

            if (!isStroke)
            {
                switch (paintable.GetPaintType())
                {
                case SVGPaintMethod.SolidFill:
                {
                    layer.type = SVGShapeType.FILL;
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                case SVGPaintMethod.LinearGradientFill:
                {
                    layer.type = SVGShapeType.FILL;
                    SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = linearGradBrush.fill;
                }
                break;

                case SVGPaintMethod.RadialGradientFill:
                {
                    layer.type = SVGShapeType.FILL;
                    SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = radialGradBrush.fill;
                }
                break;

                case SVGPaintMethod.ConicalGradientFill:
                {
                    layer.type = SVGShapeType.FILL;
                    SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = conicalGradBrush.fill;
                }
                break;

                case SVGPaintMethod.PathDraw:
                {
                    layer.type = SVGShapeType.STROKE;
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                default:
                    break;
                }
            }
            else
            {
                layer.type = SVGShapeType.STROKE;
                Color color = paintable.strokeColor.Value.color;
                color.a          *= paintable.strokeOpacity;
                paintable.svgFill = new SVGFill(color, FILL_BLEND.OPAQUE, FILL_TYPE.SOLID);
                if (color.a != 1f)
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
                paintable.svgFill.color = color;
            }

            // Use LibTessDotNet
            if (true)
            {
                LibTessDotNet.Tess            tesselation = new LibTessDotNet.Tess();
                LibTessDotNet.ContourVertex[] path;
                int pathLength;
                for (int i = 0; i < simplifiedShapes.Count; i++)
                {
                    if (simplifiedShapes[i] == null)
                    {
                        continue;
                    }

                    pathLength = simplifiedShapes[i].Count;
                    path       = new LibTessDotNet.ContourVertex[pathLength];
                    Vector2 position;
                    for (int j = 0; j < pathLength; j++)
                    {
                        position         = simplifiedShapes[i][j];
                        path[j].Position = new LibTessDotNet.Vec3 {
                            X = position.x, Y = position.y, Z = 0f
                        };
                    }
                    tesselation.AddContour(path, SVGImporter.LibTessDotNet.ContourOrientation.Clockwise);
                }

                tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);
                int meshVertexCount = tesselation.Vertices.Length;
                if (meshVertexCount == 0)
                {
                    return(false);
                }

                int numTriangles = tesselation.ElementCount;
                layer.triangles = new int[numTriangles * 3];
                layer.vertices  = new Vector2[meshVertexCount];

                for (int i = 0; i < numTriangles; i++)
                {
                    layer.triangles[i * 3]     = tesselation.Elements[i * 3];
                    layer.triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1];
                    layer.triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2];
                }

                for (int i = 0; i < meshVertexCount; i++)
                {
                    layer.vertices[i] = new Vector2(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y) * SVGAssetImport.meshScale;
                }
            }

            /*
             * else {
             *  // Use Triangle.net library
             *  SVGImporter.TriangleNet.Mesh triangleMesh = new SVGImporter.TriangleNet.Mesh();
             *  SVGImporter.TriangleNet.Geometry.InputGeometry triangleInput = new SVGImporter.TriangleNet.Geometry.InputGeometry();
             *
             *  int pathLength, m = 0;
             *  for(int i = 0; i < simplifiedShapes.Count; i++)
             *  {
             *      if(simplifiedShapes[i] == null)
             *          continue;
             *
             *      pathLength = simplifiedShapes[i].Count;
             *      Vector2 position;
             *      for(int j = 0; j < pathLength; j++)
             *      {
             *          triangleInput.AddPoint(simplifiedShapes[i][j].x, simplifiedShapes[i][j].y);
             *      }
             *  }
             *
             *  triangleMesh.Triangulate(triangleInput);
             *
             *  int totalVertices = triangleMesh.vertices.Count;
             *  layer.vertices = new Vector2[totalVertices];
             *  for(int i = 0; i < totalVertices; i++)
             *  {
             *      layer.vertices[i].x = (float)triangleMesh.vertices[i].x * SVGAssetImport.meshScale;
             *      layer.vertices[i].y = (float)triangleMesh.vertices[i].y * SVGAssetImport.meshScale;
             *  }
             *
             *  int totalTriangles = triangleMesh.triangles.Count;
             *  layer.triangles = new int[totalTriangles * 3];
             *  int ti = 0;
             *  for(int i = 0; i < totalTriangles; i++)
             *  {
             *      ti = i * 3;
             *      layer.triangles[ti] = triangleMesh.triangles[i].P0;
             *      layer.triangles[ti + 1] = triangleMesh.triangles[i].P1;
             *      layer.triangles[ti + 2] = triangleMesh.triangles[i].P2;
             *  }
             * }
             */

            layer.fill         = paintable.svgFill;
            layer.fill.opacity = paintable.opacity;
            if (layer.fill.opacity < 1f && layer.fill.blend == FILL_BLEND.OPAQUE)
            {
                layer.fill.blend = FILL_BLEND.ALPHA_BLENDED;
            }

            if (layer.fill.fillType == FILL_TYPE.GRADIENT && layer.fill.gradientColors != null)
            {
                layer.fill.color = Color.white;
            }
            else if (layer.fill.fillType == FILL_TYPE.TEXTURE)
            {
                layer.fill.color = Color.white;
            }

            viewport.x         *= SVGAssetImport.meshScale;
            viewport.y         *= SVGAssetImport.meshScale;
            viewport.size      *= SVGAssetImport.meshScale;
            layer.fill.viewport = viewport;

            SVGMatrix scaleMatrix = SVGMatrix.identity.Scale(SVGAssetImport.meshScale);

            layer.fill.transform = scaleMatrix.Multiply(layer.fill.transform);
            layer.fill.transform = layer.fill.transform.Multiply(scaleMatrix.Inverse());

            Vector2 boundsMin = bounds.min * SVGAssetImport.meshScale;
            Vector2 boundsMax = bounds.max * SVGAssetImport.meshScale;

            layer.bounds = new Rect(boundsMin.x,
                                    boundsMin.y,
                                    boundsMax.x - boundsMin.x,
                                    boundsMax.y - boundsMin.y);

            if (antialiasing)
            {
                if (CreateAntialiasing(simplifiedShapes, out antialiasingLayer, Color.white, -1f, ClosePathRule.ALWAYS))
                {
                    int verticesLength = antialiasingLayer.vertices.Length;
                    for (int i = 0; i < verticesLength; i++)
                    {
                        antialiasingLayer.vertices[i] *= SVGAssetImport.meshScale;
                    }
                    antialiasingLayer.type = SVGShapeType.ANTIALIASING;
                    antialiasingLayer.RecalculateBounds();
                    antialiasingLayer.fill       = layer.fill.Clone();
                    antialiasingLayer.fill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
            }

            return(true);
        }
        public static Mesh CreatePolygon(List<List<Vector2>> inputShapes, SVGPaintable paintable, SVGMatrix matrix, out Mesh antialiasingMesh)
        {   
            antialiasingMesh = null;
            if(inputShapes == null || inputShapes.Count == 0)
            {
                return null;
            }

            List<List<Vector2>> simplifiedShapes = new List<List<Vector2>>();

            PolyFillType fillType = PolyFillType.pftNonZero;
            if(paintable.fillRule == SVGFillRule.EvenOdd) { fillType = PolyFillType.pftEvenOdd; }

            simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType);
            if(simplifiedShapes == null || simplifiedShapes.Count == 0) return null;

            AddInputShape(simplifiedShapes);

            Rect bounds = GetRect(simplifiedShapes);

            switch (paintable.GetPaintType())
            {
                case SVGPaintMethod.SolidGradientFill:
                {
                    Color color = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if(colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    } else {
                        color = paintable.fillColor.Value.color;
                        color.a *= paintable.fillOpacity; 
                        paintable.svgFill = new SVGFill(color);
                    }
                    
                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if(color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    } else {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                    break;
                case SVGPaintMethod.LinearGradientFill:      
                {
                    SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix);
                    paintable.svgFill = linearGradBrush.fill;
                }
                    break;
                case SVGPaintMethod.RadialGradientFill:
                {
                    SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix);
                    paintable.svgFill = radialGradBrush.fill;
                }
                    break;
                case SVGPaintMethod.ConicalGradientFill:
                {
                    SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix);
                    paintable.svgFill = conicalGradBrush.fill;
                }
                    break;
                case SVGPaintMethod.PathDraw:  
                {
                    Color color = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if(colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    } else {
                        color = paintable.fillColor.Value.color;
                        color.a *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    
                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if(color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    } else {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                    break;
                default:
                    break;
            }

            LibTessDotNet.Tess tesselation = new LibTessDotNet.Tess();
            LibTessDotNet.ContourVertex[] path;
            int pathLength;
            for(int i = 0; i < simplifiedShapes.Count; i++)
            {
                if(simplifiedShapes[i] == null)
                    continue;
                
                pathLength = simplifiedShapes[i].Count;
                path = new LibTessDotNet.ContourVertex[pathLength];
                Vector2 position;
                for(int j = 0; j < pathLength; j++)
                {
                    position = simplifiedShapes[i][j];
                    path[j].Position = new LibTessDotNet.Vec3{X = position.x, Y = position.y, Z = 0f};
                }
                tesselation.AddContour(path);
            }

            tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);

            Mesh mesh = new Mesh();
            int meshVertexCount = tesselation.Vertices.Length;
            Vector3[] vertices = new Vector3[meshVertexCount];
            Vector2[] uv = null;
            Vector2[] uv2 = null;

            for(int i = 0; i < meshVertexCount; i++)
            {
                vertices[i] = new Vector3(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y, 0f);
            }

            int numTriangles = tesselation.ElementCount;
            int[] triangles = new int[numTriangles * 3];
            for (int i = 0; i < numTriangles; i++)
            {
                triangles[i * 3] = tesselation.Elements[i * 3];
                triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1];
                triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2];
            }

            SVGFill svgFill = paintable.svgFill;
            Color32 fillColor = Color.white;
            if (svgFill.fillType != FILL_TYPE.GRADIENT && svgFill.gradientColors == null)
                fillColor = svgFill.color;

            antialiasingMesh = CreateAntialiasing(simplifiedShapes, fillColor, -SVGAssetImport.antialiasingWidth, false, SVGImporter.Utils.ClosePathRule.ALWAYS);

            Color32[] colors32 = new Color32[meshVertexCount];

            for (int i = 0; i < meshVertexCount; i++) 
            {
                colors32 [i].r = fillColor.r;
                colors32 [i].g = fillColor.g;
                colors32 [i].b = fillColor.b;
                colors32 [i].a = fillColor.a;
            }

            if(antialiasingMesh != null)
            {
                Vector3[] antialiasingVertices = antialiasingMesh.vertices;
                Vector2[] antialiasingUV = antialiasingMesh.uv;
                Vector2[] antialiasingUV2 = antialiasingMesh.uv2;
                WriteUVGradientCoordinates(ref antialiasingUV, antialiasingVertices, paintable, bounds);
                WriteUVGradientIndexType(ref antialiasingUV2, antialiasingVertices.Length, paintable);
                antialiasingMesh.uv = antialiasingUV;
                antialiasingMesh.uv2 = antialiasingUV2;
            }

            WriteUVGradientCoordinates(ref uv, vertices, paintable, bounds);
            WriteUVGradientIndexType(ref uv2, meshVertexCount, paintable);

            mesh.vertices = vertices;
            mesh.triangles = triangles;
            if(colors32 != null) mesh.colors32 = colors32;
            if(uv != null) mesh.uv = uv;
            if(uv2 != null) mesh.uv2 = uv2;

            return mesh;
        }
 protected static void WriteUVGradientIndexType(ref Vector2[] uv, int meshVertexCount, SVGPaintable svgPaintable)
 {
     SVGFill svgFill = svgPaintable.svgFill;
     if (svgFill.fillType == FILL_TYPE.GRADIENT && svgFill.gradientColors != null)
     {
         Vector2 gradientUV = new Vector2(svgFill.gradientColors.index, (int)svgFill.gradientType);
         uv = new Vector2[meshVertexCount];
         for (int i = 0; i < meshVertexCount; i++) {
             uv [i].x = gradientUV.x;
             uv [i].y = gradientUV.y;
         }
     }
 }
        public SVGRectElement(Node node, SVGTransformList inheritTransformList, SVGPaintable inheritPaintable = null) : base(inheritTransformList)
        {
            this._attrList = node.attributes;
            this._paintable = new SVGPaintable(inheritPaintable, node);
            this._x = new SVGLength(attrList.GetValue("x"));
            this._y = new SVGLength(attrList.GetValue("y"));
            this._width = new SVGLength(attrList.GetValue("width"));
            this._height = new SVGLength(attrList.GetValue("height"));
            this._rx = new SVGLength(attrList.GetValue("rx"));
            this._ry = new SVGLength(attrList.GetValue("ry"));
            this.currentTransformList = new SVGTransformList(attrList.GetValue("transform"));

            Rect viewport = _paintable.viewport;
            this.currentTransformList.AppendItem(new SVGTransform(SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, false)));
            paintable.SetViewport(viewport);
        }