Browse Source

IAssetLoader changes

Rename resource to asset
pull/1564/head
Benedikt Schroeder 8 years ago
parent
commit
a10a756366
  1. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-Bold.ttf
  2. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-BoldItalic.ttf
  3. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf
  4. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-Regular.ttf
  5. 12
      samples/ControlCatalog/ControlCatalog.csproj
  6. 8
      samples/ControlCatalog/Pages/TextBoxPage.xaml
  7. 10
      src/Avalonia.Base/Platform/IAssetLoader.cs
  8. 11
      src/Avalonia.Visuals/Media/FontFamily.cs
  9. 26
      src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs
  10. 8
      src/Avalonia.Visuals/Media/Fonts/FontAsset.cs
  11. 10
      src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs
  12. 157
      src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs
  13. 4
      src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
  14. 17
      src/Shared/PlatformSupport/AssetLoader.cs
  15. 8
      src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs
  16. 12
      src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs
  17. 4
      src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs
  18. 2
      tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-Bold.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-BoldItalic.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-Regular.ttf

Binary file not shown.

12
samples/ControlCatalog/ControlCatalog.csproj

@ -11,6 +11,18 @@
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Assets\*" /> <EmbeddedResource Include="Assets\*" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Assets\Fonts\SourceSansPro-Bold.ttf" />
<None Remove="Assets\Fonts\SourceSansPro-BoldItalic.ttf" />
<None Remove="Assets\Fonts\SourceSansPro-Italic.ttf" />
<None Remove="Assets\Fonts\SourceSansPro-Regular.ttf" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-Bold.ttf" />
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-BoldItalic.ttf" />
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-Italic.ttf" />
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-Regular.ttf" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" /> <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />

8
samples/ControlCatalog/Pages/TextBoxPage.xaml

@ -31,6 +31,12 @@
<TextBox AcceptsReturn="True" Width="200" Height="125" <TextBox AcceptsReturn="True" Width="200" Height="125"
Text="Multiline TextBox with no TextWrapping.&#xD;&#xD;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est." /> Text="Multiline TextBox with no TextWrapping.&#xD;&#xD;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est." />
</StackPanel> </StackPanel>
</StackPanel> <StackPanel Orientation="Vertical" Gap="8">
<TextBox Width="200" Text="Custom font regular" FontWeight="Normal" FontStyle="Normal" FontFamily="resm:ControlCatalog.Assets.Fonts?assembly=ControlCatalog#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font bold" FontWeight="Bold" FontStyle="Normal" FontFamily="resm:ControlCatalog.Assets.Fonts?assembly=ControlCatalog#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font italic" FontWeight="Normal" FontStyle="Italic" FontFamily="resm:ControlCatalog.Assets.Fonts.SourceSansPro-Italic.ttf?assembly=ControlCatalog#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font italic bold" FontWeight="Bold" FontStyle="Italic" FontFamily="resm:ControlCatalog.Assets.Fonts.SourceSansPro-*.ttf?assembly=ControlCatalog#Source Sans Pro"/>
</StackPanel>
</StackPanel>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

10
src/Avalonia.Base/Platform/IAssetLoader.cs

@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
@ -58,6 +59,13 @@ namespace Avalonia.Platform
/// <exception cref="FileNotFoundException"> /// <exception cref="FileNotFoundException">
/// The resource was not found. /// The resource was not found.
/// </exception> /// </exception>
Tuple<Stream, Assembly> OpenAndGetAssembly(Uri uri, Uri baseUri = null); (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null);
/// <summary>
/// Gets all assets at a specific location.
/// </summary>
/// <param name="location">The location of resources.</param>
/// <returns>A tuple containing the absolute path to the resource and the owner assembly</returns>
IEnumerable<(string AbsolutePath, Assembly Assembly)> GetAssets(Uri location);
} }
} }

11
src/Avalonia.Visuals/Media/FontFamily.cs

@ -19,7 +19,8 @@ namespace Avalonia.Media
/// <exception cref="T:System.ArgumentNullException">name</exception> /// <exception cref="T:System.ArgumentNullException">name</exception>
public FontFamily(string name) public FontFamily(string name)
{ {
if (name == null) throw new ArgumentNullException(); Contract.Requires<ArgumentNullException>(name != null);
FamilyNames = new FamilyNameCollection(new[] { name }); FamilyNames = new FamilyNameCollection(new[] { name });
} }
@ -30,14 +31,16 @@ namespace Avalonia.Media
/// <exception cref="T:System.ArgumentNullException">name</exception> /// <exception cref="T:System.ArgumentNullException">name</exception>
public FontFamily(IEnumerable<string> names) public FontFamily(IEnumerable<string> names)
{ {
if (names == null) throw new ArgumentNullException(); Contract.Requires<ArgumentNullException>(names != null);
FamilyNames = new FamilyNameCollection(names); FamilyNames = new FamilyNameCollection(names);
} }
/// <inheritdoc />
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:Avalonia.Media.FontFamily" /> class. /// Initializes a new instance of the <see cref="T:Avalonia.Media.FontFamily" /> class.
/// </summary> /// </summary>
/// <param name="name">The name of the <see cref="FontFamily"/>.</param> /// <param name="name">The name of the <see cref="T:Avalonia.Media.FontFamily" />.</param>
/// <param name="source">The source of font resources.</param> /// <param name="source">The source of font resources.</param>
public FontFamily(string name, Uri source) : this(name) public FontFamily(string name, Uri source) : this(name)
{ {
@ -64,7 +67,7 @@ namespace Avalonia.Media
} }
/// <summary> /// <summary>
/// Gets the key for associated resources. /// Gets the key for associated assets.
/// </summary> /// </summary>
/// <value> /// <value>
/// The family familyNames. /// The family familyNames.

26
src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs

@ -13,13 +13,23 @@ namespace Avalonia.Media.Fonts
{ {
private readonly ReadOnlyCollection<string> _familyNames; private readonly ReadOnlyCollection<string> _familyNames;
/// <summary>
/// Initializes a new instance of the <see cref="FamilyNameCollection"/> class.
/// </summary>
/// <param name="familyNames">The family names.</param>
/// <exception cref="ArgumentException">familyNames</exception>
public FamilyNameCollection(IEnumerable<string> familyNames) public FamilyNameCollection(IEnumerable<string> familyNames)
{ {
if (familyNames == null) throw new ArgumentNullException(nameof(familyNames)); Contract.Requires<ArgumentNullException>(familyNames != null);
var names = new List<string>(familyNames); var names = new List<string>(familyNames);
if (names.Count == 0) throw new ArgumentException($"{nameof(familyNames)} must not be empty."); if (names.Count == 0) throw new ArgumentException($"{nameof(familyNames)} must not be empty.");
_familyNames = new ReadOnlyCollection<string>(names); _familyNames = new ReadOnlyCollection<string>(names);
PrimaryFamilyName = _familyNames.First(); PrimaryFamilyName = _familyNames.First();
HasFallbacks = _familyNames.Count > 1; HasFallbacks = _familyNames.Count > 1;
} }
@ -39,11 +49,25 @@ namespace Avalonia.Media.Fonts
/// </value> /// </value>
public bool HasFallbacks { get; } public bool HasFallbacks { get; }
/// <inheritdoc />
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// An enumerator that can be used to iterate through the collection.
/// </returns>
public IEnumerator<string> GetEnumerator() public IEnumerator<string> GetEnumerator()
{ {
return _familyNames.GetEnumerator(); return _familyNames.GetEnumerator();
} }
/// <inheritdoc />
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
/// </returns>
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
return GetEnumerator(); return GetEnumerator();

8
src/Avalonia.Visuals/Media/Fonts/FontResource.cs → src/Avalonia.Visuals/Media/Fonts/FontAsset.cs

@ -5,19 +5,19 @@ using System;
namespace Avalonia.Media.Fonts namespace Avalonia.Media.Fonts
{ {
internal class FontResource internal class FontAsset
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="FontResource"/> class. /// Initializes a new instance of the <see cref="FontAsset"/> class.
/// </summary> /// </summary>
/// <param name="source">The source.</param> /// <param name="source">The source.</param>
public FontResource(Uri source) public FontAsset(Uri source)
{ {
Source = source; Source = source;
} }
/// <summary> /// <summary>
/// Gets the source. /// Gets the source of the asset.
/// </summary> /// </summary>
/// <value> /// <value>
/// The source. /// The source.

10
src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs

@ -33,15 +33,21 @@ namespace Avalonia.Media.Fonts
} }
/// <summary> /// <summary>
/// Location of stored <see cref="FontResource"/> that belong to a <see cref="FontFamily"/> /// Location of stored <see cref="FontAsset"/> that belong to a <see cref="FontFamily"/>
/// </summary> /// </summary>
public Uri Location { get; } public Uri Location { get; }
/// <summary> /// <summary>
/// Optional filename for <see cref="FontResource"/> that belong to a <see cref="FontFamily"/> /// Optional filename for <see cref="FontAsset"/> that belong to a <see cref="FontFamily"/>
/// </summary> /// </summary>
public string FileName { get; } public string FileName { get; }
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns>
public override int GetHashCode() public override int GetHashCode()
{ {
unchecked unchecked

157
src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs

@ -11,181 +11,68 @@ namespace Avalonia.Media.Fonts
{ {
internal static class FontFamilyLoader internal static class FontFamilyLoader
{ {
private static readonly Dictionary<string, AssemblyDescriptor> s_assemblyNameCache private static readonly IAssetLoader s_assetLoader;
= new Dictionary<string, AssemblyDescriptor>();
private static readonly AssemblyDescriptor s_defaultAssembly;
static FontFamilyLoader() static FontFamilyLoader()
{ {
s_defaultAssembly = new AssemblyDescriptor(Assembly.GetEntryAssembly()); s_assetLoader = AvaloniaLocator.Current.GetService<IAssetLoader>();
} }
public static IEnumerable<FontResource> LoadFontResources(FontFamilyKey fontFamilyKey) public static IEnumerable<FontAsset> LoadFontAssets(FontFamilyKey fontFamilyKey)
{ {
return fontFamilyKey.FileName != null return fontFamilyKey.FileName != null
? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) ? GetFontAssetsByFileName(fontFamilyKey.Location, fontFamilyKey.FileName)
: GetFontResourcesByLocation(fontFamilyKey.Location); : GetFontAssetsByLocation(fontFamilyKey.Location);
} }
/// <summary> /// <summary>
/// Searches for font resources at a given location and returns a quanity of found resources /// Searches for font assets at a given location and returns a quanity of found assets
/// </summary> /// </summary>
/// <param name="location"></param> /// <param name="location"></param>
/// <returns></returns> /// <returns></returns>
private static IEnumerable<FontResource> GetFontResourcesByLocation(Uri location) private static IEnumerable<FontAsset> GetFontAssetsByLocation(Uri location)
{ {
var assembly = GetAssembly(location); var availableAssets = s_assetLoader.GetAssets(location);
if (assembly == null) return Enumerable.Empty<FontResource>();
var locationPath = location.AbsolutePath; var locationPath = location.AbsolutePath;
var matchingResources = assembly.Resources.Where(x => x.Contains(locationPath)); var mathchingAssets = availableAssets.Where(x => x.AbsolutePath.Contains(locationPath) && x.AbsolutePath.EndsWith(".ttf"));
return matchingResources.Select(x => CreateResource(GetResourceUri(x, assembly.Name))); return mathchingAssets.Select(x => CreateFontAsset(GetAssetUri(x.AbsolutePath, x.Assembly)));
} }
/// <summary> /// <summary>
/// Searches for font resources at a given location and only accepts resources that fit to a given filename expression. /// Searches for font assets at a given location and only accepts assets that fit to a given filename expression.
/// <para>Filenames can target multible files with * wildcard. For example "FontFile*.ttf"</para> /// <para>Filenames can target multible files with * wildcard. For example "FontFile*.ttf"</para>
/// </summary> /// </summary>
/// <param name="location"></param> /// <param name="location"></param>
/// <param name="fileName"></param> /// <param name="fileName"></param>
/// <returns></returns> /// <returns></returns>
private static IEnumerable<FontResource> GetFontResourcesByFileName(Uri location, string fileName) private static IEnumerable<FontAsset> GetFontAssetsByFileName(Uri location, string fileName)
{ {
var assembly = GetAssembly(location); var availableResources = s_assetLoader.GetAssets(location);
if (assembly == null) return Enumerable.Empty<FontResource>();
var compareTo = location.AbsolutePath + "." + fileName.Split('*').First(); var compareTo = location.AbsolutePath + "." + fileName.Split('*').First();
var matchingResources = assembly.Resources.Where(x => x.Contains(compareTo)); var matchingResources = availableResources.Where(x => x.AbsolutePath.Contains(compareTo));
return matchingResources.Select(x => CreateResource(GetResourceUri(x, assembly.Name)));
}
private static FontResource CreateResource(Uri source)
{
return new FontResource(source);
}
/// <summary>
/// Returns a valid resource <see cref="Uri"/> that follows the resm scheme
/// </summary>
/// <param name="path"></param>
/// <param name="assemblyName"></param>
/// <returns></returns>
private static Uri GetResourceUri(string path, string assemblyName)
{
return new Uri("resm:" + path + "?assembly=" + assemblyName);
}
/// <summary>
/// Extracts a <see cref="AssemblyDescriptor"/> from a given <see cref="Uri"/>
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
private static AssemblyDescriptor GetAssembly(Uri uri)
{
if (uri == null) return null;
var parameters = ParseParameters(uri);
return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : s_defaultAssembly; return matchingResources.Select(x => CreateFontAsset(GetAssetUri(x.AbsolutePath, x.Assembly)));
} }
/// <summary> private static FontAsset CreateFontAsset(Uri source)
/// Returns a <see cref="AssemblyDescriptor"/> that is identified by a given name.
/// <para>
/// If name is <value>null</value> the default assembly is used.
/// </para>
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private static AssemblyDescriptor GetAssembly(string name)
{ {
if (name == null) return new FontAsset(source);
{
return s_defaultAssembly;
}
if (!s_assemblyNameCache.TryGetValue(name, out var rv))
{
var loadedAssemblies = AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetLoadedAssemblies();
var match = loadedAssemblies.FirstOrDefault(a => a.GetName().Name == name);
if (match != null)
{
s_assemblyNameCache[name] = rv = new AssemblyDescriptor(match);
}
else
{
// iOS does not support loading assemblies dynamically!
//
#if NETCOREAPP1_0
s_assemblyNameCache[name] = rv = new AssemblyDescriptor(Assembly.Load(new AssemblyName(name)));
#elif __IOS__
throw new InvalidOperationException(
$"Assembly {name} needs to be referenced and explicitly loaded before loading resources");
#else
s_assemblyNameCache[name] = rv = new AssemblyDescriptor(Assembly.Load(name));
#endif
}
}
return rv;
} }
/// <summary> /// <summary>
/// Parses the parameters. /// Returns a <see cref="Uri"/> for a font asset that follows the resm scheme
/// </summary> /// </summary>
/// <param name="uri">The URI.</param> /// <param name="absolutePath"></param>
/// <param name="assembly"></param>
/// <returns></returns> /// <returns></returns>
private static Dictionary<string, string> ParseParameters(Uri uri) private static Uri GetAssetUri(string absolutePath, Assembly assembly)
{ {
return uri.Query.TrimStart('?') return new Uri("resm:" + absolutePath + "?assembly=" + assembly.GetName().Name, UriKind.RelativeOrAbsolute);
.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
.Select(p => p.Split('='))
.ToDictionary(p => p[0], p => p[1]);
}
private class AssemblyDescriptor
{
public AssemblyDescriptor(Assembly assembly)
{
Assembly = assembly;
if (Assembly == null) return;
Resources = assembly.GetManifestResourceNames().ToList();
Name = Assembly.GetName().Name;
}
/// <summary>
/// Gets the name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name { get; }
/// <summary>
/// Gets the assembly.
/// </summary>
/// <value>
/// The assembly.
/// </value>
public Assembly Assembly { get; }
/// <summary>
/// Gets the resources.
/// </summary>
/// <value>
/// The resources.
/// </value>
public List<string> Resources { get; }
} }
} }
} }

4
src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs

@ -126,11 +126,11 @@ namespace Avalonia.Markup.Xaml
} }
var asset = assetLocator.OpenAndGetAssembly(uri, baseUri); var asset = assetLocator.OpenAndGetAssembly(uri, baseUri);
using (var stream = asset.Item1) using (var stream = asset.Stream)
{ {
try try
{ {
return Load(stream, asset.Item2, rootInstance, uri); return Load(stream, asset.Assembly, rootInstance, uri);
} }
catch (Exception e) catch (Exception e)
{ {

17
src/Shared/PlatformSupport/AssetLoader.cs

@ -67,8 +67,8 @@ namespace Avalonia.Shared.PlatformSupport
/// <exception cref="FileNotFoundException"> /// <exception cref="FileNotFoundException">
/// The resource was not found. /// The resource was not found.
/// </exception> /// </exception>
public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Item1; public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Stream;
/// <summary> /// <summary>
/// Opens the resource with the requested URI and returns the resource string and the /// Opens the resource with the requested URI and returns the resource string and the
/// assembly containing the resource. /// assembly containing the resource.
@ -83,7 +83,7 @@ namespace Avalonia.Shared.PlatformSupport
/// <exception cref="FileNotFoundException"> /// <exception cref="FileNotFoundException">
/// The resource was not found. /// The resource was not found.
/// </exception> /// </exception>
public Tuple<Stream, Assembly> OpenAndGetAssembly(Uri uri, Uri baseUri = null) public (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null)
{ {
var asset = GetAsset(uri, baseUri); var asset = GetAsset(uri, baseUri);
@ -92,9 +92,18 @@ namespace Avalonia.Shared.PlatformSupport
throw new FileNotFoundException($"The resource {uri} could not be found."); throw new FileNotFoundException($"The resource {uri} could not be found.");
} }
return Tuple.Create(asset.GetStream(), asset.Assembly); return (asset.GetStream(), asset.Assembly);
}
public IEnumerable<(string AbsolutePath, Assembly Assembly)> GetAssets(Uri location)
{
var assembly = GetAssembly(location);
return assembly?.Resources.Select(x => (x.Key, x.Value.Assembly)) ??
Enumerable.Empty<(string AbsolutePath, Assembly Assembly)>();
} }
private IAssetDescriptor GetAsset(Uri uri, Uri baseUri) private IAssetDescriptor GetAsset(Uri uri, Uri baseUri)
{ {
if (!uri.IsAbsoluteUri || uri.Scheme == "resm") if (!uri.IsAbsoluteUri || uri.Scheme == "resm")

8
src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs

@ -22,17 +22,17 @@ namespace Avalonia.Skia
private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily)
{ {
var resources = FontFamilyLoader.LoadFontResources(fontFamily.Key); var assets = FontFamilyLoader.LoadFontAssets(fontFamily.Key);
var typeFaceCollection = new SKTypefaceCollection(); var typeFaceCollection = new SKTypefaceCollection();
var assetLoader = AvaloniaLocator.Current.GetService<IAssetLoader>(); var assetLoader = AvaloniaLocator.Current.GetService<IAssetLoader>();
foreach (var fontResource in resources) foreach (var fontAsset in assets)
{ {
var stream = assetLoader.Open(fontResource.Source); var assetStream = assetLoader.Open(fontAsset.Source);
var typeface = SKTypeface.FromStream(stream); var typeface = SKTypeface.FromStream(assetStream);
typeFaceCollection.AddTypeFace(typeface); typeFaceCollection.AddTypeFace(typeface);
} }

12
src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs

@ -16,20 +16,20 @@ namespace Avalonia.Direct2D1.Media
/// Initializes a new instance of the <see cref="DWriteResourceFontLoader"/> class. /// Initializes a new instance of the <see cref="DWriteResourceFontLoader"/> class.
/// </summary> /// </summary>
/// <param name="factory">The factory.</param> /// <param name="factory">The factory.</param>
/// <param name="fontResources"></param> /// <param name="fontAssets"></param>
public DWriteResourceFontLoader(Factory factory, IEnumerable<FontResource> fontResources) public DWriteResourceFontLoader(Factory factory, IEnumerable<FontAsset> fontAssets)
{ {
var factory1 = factory; var factory1 = factory;
var assetLoader = AvaloniaLocator.Current.GetService<IAssetLoader>(); var assetLoader = AvaloniaLocator.Current.GetService<IAssetLoader>();
foreach (var font in fontResources) foreach (var font in fontAssets)
{ {
var resourceStream = assetLoader.Open(font.Source); var assetStream = assetLoader.Open(font.Source);
var dataStream = new DataStream((int)resourceStream.Length, true, true); var dataStream = new DataStream((int)assetStream.Length, true, true);
resourceStream.CopyTo(dataStream); assetStream.CopyTo(dataStream);
dataStream.Position = 0; dataStream.Position = 0;

4
src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs

@ -24,9 +24,9 @@ namespace Avalonia.Direct2D1.Media
private static SharpDX.DirectWrite.FontCollection CreateFontCollection(FontFamilyKey key) private static SharpDX.DirectWrite.FontCollection CreateFontCollection(FontFamilyKey key)
{ {
var resources = FontFamilyLoader.LoadFontResources(key); var assets = FontFamilyLoader.LoadFontAssets(key);
var fontLoader = new DWriteResourceFontLoader(s_factory, resources); var fontLoader = new DWriteResourceFontLoader(s_factory, assets);
return new SharpDX.DirectWrite.FontCollection(s_factory, fontLoader, fontLoader.Key); return new SharpDX.DirectWrite.FontCollection(s_factory, fontLoader, fontLoader.Key);
} }

2
tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs

@ -22,7 +22,7 @@ namespace Avalonia.Visuals.UnitTests.Media.Fonts
var key = new FontFamilyKey(source); var key = new FontFamilyKey(source);
var resources = FontFamilyLoader.LoadFontResources(key); var resources = FontFamilyLoader.LoadFontAssets(key);
Assert.Single(resources); Assert.Single(resources);
} }

Loading…
Cancel
Save