Dashboard/Quik/Typography/FontProvider.cs

108 lines
3.3 KiB
C#

using Quik.Media;
using Quik.Media.Font;
using Quik.PAL;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
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;
public IFontDataBase Database { get; set; }
public IFontFactory FontFactory { get; set; }
private readonly QuikApplication App;
public QFont this[FontFace info]
{
get
{
if (!Fonts.TryGetValue(info, out QFont font))
{
using Stream str = Database?.Open(info);
if (FontFactory.TryOpen(str, out font))
{
Fonts.Add(info, font);
}
else
{
throw new Exception("Font not found.");
}
}
UsedFonts.Add(font);
return font;
}
}
public QFont this[SystemFontFamily family]
{
get
{
return this[Database.GetSystemFontFace(family)];
}
}
public FontProvider(QuikApplication app, in FontRasterizerOptions options)
{
RasterizerOptions = options;
App = app;
Type fdb = Type.GetType("Quik.Media.Defaults.FontDataBaseProvider, Quik.Media.Defaults");
if (fdb != null)
{
PropertyInfo instanceProperty = fdb.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty);
if (instanceProperty != null)
{
Database = (IFontDataBase)instanceProperty.GetValue(null);
}
}
Type ffact = Type.GetType("Quik.Media.Defaults.FreeTypeFontFactory, Quik.Media.Defaults");
if (ffact != null)
{
ConstructorInfo ctor = ffact.GetConstructor(Array.Empty<Type>());
FontFactory = (IFontFactory)ctor.Invoke(null);
}
}
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();
}
}
}
}