Browse Source
* Improve FontCollection user story * Make adjustments after review * Refactor IsFontFile * Make FontFamilyLoader internal Make tests happy again * Update baseline * Adjust modifier --------- Co-authored-by: Julien Lebosquain <julien@lebosquain.net>pull/20137/head
committed by
GitHub
29 changed files with 1404 additions and 557 deletions
@ -0,0 +1,40 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids --> |
|||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
|||
<Suppression> |
|||
<DiagnosticId>CP0002</DiagnosticId> |
|||
<Target>M:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost.PreFilterMessage(System.Windows.Forms.Message@)</Target> |
|||
<Left>baseline/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll</Left> |
|||
<Right>current/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll</Right> |
|||
</Suppression> |
|||
<Suppression> |
|||
<DiagnosticId>CP0002</DiagnosticId> |
|||
<Target>M:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost.PreFilterMessage(System.Windows.Forms.Message@)</Target> |
|||
<Left>baseline/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll</Left> |
|||
<Right>current/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll</Right> |
|||
</Suppression> |
|||
<Suppression> |
|||
<DiagnosticId>CP0002</DiagnosticId> |
|||
<Target>M:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost.PreFilterMessage(System.Windows.Forms.Message@)</Target> |
|||
<Left>baseline/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll</Left> |
|||
<Right>current/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll</Right> |
|||
</Suppression> |
|||
<Suppression> |
|||
<DiagnosticId>CP0008</DiagnosticId> |
|||
<Target>T:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost</Target> |
|||
<Left>baseline/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll</Left> |
|||
<Right>current/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll</Right> |
|||
</Suppression> |
|||
<Suppression> |
|||
<DiagnosticId>CP0008</DiagnosticId> |
|||
<Target>T:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost</Target> |
|||
<Left>baseline/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll</Left> |
|||
<Right>current/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll</Right> |
|||
</Suppression> |
|||
<Suppression> |
|||
<DiagnosticId>CP0008</DiagnosticId> |
|||
<Target>T:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost</Target> |
|||
<Left>baseline/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll</Left> |
|||
<Right>current/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll</Right> |
|||
</Suppression> |
|||
</Suppressions> |
|||
@ -0,0 +1,9 @@ |
|||
using System; |
|||
|
|||
namespace Avalonia.Media.Fonts |
|||
{ |
|||
internal class EmptySystemFontCollection : FontCollectionBase |
|||
{ |
|||
public override Uri Key => FontManager.SystemFontsKey; |
|||
} |
|||
} |
|||
@ -0,0 +1,188 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Fonts; |
|||
using Avalonia.Platform; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Skia.UnitTests.Media |
|||
{ |
|||
public class CustomFontCollectionTests |
|||
{ |
|||
private const string NotoMono = |
|||
"resm:Avalonia.Skia.UnitTests.Assets?assembly=Avalonia.Skia.UnitTests"; |
|||
|
|||
[Fact] |
|||
public void Should_AddGlyphTypeface_By_Stream() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new FontManagerImpl()))) |
|||
{ |
|||
var fontManager = FontManager.Current; |
|||
|
|||
var fontCollection = new CustomFontCollection(new Uri("fonts:custom", UriKind.Absolute)); |
|||
|
|||
fontManager.AddFontCollection(fontCollection); |
|||
|
|||
var assetLoader = AvaloniaLocator.Current.GetRequiredService<IAssetLoader>(); |
|||
|
|||
var assets = assetLoader.GetAssets(new Uri(NotoMono, UriKind.Absolute), null).ToArray(); |
|||
|
|||
Assert.NotEmpty(assets); |
|||
|
|||
var notoMonoLocation = assets.First(); |
|||
|
|||
using var notoMonoStream = assetLoader.Open(notoMonoLocation); |
|||
|
|||
Assert.NotNull(notoMonoStream); |
|||
|
|||
Assert.True(fontCollection.TryAddGlyphTypeface(notoMonoStream, out var glyphTypeface)); |
|||
|
|||
Assert.Equal("Inter", glyphTypeface.FamilyName); |
|||
|
|||
Assert.True(fontManager.TryGetGlyphTypeface(new Typeface("fonts:custom#Inter"), out var secondGlyphTypeface)); |
|||
|
|||
Assert.Equal(glyphTypeface, secondGlyphTypeface); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Enumerate_FontFamilies() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new FontManagerImpl()))) |
|||
{ |
|||
var fontManager = FontManager.Current; |
|||
|
|||
var fontCollection = new CustomFontCollection(new Uri("fonts:custom", UriKind.Absolute)); |
|||
|
|||
fontManager.AddFontCollection(fontCollection); |
|||
|
|||
var assetLoader = AvaloniaLocator.Current.GetRequiredService<IAssetLoader>(); |
|||
|
|||
var assets = assetLoader.GetAssets(new Uri(NotoMono, UriKind.Absolute), null).Where(x => x.AbsolutePath.EndsWith(".ttf")).ToArray(); |
|||
|
|||
foreach (var asset in assets) |
|||
{ |
|||
fontCollection.TryAddGlyphTypeface(assetLoader.Open(asset), out _); |
|||
} |
|||
|
|||
var families = fontCollection.ToArray(); |
|||
|
|||
Assert.True(families.Length >= assets.Length); |
|||
|
|||
var other = new CustomFontCollection(new Uri("fonts:other", UriKind.Absolute)); |
|||
|
|||
foreach (var family in families) |
|||
{ |
|||
var familyTypefaces = family.FamilyTypefaces; |
|||
|
|||
foreach (var typeface in familyTypefaces) |
|||
{ |
|||
other.TryAddGlyphTypeface(typeface.GlyphTypeface); |
|||
} |
|||
} |
|||
|
|||
Assert.Equal(families.Length, other.Count); |
|||
|
|||
for (int i = 0; i < families.Length; i++) |
|||
{ |
|||
Assert.Equal(families[i].Name, other[i].Name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_AddFontSource_From_File() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new FontManagerImpl()))) |
|||
{ |
|||
var fontManager = FontManager.Current; |
|||
var fontCollection = new CustomFontCollection(new Uri("fonts:custom", UriKind.Absolute)); |
|||
fontManager.AddFontCollection(fontCollection); |
|||
|
|||
// Path to the test font
|
|||
var fontPath = Path.Combine(AppContext.BaseDirectory, "Assets", "Inter-Regular.ttf"); |
|||
Assert.True(File.Exists(fontPath)); |
|||
|
|||
var fontUri = new Uri(fontPath, UriKind.Absolute); |
|||
|
|||
// Add the font file
|
|||
Assert.True(fontCollection.TryAddFontSource(fontUri)); |
|||
|
|||
// Check if the font was loaded
|
|||
Assert.True(fontCollection.TryGetGlyphTypeface("Inter", FontStyle.Normal, FontWeight.Regular, FontStretch.Normal, out var glyphTypeface)); |
|||
Assert.Equal("Inter", glyphTypeface.FamilyName); |
|||
|
|||
// Check if the FontManager can find the font
|
|||
Assert.True(fontManager.TryGetGlyphTypeface(new Typeface("fonts:custom#Inter"), out var glyphTypeface2)); |
|||
Assert.Equal(glyphTypeface, glyphTypeface2); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_AddFontSource_From_Folder() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new FontManagerImpl()))) |
|||
{ |
|||
var fontManager = FontManager.Current; |
|||
var fontCollection = new CustomFontCollection(new Uri("fonts:custom", UriKind.Absolute)); |
|||
fontManager.AddFontCollection(fontCollection); |
|||
|
|||
// Path to the test fonts
|
|||
var fontsFolder = Path.Combine(AppContext.BaseDirectory, "Assets"); |
|||
Assert.True(Directory.Exists(fontsFolder)); |
|||
|
|||
var folderUri = new Uri(fontsFolder + Path.DirectorySeparatorChar, UriKind.Absolute); |
|||
|
|||
// Add the fonts
|
|||
Assert.True(fontCollection.TryAddFontSource(folderUri)); |
|||
|
|||
// Check if the font was loaded
|
|||
Assert.True(fontCollection.TryGetGlyphTypeface("Inter", FontStyle.Normal, FontWeight.Regular, FontStretch.Normal, out var glyphTypeface)); |
|||
Assert.Equal("Inter", glyphTypeface.FamilyName); |
|||
|
|||
// Check if the FontManager can find the font
|
|||
Assert.True(fontManager.TryGetGlyphTypeface(new Typeface("fonts:custom#Inter"), out var glyphTypeface2)); |
|||
Assert.Equal(glyphTypeface, glyphTypeface2); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_AddFontSource_From_Resource() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new FontManagerImpl()))) |
|||
{ |
|||
var fontManager = FontManager.Current; |
|||
var fontCollection = new CustomFontCollection(new Uri("fonts:custom", UriKind.Absolute)); |
|||
fontManager.AddFontCollection(fontCollection); |
|||
|
|||
// Use the NotoMono resource as FontSource
|
|||
var notoMonoUri = new Uri(NotoMono, UriKind.Absolute); |
|||
|
|||
// Add the font resource
|
|||
Assert.True(fontCollection.TryAddFontSource(notoMonoUri)); |
|||
|
|||
// Get the loaded family names
|
|||
var families = fontCollection.ToArray(); |
|||
|
|||
Assert.NotEmpty(families); |
|||
|
|||
// Try to get a GlyphTypeface
|
|||
Assert.True(fontCollection.TryGetGlyphTypeface("Noto Mono", FontStyle.Normal, FontWeight.Regular, FontStretch.Normal, out var glyphTypeface)); |
|||
Assert.Equal("Noto Mono", glyphTypeface.FamilyName); |
|||
|
|||
// Check if the FontManager can find the font
|
|||
Assert.True(fontManager.TryGetGlyphTypeface(new Typeface("fonts:custom#Noto Mono"), out var glyphTypeface2)); |
|||
Assert.Equal(glyphTypeface, glyphTypeface2); |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
private class CustomFontCollection(Uri key) : FontCollectionBase |
|||
{ |
|||
public override Uri Key { get; } = key; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue