using System; using System.IO; using System.Linq; using System.Xml; using SBRL.Utilities; namespace MusicBoxConverter { public class Rectangle { public Vector2 Start { get; set; } public Vector2 Size { get; set; } public Rectangle(Vector2 inStart, Vector2 inSize) { Start = inStart; Size = inSize; } } /// /// TODO: Replace this with the (much) better version from the FloatingIslands /// public class SvgWriter { public XmlWriter xml; public string UnitSuffix { get; set; } = ""; public SvgWriter(string outputFilename, string widthspec = "100%", string heightspec = "100%", Rectangle viewBox = null) { xml = XmlWriter.Create( outputFilename, new XmlWriterSettings() { Indent = true } ); xml.WriteStartDocument(); xml.WriteDocType("svg", "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd", null); xml.WriteStartElement("svg", "http://www.w3.org/2000/svg"); xml.WriteAttributeString("version", "1.1"); xml.WriteAttributeString("x", "0"); xml.WriteAttributeString("y", "0"); xml.WriteAttributeString("width", widthspec); xml.WriteAttributeString("height", heightspec); if(viewBox != null) { xml.WriteAttributeString( "viewBox", $"{viewBox.Start.X} {viewBox.Start.Y} {viewBox.Size.X} {viewBox.Size.Y}" ); } } public void Complete() { xml.WriteEndElement(); xml.WriteEndDocument(); xml.Close(); } public void WriteLine(Vector2 start, Vector2 end, string strokeStyle = "darkgreen", float strokeWidth = 3) { xml.WriteStartElement("line"); xml.WriteAttributeString("x1", $"{start.X}{UnitSuffix}"); xml.WriteAttributeString("y1", $"{start.Y}{UnitSuffix}"); xml.WriteAttributeString("x2", $"{end.X}{UnitSuffix}"); xml.WriteAttributeString("y2", $"{end.Y}{UnitSuffix}"); xml.WriteAttributeString("stroke", strokeStyle); xml.WriteAttributeString("stroke-width", strokeWidth.ToString()); xml.WriteEndElement(); } public void WritePolyLine(string strokeStyle, float strokeWidth, params Vector2[] points) { xml.WriteStartElement("polyline"); xml.WriteAttributeString("points", string.Join(" ", points.Select((Vector2 p) => $"{p.X},{p.Y}"))); xml.WriteAttributeString("stroke", strokeStyle); xml.WriteAttributeString("stroke-width", strokeWidth.ToString()); xml.WriteAttributeString("fill", "none"); xml.WriteEndElement(); } /// /// Adds a cross centred on a point. /// /// The centre of the cross. /// The radius of the cross. /// The stroke style to draw with. /// The stroke width to draw with. public void WriteCross(Vector2 centre, Vector2 radius, string strokeStyle = "red", float strokeWidth = 1) { WriteLine( centre.Subtract(new Vector2(radius.X, radius.Y)), centre.Add(new Vector2(radius.X, radius.Y)), strokeStyle, strokeWidth ); WriteLine( centre.Subtract(new Vector2(radius.X, -radius.Y)), centre.Add(new Vector2(radius.X, -radius.Y)), strokeStyle, strokeWidth ); } public void StartScaleTransform(float scale) { xml.WriteStartElement("g"); xml.WriteAttributeString("transform", $"scale({scale})"); } public void EndTransform() { xml.WriteEndElement(); } /*public void WritePath(string pathData, string strokeStyle = "green", int strokeWidth = 3) { xml.WriteStartElement("path"); xml.WriteAttributeString("d", pathData); xml.WriteAttributeString("stroke", strokeStyle); xml.WriteAttributeString("stroke-width", strokeWidth.ToString()); xml.WriteAttributeString("fill", "transparent"); xml.WriteEndElement(); }*/ public void WriteRectangle(Vector2 position, Vector2 size, string strokeStyle = "red", float strokeWidth = 3, bool fillInstead = false) { xml.WriteStartElement("rect"); xml.WriteAttributeString("x", $"{position.X}{UnitSuffix}"); xml.WriteAttributeString("y", $"{position.Y}{UnitSuffix}"); xml.WriteAttributeString("width", $"{size.X}{UnitSuffix}"); xml.WriteAttributeString("height", $"{size.Y}{UnitSuffix}"); if (!fillInstead) { xml.WriteAttributeString("fill", "none"); xml.WriteAttributeString("stroke", strokeStyle); xml.WriteAttributeString("stroke-width", strokeWidth.ToString()); } else xml.WriteAttributeString("fill", strokeStyle); xml.WriteEndElement(); } public void WriteCircle(Vector2 centre, float radius, string fillStyle = "blue") { xml.WriteStartElement("circle"); xml.WriteAttributeString("cx", $"{centre.X}{UnitSuffix}"); xml.WriteAttributeString("cy", $"{centre.Y}{UnitSuffix}"); xml.WriteAttributeString("r", $"{radius}{UnitSuffix}"); xml.WriteAttributeString("fill", fillStyle); xml.WriteEndElement(); } public void WriteText(Vector2 position, string text, float size = 12) { xml.WriteStartElement("text"); xml.WriteAttributeString("x", $"{position.X}{UnitSuffix}"); xml.WriteAttributeString("y", $"{position.Y}{UnitSuffix}"); xml.WriteAttributeString("style", $"font-size: {size}{UnitSuffix}"); xml.WriteValue(text); xml.WriteEndElement(); } } }