Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</PropertyGroup>

<ItemGroup Label="Packaging">
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
<None Include="..\..\README.md" Pack="true" PackagePath="\" Visible="false" />
</ItemGroup>

<PropertyGroup Condition=" '$(MSBuildProjectExtension)' == '.csproj' ">
Expand Down
39 changes: 39 additions & 0 deletions WinFormsApp.Example/Form1.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions WinFormsApp.Example/Form1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using WinFormsMath.Controls;

namespace WinFormsApp.Example;

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var control = new FormulaControl();
Controls.Add(control);

control.Top = 5;
control.Left = 5;
control.Width = Width - 5;
control.Height = Height - 5;
control.FormulaText = @"\sqrt 2";
}
}
16 changes: 16 additions & 0 deletions WinFormsApp.Example/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace WinFormsApp.Example;

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}
15 changes: 15 additions & 0 deletions WinFormsApp.Example/WinFormsApp.Example.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\src\WinFormsMath\WinFormsMath.csproj" />
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions XamlMath.All.sln
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "api", "api", "{3F2FED19-93A
api\XamlMath.Shared.net6.0.verified.cs = api\XamlMath.Shared.net6.0.verified.cs
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsMath", "src\WinFormsMath\WinFormsMath.csproj", "{4236794D-83A5-46B8-8F1C-8777D525DCD9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsApp.Example", "WinFormsApp.Example\WinFormsApp.Example.csproj", "{7AD0440C-A9E8-4153-883C-B595E8B7346F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -124,6 +128,14 @@ Global
{54F77EF7-F918-46F8-A615-56BC0BFE8AAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54F77EF7-F918-46F8-A615-56BC0BFE8AAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54F77EF7-F918-46F8-A615-56BC0BFE8AAB}.Release|Any CPU.Build.0 = Release|Any CPU
{4236794D-83A5-46B8-8F1C-8777D525DCD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4236794D-83A5-46B8-8F1C-8777D525DCD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4236794D-83A5-46B8-8F1C-8777D525DCD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4236794D-83A5-46B8-8F1C-8777D525DCD9}.Release|Any CPU.Build.0 = Release|Any CPU
{7AD0440C-A9E8-4153-883C-B595E8B7346F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AD0440C-A9E8-4153-883C-B595E8B7346F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AD0440C-A9E8-4153-883C-B595E8B7346F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AD0440C-A9E8-4153-883C-B595E8B7346F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
21 changes: 21 additions & 0 deletions src/WinFormsMath/Controls/FormulaControl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using WinFormsMath.Parsers;
using WinFormsMath.Rendering;
using XamlMath.Rendering;

namespace WinFormsMath.Controls;

public class FormulaControl : Control
{
public string FormulaText { get; set; } // TODO: Naming?

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

var texFormula = WinFormsFormulaParser.Instance.Parse(FormulaText);
var environment = WinFormsTeXEnvironment.Create();

var renderer = new WinFormsRenderer(e.Graphics);
texFormula.RenderTo(renderer, environment, 0.0, 0.0);
}
}
5 changes: 5 additions & 0 deletions src/WinFormsMath/Fonts/WinFormsGlyphTypeface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using XamlMath.Fonts;

namespace WinFormsMath.Fonts;

internal record WinFormsGlyphTypeface(Font Font) : IFontTypeface;
30 changes: 30 additions & 0 deletions src/WinFormsMath/Fonts/WinFormsMathFontProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Drawing.Text;
using XamlMath.Fonts;
using XamlMath.Utils;

namespace WinFormsMath.Fonts;

/// <summary>A font provider implementation specifically for the WinFormsMath assembly.</summary>
internal class WinFormsMathFontProvider : IFontProvider
{
private WinFormsMathFontProvider() {}

public static WinFormsMathFontProvider Instance = new();

private const string FontsDirectory = "WinFormsMath.Fonts";

public unsafe IFontTypeface ReadFontFile(string fontFileName)
{
using var resource = typeof(WinFormsMathFontProvider).Assembly.ReadResource($"{FontsDirectory}.{fontFileName}");
using var byteStream = new MemoryStream();
resource.CopyTo(byteStream);
var bytes = byteStream.ToArray();

var c = new PrivateFontCollection(); // TODO: Dispose?
fixed (byte* p = bytes)
c.AddMemoryFont((IntPtr)p, bytes.Length);

var ff = c.Families.Single();
return new WinFormsGlyphTypeface(new Font(ff, 1.0f));
}
}
114 changes: 114 additions & 0 deletions src/WinFormsMath/Fonts/WinFormsSystemFont.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using XamlMath;
using XamlMath.Exceptions;
using XamlMath.Fonts;
using XamlMath.Utils;

namespace WinFormsMath.Fonts;

internal class WinFormsSystemFont : ITeXFont
{
private readonly Lazy<Font> _font;

public WinFormsSystemFont(double size, FontFamily fontFamily)
{
Size = size;
_font = new Lazy<Font>(() => new Font(fontFamily, (float)Size));
}

public bool SupportsMetrics => false;

public double Size { get; }

public ExtensionChar GetExtension(CharInfo charInfo, TexStyle style) =>
throw MethodNotSupported(nameof(GetExtension));

public CharFont? GetLigature(CharFont leftChar, CharFont rightChar) => null;

public CharInfo GetNextLargerCharInfo(CharInfo charInfo, TexStyle style) =>
throw MethodNotSupported(nameof(GetNextLargerCharInfo));

public Result<CharInfo> GetDefaultCharInfo(char character, TexStyle style) =>
Result.Error<CharInfo>(MethodNotSupported(nameof(this.GetDefaultCharInfo)));

public Result<CharInfo> GetCharInfo(char character, string textStyle, TexStyle style)
{
var font = _font.Value;
var metrics = GetFontMetrics(character, font);
return Result.Ok(
new CharInfo(character, new WinFormsGlyphTypeface(font), 1.0, TexFontUtilities.NoFontId, metrics));
}

public Result<CharInfo> GetCharInfo(CharFont charFont, TexStyle style) =>
Result.Error<CharInfo>(MethodNotSupported(nameof(this.GetCharInfo)));

public Result<CharInfo> GetCharInfo(string name, TexStyle style) =>
Result.Error<CharInfo>(MethodNotSupported(nameof(GetCharInfo)));

public double GetKern(CharFont leftChar, CharFont rightChar, TexStyle style) => 0.0;

public double GetQuad(int fontId, TexStyle style) => throw MethodNotSupported(nameof(GetQuad));

public double GetSkew(CharFont charFont, TexStyle style) => throw MethodNotSupported(nameof(GetSkew));

public bool HasSpace(int fontId) => throw MethodNotSupported(nameof(HasSpace));

public bool HasNextLarger(CharInfo charInfo) => throw MethodNotSupported(nameof(HasNextLarger));

public bool IsExtensionChar(CharInfo charInfo) => throw MethodNotSupported(nameof(IsExtensionChar));

public int GetMuFontId() => throw MethodNotSupported(nameof(GetMuFontId));

public double GetXHeight(TexStyle style, int fontId) => throw MethodNotSupported(nameof(GetXHeight));

public double GetSpace(TexStyle style) => throw MethodNotSupported(nameof(GetSpace));

public double GetAxisHeight(TexStyle style) => throw MethodNotSupported(nameof(GetAxisHeight));

public double GetBigOpSpacing1(TexStyle style) => throw MethodNotSupported(nameof(GetBigOpSpacing1));

public double GetBigOpSpacing2(TexStyle style) => throw MethodNotSupported(nameof(GetBigOpSpacing2));

public double GetBigOpSpacing3(TexStyle style) => throw MethodNotSupported(nameof(GetBigOpSpacing3));

public double GetBigOpSpacing4(TexStyle style) => throw MethodNotSupported(nameof(GetBigOpSpacing4));

public double GetBigOpSpacing5(TexStyle style) => throw MethodNotSupported(nameof(GetBigOpSpacing5));

public double GetSub1(TexStyle style) => throw MethodNotSupported(nameof(GetSub1));

public double GetSub2(TexStyle style) => throw MethodNotSupported(nameof(GetSub2));

public double GetSubDrop(TexStyle style) => throw MethodNotSupported(nameof(GetSubDrop));

public double GetSup1(TexStyle style) => throw MethodNotSupported(nameof(GetSup1));

public double GetSup2(TexStyle style) => throw MethodNotSupported(nameof(GetSup2));

public double GetSup3(TexStyle style) => throw MethodNotSupported(nameof(GetSup3));

public double GetSupDrop(TexStyle style) => throw MethodNotSupported(nameof(GetSupDrop));

public double GetNum1(TexStyle style) => throw MethodNotSupported(nameof(GetNum1));

public double GetNum2(TexStyle style) => throw MethodNotSupported(nameof(GetNum2));

public double GetNum3(TexStyle style) => throw MethodNotSupported(nameof(GetNum3));

public double GetDenom1(TexStyle style) => throw MethodNotSupported(nameof(GetDenom1));

public double GetDenom2(TexStyle style) => throw MethodNotSupported(nameof(GetDenom2));

public double GetDefaultLineThickness(TexStyle style) => throw MethodNotSupported(nameof(GetDefaultLineThickness));

private static TexNotSupportedException MethodNotSupported(string callerMethod)
{
return new TexNotSupportedException(
$"Call of method {callerMethod} on {nameof(WinFormsSystemFont)} is not supported");
}

private static TeXFontMetrics GetFontMetrics(char c, Font font)
{
var size = TextRenderer.MeasureText(c.ToString(), font);
return new TeXFontMetrics(size.Width, size.Height, 0.0, size.Width, 1.0);
}
}
22 changes: 22 additions & 0 deletions src/WinFormsMath/Parsers/WinFormsFormulaParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using WinFormsMath.Rendering;
using XamlMath;

namespace WinFormsMath.Parsers;

public static class WinFormsFormulaParser
{
public static TexFormulaParser Instance { get; }
static WinFormsFormulaParser()
{
var predefinedFormulae = LoadPredefinedFormulae();
Instance = new TexFormulaParser(WinFormsBrushFactory.Instance, predefinedFormulae);
}

private static IReadOnlyDictionary<string, Func<SourceSpan, TexFormula?>> LoadPredefinedFormulae()
{
var predefinedFormulaParser = new TexPredefinedFormulaParser(WinFormsBrushFactory.Instance);
var predefinedFormulae = new Dictionary<string, Func<SourceSpan, TexFormula?>>();
predefinedFormulaParser.Parse(predefinedFormulae);
return predefinedFormulae;
}
}
32 changes: 32 additions & 0 deletions src/WinFormsMath/Rendering/WinFormsBrush.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Diagnostics.CodeAnalysis;
using XamlMath.Colors;
using XamlMath.Rendering;

namespace WinFormsMath.Rendering;

public record WinFormsBrush : GenericBrush<Brush>
{
private WinFormsBrush(Brush brush) : base(brush)
{
}

public static WinFormsBrush FromBrush(Brush value) => new(value);
}

public class WinFormsBrushFactory : IBrushFactory
{
public static readonly WinFormsBrushFactory Instance = new();

private WinFormsBrushFactory() {}

public IBrush FromColor(RgbaColor color) =>
new SolidBrush(
Color.FromArgb(color.A, color.R, color.G, color.B)).ToPlatform();
}

public static class WinFormsBrushExtensions
{
public static Brush? ToWinForms(this IBrush? brush) => ((WinFormsBrush?)brush)?.Value;
[return: NotNullIfNotNull(nameof(brush))]
public static IBrush? ToPlatform(this Brush? brush) => brush == null ? null : WinFormsBrush.FromBrush(brush);
}
7 changes: 7 additions & 0 deletions src/WinFormsMath/Rendering/WinFormsRectangleExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace WinFormsMath.Rendering;

internal static class WinFormsRectangleExtensions
{
public static RectangleF ToWinForms(this XamlMath.Rendering.Rectangle rectangle) =>
new((float)rectangle.X, (float)rectangle.Y, (float)rectangle.Width, (float)rectangle.Height);
}
Loading