|
|
|
@ -2,6 +2,7 @@ |
|
|
|
using System.Collections.Concurrent; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Diagnostics.CodeAnalysis; |
|
|
|
using System.Linq; |
|
|
|
using Avalonia.Platform; |
|
|
|
|
|
|
|
namespace Avalonia.Media.Fonts |
|
|
|
@ -9,12 +10,12 @@ namespace Avalonia.Media.Fonts |
|
|
|
internal class SystemFontCollection : FontCollectionBase |
|
|
|
{ |
|
|
|
private readonly FontManager _fontManager; |
|
|
|
private readonly string[] _familyNames; |
|
|
|
private readonly List<string> _familyNames; |
|
|
|
|
|
|
|
public SystemFontCollection(FontManager fontManager) |
|
|
|
{ |
|
|
|
_fontManager = fontManager; |
|
|
|
_familyNames = fontManager.PlatformImpl.GetInstalledFontFamilyNames(); |
|
|
|
_familyNames = fontManager.PlatformImpl.GetInstalledFontFamilyNames().ToList(); |
|
|
|
} |
|
|
|
|
|
|
|
public override Uri Key => FontManager.SystemFontsKey; |
|
|
|
@ -29,7 +30,15 @@ namespace Avalonia.Media.Fonts |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override int Count => _familyNames.Length; |
|
|
|
public override int Count => _familyNames.Count; |
|
|
|
|
|
|
|
public override IEnumerator<FontFamily> GetEnumerator() |
|
|
|
{ |
|
|
|
foreach (var familyName in _familyNames) |
|
|
|
{ |
|
|
|
yield return new FontFamily(familyName); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override bool TryGetGlyphTypeface(string familyName, FontStyle style, FontWeight weight, |
|
|
|
FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface) |
|
|
|
@ -58,11 +67,46 @@ namespace Avalonia.Media.Fonts |
|
|
|
//We initialize the system font collection during construction.
|
|
|
|
} |
|
|
|
|
|
|
|
public override IEnumerator<FontFamily> GetEnumerator() |
|
|
|
public void AddCustomFontSource(Uri source) |
|
|
|
{ |
|
|
|
foreach (var familyName in _familyNames) |
|
|
|
if (source is null) |
|
|
|
{ |
|
|
|
yield return new FontFamily(familyName); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
LoadGlyphTypefaces(_fontManager.PlatformImpl, source); |
|
|
|
} |
|
|
|
|
|
|
|
private void LoadGlyphTypefaces(IFontManagerImpl fontManager, Uri source) |
|
|
|
{ |
|
|
|
var assetLoader = AvaloniaLocator.Current.GetRequiredService<IAssetLoader>(); |
|
|
|
|
|
|
|
var fontAssets = FontFamilyLoader.LoadFontAssets(source); |
|
|
|
|
|
|
|
foreach (var fontAsset in fontAssets) |
|
|
|
{ |
|
|
|
var stream = assetLoader.Open(fontAsset); |
|
|
|
|
|
|
|
if (fontManager.TryCreateGlyphTypeface(stream, out var glyphTypeface)) |
|
|
|
{ |
|
|
|
if (!_glyphTypefaceCache.TryGetValue(glyphTypeface.FamilyName, out var glyphTypefaces)) |
|
|
|
{ |
|
|
|
glyphTypefaces = new ConcurrentDictionary<FontCollectionKey, IGlyphTypeface?>(); |
|
|
|
|
|
|
|
if (_glyphTypefaceCache.TryAdd(glyphTypeface.FamilyName, glyphTypefaces)) |
|
|
|
{ |
|
|
|
//Move the user defined system font to the start of the collection
|
|
|
|
_familyNames.Insert(0, glyphTypeface.FamilyName); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var key = new FontCollectionKey( |
|
|
|
glyphTypeface.Style, |
|
|
|
glyphTypeface.Weight, |
|
|
|
glyphTypeface.Stretch); |
|
|
|
|
|
|
|
glyphTypefaces.TryAdd(key, glyphTypeface); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|