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(); } } } }