166 lines
5.7 KiB
C#
166 lines
5.7 KiB
C#
using System.Diagnostics;
|
|
using System.Numerics;
|
|
using BlurgText;
|
|
using Dashboard.Drawing;
|
|
using Dashboard.Pal;
|
|
|
|
namespace Dashboard.BlurgText
|
|
{
|
|
public interface IBlurgDcExtensionFactory
|
|
{
|
|
public BlurgDcExtension CreateExtension(BlurgTextExtension appExtension, DeviceContext dc);
|
|
}
|
|
|
|
public class BlurgTextExtension(IBlurgDcExtensionFactory dcExtensionFactory) : IApplicationExtension, IFontLoader
|
|
{
|
|
private readonly Blurg _blurg = new Blurg(GlobalTextureAllocation, GlobalTextureUpdate);
|
|
|
|
public Application Context { get; private set; } = null!;
|
|
public string DriverName { get; } = "BlurgText";
|
|
public string DriverVendor { get; } = "Dashbord and BlurgText";
|
|
public Version DriverVersion { get; } = new Version(1, 0);
|
|
public IBlurgDcExtensionFactory DcExtensionFactory { get; } = dcExtensionFactory;
|
|
IContextBase IContextExtensionBase.Context => Context;
|
|
public bool IsDisposed { get; private set; } = false;
|
|
|
|
public void Require(Application context)
|
|
{
|
|
Context = context;
|
|
context.DeviceContextCreated += OnDeviceContextCreated;
|
|
}
|
|
|
|
void IContextExtensionBase.Require(IContextBase context) => Require((Application)context);
|
|
|
|
private void RequireDeviceContextExtension(DeviceContext dc)
|
|
{
|
|
dc.ExtensionPreload<BlurgDcExtension>(() => DcExtensionFactory.CreateExtension(this, dc));
|
|
}
|
|
|
|
private void OnDeviceContextCreated(object? sender, DeviceContext dc)
|
|
{
|
|
RequireDeviceContextExtension(dc);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (IsDisposed)
|
|
return;
|
|
IsDisposed = true;
|
|
|
|
_blurg.Dispose();
|
|
Context.DeviceContextCreated -= OnDeviceContextCreated;
|
|
}
|
|
|
|
private static void GlobalTextureUpdate(IntPtr userdata, IntPtr buffer, int x, int y, int width, int height)
|
|
{
|
|
// Report the user error.
|
|
Debug.WriteLine("Attempt to create or update a texture from the global BlurgText.", "Dashboard/BlurgEngine");
|
|
}
|
|
|
|
private static IntPtr GlobalTextureAllocation(int width, int height)
|
|
{
|
|
Debug.WriteLine("Attempt to create or update a texture from the global BlurgText.", "Dashboard/BlurgEngine");
|
|
return IntPtr.Zero;
|
|
}
|
|
|
|
public IFont Load(FontInfo info)
|
|
{
|
|
BlurgFont? font = _blurg.QueryFont(
|
|
info.Family,
|
|
info.Weight switch
|
|
{
|
|
FontWeight._100 => global::BlurgText.FontWeight.Thin,
|
|
FontWeight._200 => global::BlurgText.FontWeight.ExtraLight,
|
|
FontWeight._300 => global::BlurgText.FontWeight.Light,
|
|
FontWeight._500 => global::BlurgText.FontWeight.Medium,
|
|
FontWeight._600 => global::BlurgText.FontWeight.SemiBold,
|
|
FontWeight._700 => global::BlurgText.FontWeight.Bold,
|
|
FontWeight._800 => global::BlurgText.FontWeight.ExtraBold,
|
|
FontWeight._900 => global::BlurgText.FontWeight.Black,
|
|
_ => global::BlurgText.FontWeight.Regular,
|
|
},
|
|
info.Slant switch
|
|
{
|
|
FontSlant.Oblique or FontSlant.Italic => true,
|
|
_ => false,
|
|
});
|
|
|
|
if (font == null)
|
|
throw new Exception("Font not found.");
|
|
|
|
return new BlurgFontProxy(_blurg, font);
|
|
}
|
|
|
|
public IFont Load(string path)
|
|
{
|
|
BlurgFont? font = _blurg.AddFontFile(path);
|
|
|
|
if (font == null)
|
|
throw new Exception("Font not found.");
|
|
|
|
return new BlurgFontProxy(_blurg, font);
|
|
}
|
|
|
|
public IFont Load(Stream stream)
|
|
{
|
|
string path;
|
|
Stream dest;
|
|
for (int i = 0;; i++)
|
|
{
|
|
path = Path.GetTempFileName();
|
|
try
|
|
{
|
|
dest = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
if (i < 3)
|
|
continue;
|
|
else
|
|
throw new Exception("Could not open a temporary file for writing the font.", ex);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
stream.CopyTo(dest);
|
|
dest.Dispose();
|
|
|
|
return Load(path);
|
|
}
|
|
}
|
|
|
|
public abstract class BlurgDcExtension : IDeviceContextExtension
|
|
{
|
|
public abstract Blurg Blurg { get; }
|
|
public abstract string DriverName { get; }
|
|
public abstract string DriverVendor { get; }
|
|
public abstract Version DriverVersion { get; }
|
|
|
|
public Application Application => Context.Application;
|
|
public DeviceContext Context { get; private set; } = null!;
|
|
|
|
public abstract void DrawBlurgResult(BlurgResult result, Vector3 position);
|
|
|
|
public void DrawBlurgFormattedText(BlurgFormattedText text, Vector3 position, float width = 0f)
|
|
{
|
|
BlurgResult? result = Blurg.BuildFormattedText(text, maxWidth: width);
|
|
if (result == null)
|
|
throw new Exception("Could not build formatted text result.");
|
|
|
|
DrawBlurgResult(result, position);
|
|
}
|
|
|
|
public abstract void Dispose();
|
|
|
|
IContextBase IContextExtensionBase.Context => Context;
|
|
|
|
public void Require(DeviceContext context)
|
|
{
|
|
Context = context;
|
|
}
|
|
|
|
void IContextExtensionBase.Require(IContextBase context) => Require((DeviceContext)context);
|
|
}
|
|
}
|