127 lines
4.5 KiB
C#
127 lines
4.5 KiB
C#
using BlurgText;
|
|
using OpenTK.Graphics.OpenGL;
|
|
using OPENGL = OpenTK.Graphics.OpenGL;
|
|
|
|
namespace Dashboard.Drawing.OpenGL.Text
|
|
{
|
|
public class BlurgEngine : IResourceManager, IGLDisposable
|
|
{
|
|
public string Name { get; } = "BlurgEngine";
|
|
public Blurg Blurg { get; }
|
|
public bool SystemFontsEnabled { get; }
|
|
|
|
private readonly List<int> _textures = new List<int>();
|
|
|
|
public BlurgEngine()
|
|
{
|
|
Blurg = new Blurg(AllocateTexture, UpdateTexture);
|
|
|
|
SystemFontsEnabled = Blurg.EnableSystemFonts();
|
|
}
|
|
|
|
~BlurgEngine()
|
|
{
|
|
Dispose(false, true);
|
|
}
|
|
|
|
public DbBlurgFont AddFont(string path)
|
|
{
|
|
BlurgFont? font = Blurg.AddFontFile(path) ?? throw new Exception("Failed to load the font file.");
|
|
return new DbBlurgFont(font, 12f);
|
|
}
|
|
|
|
public DbBlurgFont AddFont(Stream stream)
|
|
{
|
|
string path;
|
|
Stream dest;
|
|
for (int i = 0;; i++)
|
|
{
|
|
path = Path.GetTempFileName();
|
|
try
|
|
{
|
|
dest = File.Open(path, FileMode.CreateNew, 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();
|
|
|
|
DbBlurgFont? font = AddFont(path);
|
|
File.Delete(path);
|
|
return font;
|
|
}
|
|
|
|
public DbBlurgFont? QueryFont(string family, FontWeight weight, FontSlant slant, FontStretch stretch)
|
|
{
|
|
// Ignore the stretch argument.
|
|
bool italic = slant != FontSlant.Normal;
|
|
BlurgFont? font = Blurg.QueryFont(family, new BlurgText.FontWeight((int)weight), italic);
|
|
|
|
if (font != null)
|
|
return new DbBlurgFont(font, 12f);
|
|
return null;
|
|
}
|
|
|
|
private void UpdateTexture(IntPtr texture, IntPtr buffer, int x, int y, int width, int height)
|
|
{
|
|
GL.BindTexture(TextureTarget.Texture2d, (int)texture);
|
|
GL.TexSubImage2D(TextureTarget.Texture2d, 0, x, y, width, height, OPENGL.PixelFormat.Rgba, PixelType.UnsignedByte, buffer);
|
|
// GL.TexSubImage2D(TextureTarget.Texture2d, 0, x, y, width, height, OPENGL.PixelFormat.Red, PixelType.Byte, buffer);
|
|
}
|
|
|
|
private IntPtr AllocateTexture(int width, int height)
|
|
{
|
|
int texture = GL.GenTexture();
|
|
|
|
GL.BindTexture(TextureTarget.Texture2d, texture);
|
|
GL.TexImage2D(TextureTarget.Texture2d, 0, InternalFormat.Rgba, width, height, 0, OPENGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
|
|
// GL.TexImage2D(TextureTarget.Texture2d, 0, InternalFormat.R8, width, height, 0, OPENGL.PixelFormat.Red, PixelType.Byte, IntPtr.Zero);
|
|
|
|
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
|
|
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
|
// GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleR, (int)TextureSwizzle.One);
|
|
// GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleG, (int)TextureSwizzle.One);
|
|
// GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleB, (int)TextureSwizzle.One);
|
|
// GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleA, (int)TextureSwizzle.Red);
|
|
|
|
_textures.Add(texture);
|
|
|
|
return texture;
|
|
}
|
|
|
|
private bool _isDisposed = false;
|
|
|
|
private void Dispose(bool disposing, bool safeExit)
|
|
{
|
|
if (_isDisposed)
|
|
return;
|
|
_isDisposed = true;
|
|
|
|
if (disposing)
|
|
{
|
|
Blurg.Dispose();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
if (safeExit)
|
|
{
|
|
foreach (int texture in _textures)
|
|
ContextCollector.Global.DeleteTexture(texture);
|
|
}
|
|
}
|
|
|
|
public void Dispose() => Dispose(true, true);
|
|
|
|
public void Dispose(bool safeExit) => Dispose(true, safeExit);
|
|
}
|
|
}
|