diff --git a/CSharpMath.CrossPlatform.slnf b/CSharpMath.CrossPlatform.slnf
index bd27cd96..e596b012 100644
--- a/CSharpMath.CrossPlatform.slnf
+++ b/CSharpMath.CrossPlatform.slnf
@@ -27,6 +27,7 @@
"CSharpMath.Avalonia/CSharpMath.Avalonia.csproj",
"CSharpMath.Avalonia.Example/CSharpMath.Avalonia.Example.csproj",
"CSharpMath.SkiaSharp/CSharpMath.SkiaSharp.csproj",
+ "CSharpMath.VectSharp/CSharpMath.VectSharp.csproj",
"CSharpMath.Forms/CSharpMath.Forms.csproj",
"CSharpMath.Forms.Example/CSharpMath.Forms.Example/CSharpMath.Forms.Example.csproj",
"CSharpMath.Forms.Tests/CSharpMath.Forms.Tests.csproj"
diff --git a/CSharpMath.VectSharp/CSharpMath.VectSharp.csproj b/CSharpMath.VectSharp/CSharpMath.VectSharp.csproj
new file mode 100644
index 00000000..c9ed0e5a
--- /dev/null
+++ b/CSharpMath.VectSharp/CSharpMath.VectSharp.csproj
@@ -0,0 +1,14 @@
+
+
+
+ netstandard2.0
+ The VectSharp front end for CSharpMath.
+ $(PackageTags) vectsharp
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CSharpMath.VectSharp/Extensions.cs b/CSharpMath.VectSharp/Extensions.cs
new file mode 100644
index 00000000..43d79011
--- /dev/null
+++ b/CSharpMath.VectSharp/Extensions.cs
@@ -0,0 +1,35 @@
+// Adapted after https://github.com/verybadcat/CSharpMath/blob/master/CSharpMath.SkiaSharp/Extensions.cs
+
+using System;
+using CSharpMath.Rendering.FrontEnd;
+
+namespace CSharpMath.VectSharp
+{
+ public static class Extensions
+ {
+ internal static global::VectSharp.Colour ToNative(this System.Drawing.Color color)
+ {
+ return global::VectSharp.Colour.FromRgba(color.R, color.G, color.B, color.A);
+ }
+
+ internal static System.Drawing.Color FromNative(this global::VectSharp.Colour colour)
+ {
+ return System.Drawing.Color.FromArgb((int)Math.Round(colour.A * 255), (int)Math.Round(colour.R * 255), (int)Math.Round(colour.G * 255), (int)Math.Round(colour.B * 255));
+ }
+
+ public static global::VectSharp.Page DrawToPage(this Painter painter, float textPainterCanvasWidth = TextPainter.DefaultCanvasWidth, TextAlignment alignment = TextAlignment.TopLeft) where TContent : class
+ {
+ var size = painter.Measure(textPainterCanvasWidth).Size;
+
+ global::VectSharp.Page pag = new global::VectSharp.Page(size.Width, size.Height);
+
+ pag.Graphics.Save();
+
+ painter.Draw(pag, alignment);
+
+ pag.Graphics.Restore();
+
+ return pag;
+ }
+ }
+}
diff --git a/CSharpMath.VectSharp/MathPainter.cs b/CSharpMath.VectSharp/MathPainter.cs
new file mode 100644
index 00000000..174da363
--- /dev/null
+++ b/CSharpMath.VectSharp/MathPainter.cs
@@ -0,0 +1,65 @@
+// Adapted after https://github.com/verybadcat/CSharpMath/blob/master/CSharpMath.SkiaSharp/MathPainter.cs
+
+using System.Drawing;
+using CSharpMath.Rendering.FrontEnd;
+using CSharpMath.Rendering.BackEnd;
+using CSharpMath.Structures;
+using VectSharp;
+
+namespace CSharpMath.VectSharp
+{
+ public class MathPainter : MathPainter
+ {
+ public bool AntiAlias { get; set; } = true;
+ public void Draw(Page canvas, global::VectSharp.Point point) => Draw(canvas, (float)point.X, (float)point.Y);
+ public override Colour UnwrapColor(Color color) => color.ToNative();
+ public override Color WrapColor(Colour color) => color.FromNative();
+ public override ICanvas WrapCanvas(Page canvas) =>
+ new VectSharpCanvas(canvas, AntiAlias);
+ ///
+ /// Ignores the MathList and LaTeX of the provided.
+ /// Repositions the .
+ ///
+ public static void DrawDisplay(MathPainter settings, Display.IDisplay display, Page canvas, PointF position)
+ {
+ DrawDisplay(settings, display, _ => _.Draw(canvas, position));
+ }
+
+ ///
+ /// Ignores the MathList and LaTeX of the provided.
+ /// Repositions the .
+ ///
+ public static void DrawDisplay(MathPainter settings, Display.IDisplay display,
+ Page canvas, global::VectSharp.Point position)
+ {
+ DrawDisplay(settings, display, _ => _.Draw(canvas, position));
+ }
+
+ ///
+ /// Ignores the MathList and LaTeX of the provided.
+ /// Repositions the .
+ ///
+ public static void DrawDisplay(MathPainter settings, Display.IDisplay display, Page canvas, float x, float y)
+ {
+ DrawDisplay(settings, display, _ => _.Draw(canvas, x, y));
+ }
+
+ ///
+ /// Ignores the MathList and LaTeX of the provided.
+ /// Repositions the .
+ ///
+ public static void DrawDisplay(MathPainter settings, Display.IDisplay display, Page canvas, TextAlignment textAlignment = TextAlignment.Center, Thickness padding = default, float offsetX = 0, float offsetY = 0)
+ {
+ DrawDisplay(settings, display, _ => _.Draw(canvas, textAlignment, padding, offsetX, offsetY));
+ }
+
+ private static void DrawDisplay(MathPainter settings, Display.IDisplay display, System.Action draw)
+ {
+ if (display is null) return;
+ var original = (settings.Display, settings._displayChanged);
+ (settings.Display, settings._displayChanged) = (display, false);
+ draw(settings);
+ (settings.Display, settings._displayChanged) = original;
+ }
+ }
+}
diff --git a/CSharpMath.VectSharp/TextPainter.cs b/CSharpMath.VectSharp/TextPainter.cs
new file mode 100644
index 00000000..72c8a0b0
--- /dev/null
+++ b/CSharpMath.VectSharp/TextPainter.cs
@@ -0,0 +1,15 @@
+// Adapted after https://github.com/verybadcat/CSharpMath/blob/master/CSharpMath.SkiaSharp/TextPainter.cs
+
+using System.Drawing;
+using CSharpMath.Rendering.FrontEnd;
+
+namespace CSharpMath.VectSharp
+{
+ public class TextPainter : TextPainter
+ {
+ public override Color WrapColor(global::VectSharp.Colour color) => color.FromNative();
+ public override global::VectSharp.Colour UnwrapColor(Color color) => color.ToNative();
+ public override ICanvas WrapCanvas(global::VectSharp.Page canvas) =>
+ new VectSharpCanvas(canvas, true);
+ }
+}
diff --git a/CSharpMath.VectSharp/VectSharpCanvas.cs b/CSharpMath.VectSharp/VectSharpCanvas.cs
new file mode 100644
index 00000000..ee2842f8
--- /dev/null
+++ b/CSharpMath.VectSharp/VectSharpCanvas.cs
@@ -0,0 +1,53 @@
+// Adapted after https://github.com/verybadcat/CSharpMath/blob/master/CSharpMath.SkiaSharp/SkiaCanvas.cs
+
+using System.Drawing;
+using CSharpMath.Rendering.FrontEnd;
+using VectSharp;
+
+namespace CSharpMath.VectSharp
+{
+ public sealed class VectSharpCanvas : ICanvas
+ {
+ public VectSharpCanvas(Page canvas, bool antiAlias)
+ {
+ Canvas = canvas;
+ this._isAntialias = antiAlias;
+ }
+ public Page Canvas { get; }
+ public float Width => (float)Canvas.Width;
+ public float Height => (float)Canvas.Height;
+ public Color DefaultColor { get; set; }
+ public Color? CurrentColor { get; set; }
+ public PaintStyle CurrentStyle { get; set; }
+
+ private readonly bool _isAntialias;
+
+ // Canvas methods
+ public void StrokeRect(float left, float top, float width, float height)
+ {
+ this.Canvas.Graphics.StrokeRectangle(left, top, width, height, (this.CurrentColor ?? this.DefaultColor).ToNative());
+ }
+
+ public void FillRect(float left, float top, float width, float height)
+ {
+ this.Canvas.Graphics.FillRectangle(left, top, width, height, (this.CurrentColor ?? this.DefaultColor).ToNative());
+ }
+
+ public void DrawLine(float x1, float y1, float x2, float y2, float lineThickness)
+ {
+ if (CurrentStyle == PaintStyle.Fill)
+ {
+ this.Canvas.Graphics.StrokePath(new GraphicsPath().MoveTo(x1, y1).LineTo(x2, y2), (this.CurrentColor ?? this.DefaultColor).ToNative(), lineThickness);
+ }
+ else
+ {
+ this.StrokeLineOutline(x1, y1, x2, y2, lineThickness);
+ }
+ }
+ public void Save() => this.Canvas.Graphics.Save();
+ public void Translate(float dx, float dy) => this.Canvas.Graphics.Translate(dx, dy);
+ public void Scale(float sx, float sy) => this.Canvas.Graphics.Scale(sx, sy);
+ public void Restore() => this.Canvas.Graphics.Restore();
+ public Path StartNewPath() => new VectSharpPath(this);
+ }
+}
diff --git a/CSharpMath.VectSharp/VectSharpPath.cs b/CSharpMath.VectSharp/VectSharpPath.cs
new file mode 100644
index 00000000..cc7da300
--- /dev/null
+++ b/CSharpMath.VectSharp/VectSharpPath.cs
@@ -0,0 +1,39 @@
+// Adapted after https://github.com/verybadcat/CSharpMath/blob/master/CSharpMath.SkiaSharp/SkiaPath.cs
+
+using System.Drawing;
+using VectSharp;
+
+namespace CSharpMath.VectSharp
+{
+ public sealed class VectSharpPath : Rendering.FrontEnd.Path
+ {
+ public VectSharpPath(VectSharpCanvas owner) => _owner = owner;
+ public override Color? Foreground { get; set; }
+ private readonly VectSharpCanvas _owner;
+ private readonly GraphicsPath _path = new GraphicsPath();
+ public override void MoveTo(float x0, float y0) { _path.Close(); _path.MoveTo(x0, y0); }
+ public override void LineTo(float x1, float y1) => _path.LineTo(x1, y1);
+ public override void Curve3(float x1, float y1, float x2, float y2)
+ {
+ _path.QuadraticBezierTo(x1, y1, x2, y2);
+ }
+
+ public override void Curve4(float x1, float y1, float x2, float y2, float x3, float y3)
+ {
+ _path.CubicBezierTo(x1, y1, x2, y2, x3, y3);
+ }
+
+ public override void CloseContour() => _path.Close();
+ public override void Dispose()
+ {
+ if (_owner.CurrentStyle == Rendering.FrontEnd.PaintStyle.Fill)
+ {
+ _owner.Canvas.Graphics.FillPath(this._path, (this.Foreground ?? _owner.CurrentColor ?? _owner.DefaultColor).ToNative());
+ }
+ else
+ {
+ _owner.Canvas.Graphics.StrokePath(this._path, (this.Foreground ?? _owner.CurrentColor ?? _owner.DefaultColor).ToNative());
+ }
+ }
+ }
+}
diff --git a/CSharpMath.sln b/CSharpMath.sln
index b240a067..6eff562c 100644
--- a/CSharpMath.sln
+++ b/CSharpMath.sln
@@ -28,6 +28,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpMath.Ios", "CSharpMat
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpMath.SkiaSharp", "CSharpMath.SkiaSharp\CSharpMath.SkiaSharp.csproj", "{35B4BB5B-2202-436E-9AFE-00997CA2CC65}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpMath.VectSharp", "CSharpMath.VectSharp\CSharpMath.VectSharp.csproj", "{58F936BB-645A-4419-B621-2EC38FF41E34}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpMath.Playground", "CSharpMath.Playground\CSharpMath.Playground.csproj", "{20986A1A-BF57-4EA7-92E1-E88D3C70874B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpMath.Forms", "CSharpMath.Forms\CSharpMath.Forms.csproj", "{9BAD6846-0B1D-4446-BF62-FCF85C6E9A9F}"
@@ -387,6 +389,54 @@ Global
{35B4BB5B-2202-436E-9AFE-00997CA2CC65}.Release|x64.Build.0 = Release|Any CPU
{35B4BB5B-2202-436E-9AFE-00997CA2CC65}.Release|x86.ActiveCfg = Release|Any CPU
{35B4BB5B-2202-436E-9AFE-00997CA2CC65}.Release|x86.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|x64.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Ad-Hoc|x86.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|ARM.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|ARM.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|x64.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|x64.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|x86.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.AppStore|x86.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|ARM.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|x64.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Debug|x86.Build.0 = Debug|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|Any CPU.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|ARM.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|ARM.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|iPhone.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|x64.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|x64.Build.0 = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|x86.ActiveCfg = Release|Any CPU
+ {58F936BB-645A-4419-B621-2EC38FF41E34}.Release|x86.Build.0 = Release|Any CPU
{20986A1A-BF57-4EA7-92E1-E88D3C70874B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{20986A1A-BF57-4EA7-92E1-E88D3C70874B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{20986A1A-BF57-4EA7-92E1-E88D3C70874B}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU