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); }
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(); 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; }
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); }
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(); }
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); }
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); }
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 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); }
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 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); }
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); }
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); }
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); }
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 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); }
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); }
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; } } }
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 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); }
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; } }
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; } } }
//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); }
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); }