using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Text; using System.Linq; namespace FastReport { /// /// Contains font management methods and properties. /// public static partial class FontManager { // NOT THREAD SAFE! private static PrivateFontCollection PrivateFontCollection { get; } = new PrivateFontCollection(); // NOT THREAD SAFE! // Do not update PrivateFontCollection at realtime, you must update property value then dispose previous. private static PrivateFontCollection TemporaryFontCollection { get; set; } = null; private static InstalledFontCollection InstalledFontCollection { get; } = new InstalledFontCollection(); private static List SubstituteFonts { get; } = new List(); /// /// Gets all installed font families. /// /// /// This method enumerates all font collections (PrivateFontCollection, TemporaryFontCollection, InstalledFontCollection) /// and sorts the result. /// public static FontFamily[] AllFamilies { get { var families = new List(); families.AddRange(InstalledFontCollection.Families); families.AddRange(PrivateFontCollection.Families); if (TemporaryFontCollection != null) { families.AddRange(TemporaryFontCollection.Families); } families.Sort((x, y) => x.Name.CompareTo(y.Name)); return families.ToArray(); } } /// /// Adds a new substitute font item. /// /// The original font name, e.g. "Arial" /// The alternatives list, e.g. "Ubuntu Sans", "Liberation Sans", "Helvetica" /// /// Substitute font replaces the original font if it is not present on a machine. /// For example, you may define "Helvetica Neue" substitute for "Arial". /// public static void AddSubstituteFont(string originalFontName, params string[] substituteFonts) { SubstituteFonts.Add(new FontSubstitute(originalFontName, substituteFonts)); } /// /// Removes substitute fonts for the given font. /// /// The original font name, e.g. "Arial" public static void RemoveSubstituteFont(string originalFontName) { for (int i = 0; i < SubstituteFonts.Count; i++) { if (SubstituteFonts[i].Name == originalFontName) { SubstituteFonts.RemoveAt(i); i--; } } } /// /// Clears all substitute fonts. /// public static void ClearSubstituteFonts() { SubstituteFonts.Clear(); } /// /// Finds a FontFamily by its name in specified font collections. /// /// The family name, e.g. "Arial". /// Search scope. /// The FontFamily instance if found; otherwise null. private static FontFamily FindFontFamily(string name, SearchScope searchScope = SearchScope.All) { FontFamily family = null; if ((searchScope & SearchScope.Temporary) != 0) { family = Find(TemporaryFontCollection); } if ((searchScope & SearchScope.Private) != 0) { family ??= Find(PrivateFontCollection); } if ((searchScope & SearchScope.Installed) != 0) { family ??= Find(InstalledFontCollection); } return family; FontFamily Find(FontCollection collection) => collection?.Families.Where(f => f.Name.Equals(name, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); } /// /// Finds a FontFamily by its name. /// /// The family name, e.g. "Arial". /// The FontFamily instance if found; otherwise default FontFamily.GenericSansSerif. internal static FontFamily GetFontFamilyOrDefault(string name) { var fontFamily = FindFontFamily(name); if (fontFamily == null) { // try to substitute foreach (var item in SubstituteFonts) { if (item.Name == name) { // may be null! fontFamily = item.SubstituteFamily; break; } } } // return default if not found return fontFamily ?? FontFamily.GenericSansSerif; } } }