Patch in BlurgText upstream as well.

This commit is contained in:
H. Utku Maden 2025-01-23 22:00:58 +03:00
parent b1aadae0f2
commit ef860f39bf
7 changed files with 222 additions and 21 deletions

@ -1,3 +1,4 @@
using Dashboard.Drawing.OpenGL.Text;
using OpenTK;
using OpenTK.Graphics;
@ -18,6 +19,8 @@ namespace Dashboard.Drawing.OpenGL
if (bindingsContext != null)
GLLoader.LoadBindings(bindingsContext);
Typesetter.Backend = BlurgEngine.Global;
}
public ContextExecutor GetExecutor(IGLContext glContext)

@ -1,10 +1,13 @@
using System.Diagnostics;
using System.Drawing;
using System.Numerics;
using BlurgText;
using OpenTK.Graphics.OpenGL;
using OPENGL = OpenTK.Graphics.OpenGL;
namespace Dashboard.Drawing.OpenGL.Text
{
public class BlurgEngine : IResourceManager, IGLDisposable
public class BlurgEngine : IResourceManager, IGLDisposable, ITypeSetter
{
public string Name { get; } = "BlurgEngine";
public Blurg Blurg { get; }
@ -12,9 +15,16 @@ namespace Dashboard.Drawing.OpenGL.Text
private readonly List<int> _textures = new List<int>();
public BlurgEngine()
public BlurgEngine() : this(false)
{
Blurg = new Blurg(AllocateTexture, UpdateTexture);
}
private BlurgEngine(bool global)
{
if (global)
Blurg = new Blurg(AllocateTextureGlobal, UpdateTextureGlobal);
else
Blurg = new Blurg(AllocateTexture, UpdateTexture);
SystemFontsEnabled = Blurg.EnableSystemFonts();
}
@ -24,13 +34,18 @@ namespace Dashboard.Drawing.OpenGL.Text
Dispose(false, true);
}
public DbBlurgFont AddFont(string path)
public SizeF MeasureString(IFont font, string value)
{
BlurgFont? font = Blurg.AddFontFile(path) ?? throw new Exception("Failed to load the font file.");
return new DbBlurgFont(font, 12f);
return MeasureStringInternal(InternFont(font), value);
}
public DbBlurgFont AddFont(Stream stream)
private SizeF MeasureStringInternal(DbBlurgFont font, string value)
{
Vector2 v = Blurg.MeasureString(font.Font, font.Size, value);
return new SizeF(v.X, v.Y);
}
public IFont LoadFont(Stream stream)
{
string path;
Stream dest;
@ -55,20 +70,50 @@ namespace Dashboard.Drawing.OpenGL.Text
stream.CopyTo(dest);
dest.Dispose();
DbBlurgFont? font = AddFont(path);
DbBlurgFont font = (DbBlurgFont)LoadFont(path);
File.Delete(path);
return font;
}
public DbBlurgFont? QueryFont(string family, FontWeight weight, FontSlant slant, FontStretch stretch)
public IFont LoadFont(string path)
{
BlurgFont? font = Blurg.AddFontFile(path) ?? throw new Exception("Failed to load the font file.");
return new DbBlurgFont(Blurg, font, 12f);
}
public IFont LoadFont(NamedFont font)
{
// Ignore the stretch argument.
bool italic = slant != FontSlant.Normal;
BlurgFont? font = Blurg.QueryFont(family, new BlurgText.FontWeight((int)weight), italic);
bool italic = font.Slant != FontSlant.Normal;
BlurgFont? loaded = Blurg.QueryFont(font.Family, new BlurgText.FontWeight((int)font.Weight), italic);
if (font != null)
return new DbBlurgFont(font, 12f);
return null;
if (loaded != null)
return new DbBlurgFont(Blurg, loaded, 12f);
else
throw new Exception("Font not found.");
}
private DbBlurgFont InternFont(IFont font)
{
if (font is NamedFont named)
{
return (DbBlurgFont)LoadFont(named);
}
else if (font is DbBlurgFont dblurg)
{
if (dblurg.Owner != Blurg)
{
throw new Exception();
}
else
{
return dblurg;
}
}
else
{
throw new Exception("Unsupported font resource.");
}
}
private void UpdateTexture(IntPtr texture, IntPtr buffer, int x, int y, int width, int height)
@ -122,5 +167,22 @@ namespace Dashboard.Drawing.OpenGL.Text
public void Dispose() => Dispose(true, true);
public void Dispose(bool safeExit) => Dispose(true, safeExit);
/// <summary>
/// The global Blurg engine implements the needed methods for command queues to work.
/// </summary>
public static BlurgEngine Global { get; } = new BlurgEngine(true);
private static void UpdateTextureGlobal(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 BlurgEngine.", "Dashboard/BlurgEngine");
}
private static IntPtr AllocateTextureGlobal(int width, int height)
{
Debug.WriteLine("Attempt to create or update a texture from the global BlurgEngine.", "Dashboard/BlurgEngine");
return IntPtr.Zero;
}
}
}

@ -5,6 +5,7 @@ namespace Dashboard.Drawing.OpenGL.Text
public class DbBlurgFont : IFont
{
public IDrawExtension Kind { get; } = BlurgFontExtension.Instance;
public Blurg Owner { get; }
public BlurgFont Font { get; }
public float Size { get; }
public string Family => Font.FamilyName;
@ -12,15 +13,16 @@ namespace Dashboard.Drawing.OpenGL.Text
public FontSlant Slant => Font.Italic ? FontSlant.Italic : FontSlant.Normal;
public FontStretch Stretch => FontStretch.Normal;
public DbBlurgFont(BlurgFont font, float size)
public DbBlurgFont(Blurg owner, BlurgFont font, float size)
{
Owner = owner;
Font = font;
Size = size;
}
public DbBlurgFont WithSize(float size)
{
return new DbBlurgFont(Font, size);
return new DbBlurgFont(Owner, Font, size);
}
}
}

@ -119,7 +119,8 @@ namespace Dashboard.Drawing
Anchor anchor = Anchor.Left)
{
IDrawController controller = queue.GetController(DbBaseCommands.Instance);
controller.EnsureBounds(new Box2d(position.X, position.Y, position.X, position.Y), position.Z);
SizeF size = Typesetter.MeasureString(font, text);
controller.EnsureBounds(new Box2d(position.X, position.Y, position.X + size.Width, position.Y + size.Height), position.Z);
controller.Write(TextExtension.Instance.TextCommand, new TextCommandArgs(font, brush, anchor, position, text));
}
@ -127,7 +128,8 @@ namespace Dashboard.Drawing
float borderRadius, string text, IFont font, Anchor anchor = Anchor.Left, BorderKind borderKind = BorderKind.Outset)
{
IDrawController controller = queue.GetController(DbBaseCommands.Instance);
controller.EnsureBounds(new Box2d(position.X, position.Y, position.X, position.Y), position.Z);
SizeF size = Typesetter.MeasureString(font, text);
controller.EnsureBounds(new Box2d(position.X, position.Y, position.X + size.Width, position.Y + size.Height), position.Z);
controller.Write(TextExtension.Instance.TextCommand, new TextCommandArgs(font, textBrush, anchor, position, text)
{
BorderBrush = borderBrush,

@ -19,4 +19,34 @@ namespace Dashboard.Drawing
public FontSlant Slant { get; }
public FontStretch Stretch { get; }
}
public struct NamedFont : IFont
{
public IDrawExtension Kind { get; } = Instance;
public string Family { get; }
public float Size { get; }
public FontWeight Weight { get; }
public FontSlant Slant { get; }
public FontStretch Stretch { get; }
public NamedFont(string family, float size, FontWeight weight = FontWeight.Normal,
FontSlant slant = FontSlant.Normal, FontStretch stretch = FontStretch.Normal)
{
Family = family;
Size = size;
Weight = weight;
Slant = slant;
Stretch = Stretch;
}
private static readonly IDrawExtension Instance = new Extension();
private class Extension : DrawExtension
{
public Extension() : base("DB_Font_Named", [FontExtension.Instance])
{
}
}
}
}

@ -0,0 +1,104 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.IO;
using System.Reflection.PortableExecutable;
namespace Dashboard.Drawing
{
/// <summary>
/// Interface for registered typesetters.
/// </summary>
public interface ITypeSetter
{
/// <summary>
/// Name of the typesetter.
/// </summary>
string Name { get; }
SizeF MeasureString(IFont font, string value);
IFont LoadFont(Stream stream);
IFont LoadFont(string path);
IFont LoadFont(NamedFont font);
}
/// <summary>
/// Class for typesetting related functions.
/// </summary>
public static class Typesetter
{
/// <summary>
/// The typesetting backend for this instance.
/// </summary>
public static ITypeSetter Backend { get; set; } = new UndefinedTypeSetter();
public static string Name => Backend.Name;
public static SizeF MeasureString(IFont font, string value)
{
return Backend.MeasureString(font, value);
}
public static IFont LoadFont(Stream stream)
{
return Backend.LoadFont(stream);
}
public static IFont LoadFont(string path)
{
return Backend.LoadFont(path);
}
public static IFont LoadFont(FileInfo file)
{
return Backend.LoadFont(file.FullName);
}
public static IFont LoadFont(NamedFont font)
{
return Backend.LoadFont(font);
}
public static IFont LoadFont(string family, float size, FontWeight weight = FontWeight.Normal,
FontSlant slant = FontSlant.Normal, FontStretch stretch = FontStretch.Normal)
{
return LoadFont(new NamedFont(family, size, weight, slant, stretch));
}
private class UndefinedTypeSetter : ITypeSetter
{
public string Name { get; } = "Undefined";
[DoesNotReturn]
private void Except()
{
throw new InvalidOperationException("No typesetting backend is loaded.");
}
public SizeF MeasureString(IFont font, string value)
{
Except();
return default;
}
public IFont LoadFont(Stream stream)
{
Except();
return default;
}
public IFont LoadFont(string path)
{
Except();
return default;
}
public IFont LoadFont(NamedFont font)
{
Except();
return default;
}
}
}
}

@ -98,9 +98,7 @@ TK.Window.SetMode(wnd, WindowMode.Normal);
List<Vector3> points = new List<Vector3>();
IFont font = executor.ResourcePool.GetResourceManager<BlurgEngine>()
.QueryFont("Nimbus Mono", FontWeight._500, FontSlant.Normal, FontStretch.Normal)!
.WithSize(12f);
IFont font = Typesetter.LoadFont("Nimbus Mono", 12f);
queue.Text(new sys.Vector3(96, 96, 0), bg, "Hello World!", font);
queue.Text(new sys.Vector3(128, 12, 0), bg, "japenis too! uwa ~~~ アホ", font);