|
|
|
@ -2,15 +2,15 @@ |
|
|
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Collections.Concurrent; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.ObjectModel; |
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
namespace Avalonia.Media |
|
|
|
{ |
|
|
|
public class FontFamily |
|
|
|
{ |
|
|
|
private IFontFamily _loadedFamily; |
|
|
|
|
|
|
|
public FontFamily(string familyName) : this(familyName, null) { } |
|
|
|
|
|
|
|
public FontFamily(string familyName, Uri baseUri) |
|
|
|
@ -25,30 +25,20 @@ namespace Avalonia.Media |
|
|
|
public Uri BaseUri => FontFamilyKey.BaseUri; |
|
|
|
|
|
|
|
internal FontFamilyKey FontFamilyKey { get; } |
|
|
|
|
|
|
|
internal IFontFamily LoadedFamily => _loadedFamily ?? (_loadedFamily = AvaloniaLocator.Current |
|
|
|
.GetService<IFontFamilyLoader>() |
|
|
|
.LoadFontFamily(FontFamilyKey)); |
|
|
|
|
|
|
|
public IEnumerable<FamilyTypeface> AvailableTypefaces => LoadedFamily.SupportedTypefaces; |
|
|
|
} |
|
|
|
|
|
|
|
public class FamilyTypeface |
|
|
|
{ |
|
|
|
public FamilyTypeface() |
|
|
|
{ |
|
|
|
FontStyle = FontStyle.Normal; |
|
|
|
FontWeight = FontWeight.Normal; |
|
|
|
} |
|
|
|
|
|
|
|
public FamilyTypeface(Typeface typeface) |
|
|
|
public FamilyTypeface(Uri resourceUri = null, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) |
|
|
|
{ |
|
|
|
FontStyle = typeface.Style; |
|
|
|
FontWeight = typeface.Weight; |
|
|
|
ResourceUri = resourceUri; |
|
|
|
FontStyle = fontStyle; |
|
|
|
FontWeight = fontWeight; |
|
|
|
} |
|
|
|
|
|
|
|
public FontStyle FontStyle { get; } |
|
|
|
public Uri ResourceUri { get; } |
|
|
|
public FontWeight FontWeight { get; } |
|
|
|
public FontStyle FontStyle { get; } |
|
|
|
} |
|
|
|
|
|
|
|
public class FontFamilyKey |
|
|
|
@ -64,39 +54,118 @@ namespace Avalonia.Media |
|
|
|
public string FriendlyName { get; } |
|
|
|
|
|
|
|
public Uri BaseUri { get; } |
|
|
|
} |
|
|
|
|
|
|
|
internal interface IFontFamily |
|
|
|
{ |
|
|
|
IEnumerable<FamilyTypeface> SupportedTypefaces { get; } |
|
|
|
public override int GetHashCode() |
|
|
|
{ |
|
|
|
unchecked |
|
|
|
{ |
|
|
|
var hash = (int)2166136261; |
|
|
|
|
|
|
|
if (FriendlyName != null) |
|
|
|
{ |
|
|
|
hash = (hash * 16777619) ^ FriendlyName.GetHashCode(); |
|
|
|
} |
|
|
|
|
|
|
|
if (BaseUri != null) |
|
|
|
{ |
|
|
|
hash = (hash * 16777619) ^ BaseUri.GetHashCode(); |
|
|
|
} |
|
|
|
|
|
|
|
return hash; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override bool Equals(object obj) |
|
|
|
{ |
|
|
|
if (!(obj is FontFamilyKey other)) return false; |
|
|
|
|
|
|
|
if (FriendlyName != other.FriendlyName) return false; |
|
|
|
|
|
|
|
if (BaseUri != other.BaseUri) return false; |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal class SystemFont : IFontFamily |
|
|
|
public class FamilyTypefaceKey |
|
|
|
{ |
|
|
|
public SystemFont() : this(new List<FamilyTypeface> { new FamilyTypeface() }) { } |
|
|
|
public FamilyTypefaceKey(FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) |
|
|
|
{ |
|
|
|
FontWeight = fontWeight; |
|
|
|
FontStyle = fontStyle; |
|
|
|
} |
|
|
|
|
|
|
|
public FontWeight FontWeight { get; } |
|
|
|
|
|
|
|
public FontStyle FontStyle { get; } |
|
|
|
|
|
|
|
public SystemFont(IEnumerable<FamilyTypeface> supportedTypefaces) |
|
|
|
public override int GetHashCode() |
|
|
|
{ |
|
|
|
SupportedTypefaces = new ReadOnlyCollection<FamilyTypeface>(new List<FamilyTypeface>(supportedTypefaces)); |
|
|
|
unchecked |
|
|
|
{ |
|
|
|
var hash = (int)2166136261; |
|
|
|
|
|
|
|
hash = (hash * 16777619) ^ FontWeight.GetHashCode(); |
|
|
|
|
|
|
|
hash = (hash * 16777619) ^ FontStyle.GetHashCode(); |
|
|
|
|
|
|
|
return hash; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public IEnumerable<FamilyTypeface> SupportedTypefaces { get; } |
|
|
|
public override bool Equals(object obj) |
|
|
|
{ |
|
|
|
if (!(obj is FamilyTypefaceKey other)) return false; |
|
|
|
|
|
|
|
if (FontWeight != other.FontWeight) return false; |
|
|
|
|
|
|
|
if (FontStyle != other.FontStyle) return false; |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal class CustomFont : IFontFamily |
|
|
|
public class CachedFontFamily |
|
|
|
{ |
|
|
|
public CustomFont() : this(new List<FamilyTypeface> { new FamilyTypeface() }) { } |
|
|
|
private readonly ConcurrentDictionary<FamilyTypefaceKey, FamilyTypeface> _typefaces = |
|
|
|
new ConcurrentDictionary<FamilyTypefaceKey, FamilyTypeface>(); |
|
|
|
|
|
|
|
public IEnumerable<FamilyTypeface> SupportedTypefaces => _typefaces.Values; |
|
|
|
|
|
|
|
public bool TryGetFamilyTypeface(out FamilyTypeface typeface, FontWeight fontWeight = FontWeight.Normal, |
|
|
|
FontStyle fontStyle = FontStyle.Normal) |
|
|
|
{ |
|
|
|
return _typefaces.TryGetValue(new FamilyTypefaceKey(fontWeight, fontStyle), out typeface); |
|
|
|
} |
|
|
|
|
|
|
|
public CustomFont(IEnumerable<FamilyTypeface> supportedTypefaces) |
|
|
|
public FamilyTypeface GetOrAddFamilyTypeface(Uri resourceUri, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) |
|
|
|
{ |
|
|
|
SupportedTypefaces = new ReadOnlyCollection<FamilyTypeface>(new List<FamilyTypeface>(supportedTypefaces)); |
|
|
|
return _typefaces.GetOrAdd(new FamilyTypefaceKey(fontWeight, fontStyle), x => CreateFamilyTypeface(x, resourceUri)); |
|
|
|
} |
|
|
|
|
|
|
|
public IEnumerable<FamilyTypeface> SupportedTypefaces { get; } |
|
|
|
private static FamilyTypeface CreateFamilyTypeface(FamilyTypefaceKey familyTypefaceKey, Uri resourceUri) |
|
|
|
{ |
|
|
|
return new FamilyTypeface(resourceUri, familyTypefaceKey.FontWeight, familyTypefaceKey.FontStyle); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public interface IFontFamilyCache |
|
|
|
{ |
|
|
|
CachedFontFamily GetOrAddFontFamily(FontFamily fontFamily); |
|
|
|
} |
|
|
|
|
|
|
|
internal interface IFontFamilyLoader |
|
|
|
public class FontFamilyCache : IFontFamilyCache |
|
|
|
{ |
|
|
|
IFontFamily LoadFontFamily(FontFamilyKey fontFamilyKey); |
|
|
|
private readonly ConcurrentDictionary<FontFamilyKey, CachedFontFamily> _cachedFontFamilies = new ConcurrentDictionary<FontFamilyKey, CachedFontFamily>(); |
|
|
|
|
|
|
|
public CachedFontFamily GetOrAddFontFamily(FontFamily fontFamily) |
|
|
|
{ |
|
|
|
return _cachedFontFamilies.GetOrAdd(fontFamily.FontFamilyKey, CreateCachedFontFamily); |
|
|
|
} |
|
|
|
|
|
|
|
private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) |
|
|
|
{ |
|
|
|
return new CachedFontFamily(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|