using System.Collections.Generic; using System.IO; using System.Linq; namespace Cryville.Common.Font { public abstract class FontManager { public IReadOnlyDictionary> MapFullNameToTypeface { get; private set; } public IReadOnlyDictionary> MapNameToTypefaces { get; private set; } public FontManager() { var map1 = new Dictionary>(); var map2 = new Dictionary>(); foreach (var f in EnumerateAllTypefaces()) { List set1; if (!map1.TryGetValue(f.FullName, out set1)) { map1.Add(f.FullName, set1 = new List()); } set1.Add(f); List set2; if (!map2.TryGetValue(f.FamilyName, out set2)) { map2.Add(f.FamilyName, set2 = new List()); } set2.Add(f); } MapFullNameToTypeface = map1.ToDictionary(i => i.Key, i => (IReadOnlyCollection)i.Value); MapNameToTypefaces = map2.ToDictionary(i => i.Key, i => (IReadOnlyCollection)i.Value); } protected abstract IEnumerable EnumerateAllTypefaces(); protected static IEnumerable ScanDirectoryForTypefaces(string dir) { foreach (var f in new DirectoryInfo(dir).EnumerateFiles()) { FontFile file; try { file = FontFile.Create(f); } catch (InvalidDataException) { continue; } if (file == null) continue; var enumerator = file.GetEnumerator(); while (enumerator.MoveNext()) { Typeface ret; try { ret = enumerator.Current; } catch (InvalidDataException) { continue; } yield return ret; } file.Close(); } } } public class FontManagerAndroid : FontManager { protected override IEnumerable EnumerateAllTypefaces() { return ScanDirectoryForTypefaces("/system/fonts"); } } public class FontManagerWindows : FontManager { protected override IEnumerable EnumerateAllTypefaces() { return ScanDirectoryForTypefaces("C:/Windows/Fonts"); } } }