Browse Source

Introduce font family mapping (#17234)

pull/17257/head
Benedikt Stebner 1 year ago
committed by GitHub
parent
commit
d3aa0c21e3
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 30
      src/Avalonia.Base/Media/FontManager.cs
  2. 17
      src/Avalonia.Base/Media/FontManagerOptions.cs
  3. 29
      tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs

30
src/Avalonia.Base/Media/FontManager.cs

@ -26,6 +26,7 @@ namespace Avalonia.Media
private readonly ConcurrentDictionary<Uri, IFontCollection> _fontCollections = new ConcurrentDictionary<Uri, IFontCollection>();
private readonly IReadOnlyList<FontFallback>? _fontFallbacks;
private readonly IReadOnlyDictionary<string, FontFamily>? _fontFamilyMappings;
public FontManager(IFontManagerImpl platformImpl)
{
@ -35,6 +36,7 @@ namespace Avalonia.Media
var options = AvaloniaLocator.Current.GetService<FontManagerOptions>();
_fontFallbacks = options?.FontFallbacks;
_fontFamilyMappings = options?.FontFamilyMappings;
var defaultFontFamilyName = GetDefaultFontFamilyName(options);
DefaultFontFamily = new FontFamily(defaultFontFamilyName);
@ -91,8 +93,8 @@ namespace Avalonia.Media
{
glyphTypeface = null;
var fontFamily = typeface.FontFamily;
var fontFamily = GetMappedFontFamily(typeface.FontFamily);
if (typeface.FontFamily.Name == FontFamily.DefaultFontFamilyName)
{
return TryGetGlyphTypeface(new Typeface(DefaultFontFamily, typeface.Style, typeface.Weight, typeface.Stretch), out glyphTypeface);
@ -108,6 +110,20 @@ namespace Avalonia.Media
var familyName = fontFamily.FamilyNames[i];
if(_fontFamilyMappings != null && _fontFamilyMappings.TryGetValue(familyName, out var mappedFontFamily))
{
if(mappedFontFamily.Key != null)
{
key = mappedFontFamily.Key;
}
else
{
key = new FontFamilyKey(SystemFontsKey);
}
familyName = mappedFontFamily.FamilyNames.PrimaryFamilyName;
}
if (TryGetGlyphTypefaceByKeyAndName(typeface, key, familyName, out glyphTypeface) &&
glyphTypeface.FamilyName.Contains(familyName))
{
@ -144,6 +160,16 @@ namespace Avalonia.Media
//Nothing was found so use the default
return TryGetGlyphTypeface(new Typeface(FontFamily.DefaultFontFamilyName, typeface.Style, typeface.Weight, typeface.Stretch), out glyphTypeface);
FontFamily GetMappedFontFamily(FontFamily fontFamily)
{
if (_fontFamilyMappings == null ||!_fontFamilyMappings.TryGetValue(fontFamily.FamilyNames.PrimaryFamilyName, out var mappedFontFamily))
{
return fontFamily;
}
return mappedFontFamily;
}
}
private bool TryGetGlyphTypefaceByKeyAndName(Typeface typeface, FontFamilyKey key, string familyName, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)

17
src/Avalonia.Base/Media/FontManagerOptions.cs

@ -4,8 +4,25 @@ namespace Avalonia.Media
{
public class FontManagerOptions
{
/// <summary>
/// Gets or sets the default font family's name
/// </summary>
public string? DefaultFamilyName { get; set; }
/// <summary>
/// Gets or sets the font fallbacks.
/// </summary>
/// <remarks>
/// A fallback is fullfilled before anything else when the font manager tries to match a specific codepoint.
/// </remarks>
public IReadOnlyList<FontFallback>? FontFallbacks { get; set; }
/// <summary>
/// Gets or sets the font family mappings.
/// </summary>
/// <remarks>
/// A font family mapping is used if a requested family name can't be resolved.
/// </remarks>
public IReadOnlyDictionary<string, FontFamily>? FontFamilyMappings { get; set; }
}
}

29
tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Avalonia.Fonts.Inter;
using Avalonia.Headless;
@ -335,5 +337,32 @@ namespace Avalonia.Skia.UnitTests.Media
}
}
}
[Fact]
public void Should_Map_FontFamily()
{
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new FontManagerImpl())))
{
using (AvaloniaLocator.EnterScope())
{
AvaloniaLocator.CurrentMutable.BindToSelf(new FontManagerOptions
{
DefaultFamilyName = s_fontUri,
FontFamilyMappings = new Dictionary<string, FontFamily>
{
{ "Segoe UI", new FontFamily("fonts:Inter#Inter") }
}
});
FontManager.Current.AddFontCollection(new InterFontCollection());
var result = FontManager.Current.TryGetGlyphTypeface(new Typeface("Abc, Segoe UI"), out var glyphTypeface);
Assert.True(result);
Assert.Equal("Inter", glyphTypeface.FamilyName);
}
}
}
}
}

Loading…
Cancel
Save