199 lines
6.1 KiB
C#
199 lines
6.1 KiB
C#
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// TODO: Replace this with the (much) better version from the FloatingIslands
|
|
/// </summary>
|
|
public class SvgWriter
|
|
{
|
|
public XmlWriter xml;
|
|
|
|
public string UnitSuffix { get; set; } = "";
|
|
|
|
public float FontSizeRegular { get; set; } = 3;
|
|
|
|
private bool haveWrittenFontStyles = false;
|
|
|
|
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 WriteText(Vector2 pos, string text, string className)
|
|
{
|
|
if (!haveWrittenFontStyles)
|
|
{
|
|
xml.WriteElementString("style", $".regular {{ font: {FontSizeRegular}{UnitSuffix} sans-serif; }}");
|
|
haveWrittenFontStyles = true;
|
|
}
|
|
|
|
xml.WriteStartElement("text");
|
|
xml.WriteAttributeString("x", $"{pos.X}{UnitSuffix}");
|
|
xml.WriteAttributeString("y", $"{pos.Y}{UnitSuffix}");
|
|
xml.WriteAttributeString("class", className);
|
|
xml.WriteString(text);
|
|
xml.WriteEndElement();
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a cross centred on a point.
|
|
/// </summary>
|
|
/// <param name="centre">The centre of the cross.</param>
|
|
/// <param name="radius">The radius of the cross.</param>
|
|
/// <param name="strokeStyle">The stroke style to draw with.</param>
|
|
/// <param name="strokeWidth">The stroke width to draw with.</param>
|
|
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 WritePlus(Vector2 centre, Vector2 radius, string strokeStyle = "red", float strokeWidth = 1)
|
|
{
|
|
WriteLine(
|
|
centre.Subtract(new Vector2(0, radius.Y)),
|
|
centre.Add(new Vector2(0, radius.Y)),
|
|
strokeStyle,
|
|
strokeWidth
|
|
);
|
|
WriteLine(
|
|
centre.Subtract(new Vector2(radius.X, 0)),
|
|
centre.Add(new Vector2(radius.X, 0)),
|
|
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();
|
|
}
|
|
}
|
|
}
|