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