Dashboard/Quik/Typography/FontProvider.cs

109 lines
3.4 KiB
C#
Raw Normal View History

2024-05-15 22:17:01 +02:00
using Quik.Media;
using Quik.Media.Font;
2024-05-27 20:49:25 +02:00
using Quik.PAL;
2024-05-15 22:17:01 +02:00
using System;
using System.Collections.Generic;
2024-05-27 20:49:25 +02:00
using System.IO;
using System.Reflection;
2024-05-15 22:17:01 +02:00
namespace Quik.Typography
{
/// <summary>
/// The font provider is a caching object that provides fonts for typesetting classes.
/// </summary>
public class FontProvider : IDisposable
{
private Dictionary<FontFace, QFont> Fonts { get; } = new Dictionary<FontFace, QFont>();
private HashSet<QFont> UsedFonts { get; } = new HashSet<QFont>();
public readonly FontRasterizerOptions RasterizerOptions;
2024-06-09 21:54:33 +02:00
public IFontDataBase? Database { get; set; }
public IFontFactory? FontFactory { get; set; }
2024-05-15 22:17:01 +02:00
private readonly QuikApplication App;
public QFont this[FontFace info]
{
get
{
2024-06-09 21:54:33 +02:00
if (!Fonts.TryGetValue(info, out QFont? font))
2024-05-15 22:17:01 +02:00
{
2024-06-09 21:54:33 +02:00
using Stream str = Database?.Open(info) ?? throw new Exception("Font could not be found.");
if (FontFactory?.TryOpen(str, out font) ?? false)
2024-05-27 20:49:25 +02:00
{
Fonts.Add(info, font);
}
else
{
throw new Exception("Font not found.");
}
2024-05-15 22:17:01 +02:00
}
UsedFonts.Add(font);
return font;
}
}
2024-05-27 20:49:25 +02:00
public QFont this[SystemFontFamily family]
{
get
{
2024-06-09 21:54:33 +02:00
return this[Database?.GetSystemFontFace(family) ?? throw new Exception("No font database.")];
2024-05-27 20:49:25 +02:00
}
}
2024-05-15 22:17:01 +02:00
public FontProvider(QuikApplication app, in FontRasterizerOptions options)
{
RasterizerOptions = options;
App = app;
2024-05-27 20:49:25 +02:00
2024-06-09 21:54:33 +02:00
Type? fdb = Type.GetType("Quik.Media.Defaults.FontDataBaseProvider, Quik.Media.Defaults");
2024-05-27 20:49:25 +02:00
if (fdb != null)
{
2024-06-09 21:54:33 +02:00
PropertyInfo? instanceProperty = fdb.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty);
2024-05-27 20:49:25 +02:00
if (instanceProperty != null)
{
2024-06-09 21:54:33 +02:00
Database = (IFontDataBase)instanceProperty.GetValue(null)!;
2024-05-27 20:49:25 +02:00
}
}
2024-06-09 21:54:33 +02:00
Type? ffact = Type.GetType("Quik.Media.Defaults.FreeTypeFontFactory, Quik.Media.Defaults");
2024-05-27 20:49:25 +02:00
if (ffact != null)
{
2024-06-09 21:54:33 +02:00
ConstructorInfo? ctor = ffact.GetConstructor(Array.Empty<Type>());
FontFactory = (IFontFactory?)ctor?.Invoke(null);
2024-05-27 20:49:25 +02:00
}
2024-05-15 22:17:01 +02:00
}
public FontProvider(QuikApplication app)
: this(app, FontRasterizerOptions.Default)
{
}
/// <summary>
/// Tracks the use of fonts used by this typesetter and removes any that haven't been referenced since the last cycle.
/// </summary>
public void Collect()
{
// foreach (FontJar jar in Fonts.Values.ToArray())
// {
// if (!UsedFonts.Contains(jar))
// {
// Fonts.Remove(jar.Info);
// }
// }
// UsedFonts.Clear();
}
private bool isDisposed = false;
public void Dispose()
{
if (isDisposed) return;
isDisposed = true;
foreach (QFont font in Fonts.Values)
{
font.Dispose();
}
}
}
}