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
{
///
/// The font provider is a caching object that provides fonts for typesetting classes.
///
public class FontProvider : IDisposable
{
private Dictionary Fonts { get; } = new Dictionary();
private HashSet UsedFonts { get; } = new HashSet();
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) ?? throw new Exception("Font could not be found.");
if (FontFactory?.TryOpen(str, out font) ?? false)
{
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) ?? throw new Exception("No font database.")];
}
}
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());
FontFactory = (IFontFactory?)ctor?.Invoke(null);
}
}
public FontProvider(QuikApplication app)
: this(app, FontRasterizerOptions.Default)
{
}
///
/// Tracks the use of fonts used by this typesetter and removes any that haven't been referenced since the last cycle.
///
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();
}
}
}
}