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;
using OpenTK.Graphics; using OpenTK.Graphics;
@ -18,6 +19,8 @@ namespace Dashboard.Drawing.OpenGL
if (bindingsContext != null) if (bindingsContext != null)
GLLoader.LoadBindings(bindingsContext); GLLoader.LoadBindings(bindingsContext);
Typesetter.Backend = BlurgEngine.Global;
} }
public ContextExecutor GetExecutor(IGLContext glContext) public ContextExecutor GetExecutor(IGLContext glContext)

@ -1,10 +1,13 @@
using System.Diagnostics;
using System.Drawing;
using System.Numerics;
using BlurgText; using BlurgText;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using OPENGL = OpenTK.Graphics.OpenGL; using OPENGL = OpenTK.Graphics.OpenGL;
namespace Dashboard.Drawing.OpenGL.Text namespace Dashboard.Drawing.OpenGL.Text
{ {
public class BlurgEngine : IResourceManager, IGLDisposable public class BlurgEngine : IResourceManager, IGLDisposable, ITypeSetter
{ {
public string Name { get; } = "BlurgEngine"; public string Name { get; } = "BlurgEngine";
public Blurg Blurg { get; } public Blurg Blurg { get; }
@ -12,9 +15,16 @@ namespace Dashboard.Drawing.OpenGL.Text
private readonly List<int> _textures = new List<int>(); 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(); SystemFontsEnabled = Blurg.EnableSystemFonts();
} }
@ -24,13 +34,18 @@ namespace Dashboard.Drawing.OpenGL.Text
Dispose(false, true); 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 MeasureStringInternal(InternFont(font), value);
return new DbBlurgFont(font, 12f);
} }
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; string path;
Stream dest; Stream dest;
@ -55,20 +70,50 @@ namespace Dashboard.Drawing.OpenGL.Text
stream.CopyTo(dest); stream.CopyTo(dest);
dest.Dispose(); dest.Dispose();
DbBlurgFont? font = AddFont(path); DbBlurgFont font = (DbBlurgFont)LoadFont(path);
File.Delete(path); File.Delete(path);
return font; 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. // Ignore the stretch argument.
bool italic = slant != FontSlant.Normal; bool italic = font.Slant != FontSlant.Normal;
BlurgFont? font = Blurg.QueryFont(family, new BlurgText.FontWeight((int)weight), italic); BlurgFont? loaded = Blurg.QueryFont(font.Family, new BlurgText.FontWeight((int)font.Weight), italic);
if (font != null) if (loaded != null)
return new DbBlurgFont(font, 12f); return new DbBlurgFont(Blurg, loaded, 12f);
return null; 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) 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() => Dispose(true, true);
public void Dispose(bool safeExit) => Dispose(true, safeExit); 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 class DbBlurgFont : IFont
{ {
public IDrawExtension Kind { get; } = BlurgFontExtension.Instance; public IDrawExtension Kind { get; } = BlurgFontExtension.Instance;
public Blurg Owner { get; }
public BlurgFont Font { get; } public BlurgFont Font { get; }
public float Size { get; } public float Size { get; }
public string Family => Font.FamilyName; public string Family => Font.FamilyName;
@ -12,15 +13,16 @@ namespace Dashboard.Drawing.OpenGL.Text
public FontSlant Slant => Font.Italic ? FontSlant.Italic : FontSlant.Normal; public FontSlant Slant => Font.Italic ? FontSlant.Italic : FontSlant.Normal;
public FontStretch Stretch => FontStretch.Normal; public FontStretch Stretch => FontStretch.Normal;
public DbBlurgFont(BlurgFont font, float size) public DbBlurgFont(Blurg owner, BlurgFont font, float size)
{ {
Owner = owner;
Font = font; Font = font;
Size = size; Size = size;
} }
public DbBlurgFont WithSize(float 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) Anchor anchor = Anchor.Left)
{ {
IDrawController controller = queue.GetController(DbBaseCommands.Instance); 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)); 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) float borderRadius, string text, IFont font, Anchor anchor = Anchor.Left, BorderKind borderKind = BorderKind.Outset)
{ {
IDrawController controller = queue.GetController(DbBaseCommands.Instance); 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) controller.Write(TextExtension.Instance.TextCommand, new TextCommandArgs(font, textBrush, anchor, position, text)
{ {
BorderBrush = borderBrush, BorderBrush = borderBrush,

@ -19,4 +19,34 @@ namespace Dashboard.Drawing
public FontSlant Slant { get; } public FontSlant Slant { get; }
public FontStretch Stretch { 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>(); List<Vector3> points = new List<Vector3>();
IFont font = executor.ResourcePool.GetResourceManager<BlurgEngine>() IFont font = Typesetter.LoadFont("Nimbus Mono", 12f);
.QueryFont("Nimbus Mono", FontWeight._500, FontSlant.Normal, FontStretch.Normal)!
.WithSize(12f);
queue.Text(new sys.Vector3(96, 96, 0), bg, "Hello World!", font); 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); queue.Text(new sys.Vector3(128, 12, 0), bg, "japenis too! uwa ~~~ アホ", font);