private static IElement CreateSvgLine(XdObjectJson xdObject, List <IDefElement> defs) { var id = xdObject.GetSimpleName().Replace(" ", "_"); var dataName = xdObject.GetSimpleName(); var shape = xdObject.Shape; var parameter = new ElementParameter { Id = id }; parameter.Transform = new Transform { Value = xdObject.Transform }; var opacity = xdObject.Style?.Opacity; parameter.Opacity = opacity; if (xdObject.Group != null) { if (MaskGroupParser.Is(xdObject)) { var clipPathId = $"clip-path{defs.Count}"; parameter.ClipPath = $"url(#{clipPathId})"; var clipPathChildren = xdObject.Meta.Ux.ClipPathResources.Children.Select(x => CreateSvgLine(x, defs)); defs.Add(new ClipPathDefElement { Id = clipPathId, Children = clipPathChildren.ToArray() }); } parameter.DataName = dataName; var blendMode = xdObject.Style?.BlendMode; var isolation = xdObject.Style?.Isolation; var children = xdObject.Group.Children.Select(x => CreateSvgLine(x, defs)).ToArray(); return(new GroupElement { Parameter = parameter, Children = children, BlendMode = blendMode, Isolation = isolation }); } XdStyleFillPatternJson image = null; var fill = xdObject.Style?.Fill; parameter.EnableFill = true; if (fill != null && fill.Type != "none") { var color = xdObject.Style.Fill.ToUnityColor(); parameter.Fill = color; if (fill.Type == "solid" || fill.Type == "gradient") { // nothing to do // gradientはサポートしていないが、知らないタイプというわけではないのでスルー } else if (fill.Type == "pattern") { image = fill.Pattern; parameter.Fill = null; } else { Debug.LogWarning($"Unknown fill type {fill.Type} in {xdObject.Name}"); } if (!string.IsNullOrWhiteSpace(shape.Winding)) { parameter.FillRule = shape.Winding; } } float?shapeR = null; if (shape.R != null) { if (shape.R is List <object> list) { shapeR = (float)(double)list[0]; } else if (shape.R is double d) { shapeR = (float)d; } else { throw new NotSupportedException($"Unknown shape.r type {shape.R.GetType()}"); } } if (shapeR != null && shape.Type != CircleElement.Name) { parameter.Rx = shapeR; if (parameter.Rx > shape.Width / 2f) { parameter.Rx = shape.Width / 2f; } if (parameter.Rx > shape.Height / 2f) { parameter.Rx = shape.Height / 2f; } } var stroke = xdObject.Style?.Stroke; string strokeAlign = null; if (stroke != null && stroke.Type != "none") { parameter.EnableStroke = true; parameter.Stroke = stroke.ToUnityColor(); parameter.StrokeWidth = stroke.Width; parameter.StrokeMiterLimit = stroke.MiterLimit; if (!string.IsNullOrWhiteSpace(stroke.Join)) { parameter.StrokeLinejoin = stroke.Join; } if (!string.IsNullOrWhiteSpace(stroke.Cap)) { parameter.StrokeLinecap = stroke.Cap; } if (stroke.Dash != null) { parameter.StrokeDasharray = stroke.Dash; } if (stroke.Align == null) { strokeAlign = null; } else if (stroke.Align == "outside") { strokeAlign = "outside"; } else if (stroke.Align == "inside") { strokeAlign = "inside"; } else { throw new NotSupportedException($"{xdObject} has unknown align type {stroke.Align}"); } } if (image != null) { var imageBytes = XdImporter.XdFile.GetResource(fill.Pattern.Meta); return(new ImageElement { Parameter = parameter, ImageBytes = imageBytes, Width = shape.Width, Height = shape.Height }); } if (shape.Type == PathElement.Name) { return new PathElement { Parameter = parameter, D = shape.Path } } ; if (shape.Type == CompoundElement.Name) { return new CompoundElement { Parameter = parameter, D = shape.Path } } ; if (shape.Type == LineElement.Name) { return new LineElement { Parameter = parameter, X1 = shape.X1, Y1 = shape.Y1, X2 = shape.X2, Y2 = shape.Y2 } } ; if (shape.Type == RectElement.Name) { if (strokeAlign == "outside") { return(RectElement.Outside(shape, parameter)); } if (strokeAlign == "inside") { return(RectElement.Inside(shape, parameter)); } return(new RectElement { Parameter = parameter, Width = shape.Width, Height = shape.Height }); } if (shape.Type == CircleElement.Name) { if (strokeAlign == "outside") { return(CircleElement.Outside(shape, parameter, shapeR)); } if (strokeAlign == "inside") { return(CircleElement.Inside(shape, parameter, shapeR)); } return(new CircleElement { Parameter = parameter, Cx = shape.Cx, Cy = shape.Cy, R = shapeR.Value }); } if (shape.Type == EllipseElement.Name) { if (strokeAlign == "outside") { return(EllipseElement.Outside(shape, parameter)); } if (strokeAlign == "inside") { return(EllipseElement.Inside(shape, parameter)); } return(new EllipseElement { Parameter = parameter, Cx = shape.Cx, Cy = shape.Cy, Rx = shape.Rx, Ry = shape.Ry }); } throw new NotSupportedException($"Unknown type {shape.Type}"); }
private static IElement CreateSvgLine(XdObjectJson xdObject, List <IDefElement> defs) { var id = xdObject.Name.Replace(" ", "_"); var dataName = xdObject.Name; var shape = xdObject.Shape; var parameter = new ElementParameter { Id = id }; var tx = xdObject.Transform?.Tx ?? 0f; var ty = xdObject.Transform?.Ty ?? 0f; parameter.Transform.X = tx; parameter.Transform.Y = ty; var opacity = xdObject.Style?.Opacity; parameter.Opacity = opacity; if (xdObject.Group != null) { parameter.DataName = dataName; if (xdObject.Meta?.Ux?.ClipPathResources?.Type == "clipPath") { var clipPath = xdObject.Meta.Ux.ClipPathResources.Children[0]; parameter.ClipPath = "url(#clip-path)"; var clipPathPath = new PathElement { Parameter = new ElementParameter { Id = "_Clipping_Path_", DataName = "Clipping Path", Transform = new Transform { X = clipPath.Transform.Tx, Y = clipPath.Transform.Ty, }, }, D = clipPath.Shape.Path, }; defs.Add(new ClipPathDefElement { Id = "clip-path", Path = clipPathPath }); } var children = xdObject.Group.Children.Select(x => CreateSvgLine(x, defs)).ToArray(); return(new GroupElement { Parameter = parameter, Children = children }); } var fill = xdObject.Style?.Fill; parameter.EnableFill = true; if (fill != null && fill.Type != "none") { var color = xdObject.GetFillColor(); parameter.Fill = color; if (!string.IsNullOrWhiteSpace(shape.Winding)) { parameter.FillRule = shape.Winding; } } float?shapeR = null; if (shape.R != null) { if (shape.R is Newtonsoft.Json.Linq.JValue jValue) { shapeR = (float)jValue; } else if (shape.R is Newtonsoft.Json.Linq.JArray jArray) { shapeR = (float)jArray[0]; } else if (shape.R is long l) { shapeR = l; } else if (shape.R is double d) { shapeR = (float)d; } else { throw new NotSupportedException($"Unknown shape.r type {shape.R.GetType()}"); } } if (shapeR != null && shape.Type != CircleElement.Name) { parameter.Rx = shapeR; if (parameter.Rx > shape.Width / 2f) { parameter.Rx = shape.Width / 2f; } if (parameter.Rx > shape.Height / 2f) { parameter.Rx = shape.Height / 2f; } } var stroke = xdObject.Style?.Stroke; string strokeAlign = null; if (stroke != null && stroke.Type != "none") { parameter.EnableStroke = true; parameter.Stroke = stroke.Color.Value; parameter.StrokeWidth = stroke.Width; parameter.StrokeMiterLimit = stroke.MiterLimit; if (!string.IsNullOrWhiteSpace(stroke.Join)) { parameter.StrokeLinejoin = stroke.Join; } if (!string.IsNullOrWhiteSpace(stroke.Cap)) { parameter.StrokeLinecap = stroke.Cap; } if (stroke.Dash != null) { parameter.StrokeDasharray = stroke.Dash; } if (stroke.Align == null) { strokeAlign = null; } else if (stroke.Align == "outside") { strokeAlign = "outside"; } else if (stroke.Align == "inside") { strokeAlign = "inside"; } else { throw new NotSupportedException($"{xdObject} has unknown align type {stroke.Align}"); } } if (shape.Type == PathElement.Name) { return new PathElement { Parameter = parameter, D = shape.Path } } ; if (shape.Type == CompoundElement.Name) { return new CompoundElement { Parameter = parameter, D = shape.Path } } ; if (shape.Type == LineElement.Name) { return new LineElement { Parameter = parameter, X1 = shape.X1, Y1 = shape.Y1, X2 = shape.X2, Y2 = shape.Y2 } } ; if (shape.Type == RectElement.Name) { if (strokeAlign == "outside") { return(RectElement.Outside(shape, parameter)); } if (strokeAlign == "inside") { return(RectElement.Inside(shape, parameter)); } return(new RectElement { Parameter = parameter, Width = shape.Width, Height = shape.Height }); } if (shape.Type == CircleElement.Name) { if (strokeAlign == "outside") { return(CircleElement.Outside(shape, parameter, shapeR)); } if (strokeAlign == "inside") { return(CircleElement.Inside(shape, parameter, shapeR)); } return(new CircleElement { Parameter = parameter, Cx = shape.Cx, Cy = shape.Cy, R = shapeR.Value }); } if (shape.Type == EllipseElement.Name) { if (strokeAlign == "outside") { return(EllipseElement.Outside(shape, parameter)); } if (strokeAlign == "inside") { return(EllipseElement.Inside(shape, parameter)); } return(new EllipseElement { Parameter = parameter, Cx = shape.Cx, Cy = shape.Cy, Rx = shape.Rx, Ry = shape.Ry }); } throw new NotSupportedException($"Unknown type {shape.Type}"); }