Browse Source

resm filename globbing

repros/custom-fonts-pr
Benedikt Schroeder 8 years ago
parent
commit
ff230d4360
  1. 18
      samples/ControlCatalog/ControlCatalog.csproj
  2. BIN
      samples/ControlCatalog/Fonts/Aspergit_Bold.ttf
  3. BIN
      samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf
  4. BIN
      samples/ControlCatalog/Fonts/Aspergit_Italic.ttf
  5. BIN
      samples/ControlCatalog/Fonts/BolshevikBd.ttf
  6. BIN
      samples/ControlCatalog/Fonts/PinkHighwayBold.ttf
  7. BIN
      samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf
  8. BIN
      samples/ControlCatalog/Fonts/PixelOperator.ttf
  9. 40
      samples/ControlCatalog/Pages/BorderPage.xaml
  10. 387
      src/Avalonia.Visuals/Media/FontFamily.cs
  11. 13
      src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs
  12. 8
      src/Shared/PlatformSupport/AssetLoader.cs
  13. 18
      src/Skia/Avalonia.Skia/TypefaceCache.cs
  14. 47
      src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs

18
samples/ControlCatalog/ControlCatalog.csproj

@ -11,6 +11,24 @@
</EmbeddedResource>
<EmbeddedResource Include="Assets\*" />
</ItemGroup>
<ItemGroup>
<None Remove="Fonts\Aspergit_Bold.ttf" />
<None Remove="Fonts\Aspergit_Bold_Italic.ttf" />
<None Remove="Fonts\Aspergit_Italic.ttf" />
<None Remove="Fonts\BolshevikBd.ttf" />
<None Remove="Fonts\PinkHighwayBold.ttf" />
<None Remove="Fonts\PixelOperator-Bold.ttf" />
<None Remove="Fonts\PixelOperator.ttf" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Fonts\Aspergit_Bold_Italic.ttf" />
<EmbeddedResource Include="Fonts\Aspergit_Bold.ttf" />
<EmbeddedResource Include="Fonts\Aspergit_Italic.ttf" />
<EmbeddedResource Include="Fonts\BolshevikBd.ttf" />
<EmbeddedResource Include="Fonts\PinkHighwayBold.ttf" />
<EmbeddedResource Include="Fonts\PixelOperator-Bold.ttf" />
<EmbeddedResource Include="Fonts\PixelOperator.ttf" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />

BIN
samples/ControlCatalog/Fonts/Aspergit_Bold.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Fonts/Aspergit_Italic.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Fonts/BolshevikBd.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Fonts/PinkHighwayBold.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Fonts/PixelOperator.ttf

Binary file not shown.

40
samples/ControlCatalog/Pages/BorderPage.xaml

@ -1,32 +1,38 @@
<UserControl xmlns="https://github.com/avaloniaui">
<StackPanel Orientation="Vertical" Gap="4">
<TextBlock Classes="h1">Border</TextBlock>
<TextBlock Classes="h2">A control which decorates a child with a border and background</TextBlock>
<StackPanel Orientation="Vertical" Gap="4">
<TextBlock Classes="h1">Border</TextBlock>
<TextBlock Classes="h2">A control which decorates a child with a border and background</TextBlock>
<StackPanel Orientation="Vertical"
<StackPanel Orientation="Vertical"
Margin="0,16,0,0"
HorizontalAlignment="Center"
Gap="16">
<Border BorderBrush="{DynamicResource ThemeAccentBrush}" BorderThickness="2" Padding="16">
<TextBlock>Border</TextBlock>
</Border>
<Border Background="{DynamicResource ThemeAccentBrush2}"
<Border BorderBrush="{DynamicResource ThemeAccentBrush}" BorderThickness="2" Padding="16">
<TextBlock>Border</TextBlock>
</Border>
<Border Background="{DynamicResource ThemeAccentBrush2}"
BorderBrush="{DynamicResource ThemeAccentBrush}"
BorderThickness="4"
Padding="16">
<TextBlock>Border and Background</TextBlock>
</Border>
<Border BorderBrush="{DynamicResource ThemeAccentBrush}"
<TextBlock>Border and Background</TextBlock>
</Border>
<Border BorderBrush="{DynamicResource ThemeAccentBrush}"
BorderThickness="4"
CornerRadius="8"
Padding="16">
<TextBlock>Rounded Corners</TextBlock>
</Border>
<Border Background="{DynamicResource ThemeAccentBrush2}"
<TextBlock>Rounded Corners</TextBlock>
</Border>
<Border Background="{DynamicResource ThemeAccentBrush2}"
CornerRadius="8"
Padding="16">
<TextBlock>Rounded Corners</TextBlock>
</Border>
<StackPanel>
<TextBlock FontFamily="resm:ControlCatalog.Fonts?assembly=ControlCatalog#Pixel Operator">Rounded Corners</TextBlock>
<TextBlock FontFamily="resm:ControlCatalog.Fonts?assembly=ControlCatalog#Pixel Operator" FontWeight="Bold">Rounded Corners</TextBlock>
<TextBlock FontFamily="resm:ControlCatalog.Fonts.Aspergit*.ttf?assembly=ControlCatalog#Aspergit" FontWeight="Bold">Rounded Corners</TextBlock>
<TextBlock FontFamily="resm:ControlCatalog.Fonts.Aspergit*.ttf?assembly=ControlCatalog#Aspergit" FontWeight="Bold" FontStyle="Italic">Rounded Corners</TextBlock>
<TextBlock FontFamily="resm:ControlCatalog.Fonts.Aspergit*.ttf?assembly=ControlCatalog#Aspergit" FontStyle="Italic">Rounded Corners</TextBlock>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
</StackPanel>
</UserControl>

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

@ -2,41 +2,71 @@
// 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.Linq;
using System.Reflection;
using System.Text;
using Avalonia.Platform;
namespace Avalonia.Media
{
public class FontFamily
{
public FontFamily(string familyName = "Courier New", Uri baseUri = null)
public FontFamily(string name = "Courier New")
{
if (familyName == null) throw new ArgumentNullException(nameof(familyName));
Key = new FontFamilyKey(familyName, baseUri);
Name = name ?? throw new ArgumentNullException(nameof(name));
}
public string Name => Key.FriendlyName;
public FontFamily(string name, Uri source) : this(name)
{
Key = new FontFamilyKey(source);
}
public Uri BaseUri => Key.BaseUri;
public string Name { get; }
public FontFamilyKey Key { get; }
public override string ToString()
{
return Key.ToString();
if (Key != null)
{
return Key + "#" + Name;
}
return Name;
}
}
public class FontFamilyKey
{
public FontFamilyKey(string friendlyName, Uri baseUri = null)
public FontFamilyKey(Uri source)
{
FriendlyName = friendlyName;
BaseUri = baseUri;
if (source.AbsolutePath.Contains(".ttf"))
{
var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", "");
if (source.Scheme == "resm")
{
var fileNameWithoutExtension = filePathWithoutExtension.Split('.').Last();
FileName = fileNameWithoutExtension + ".ttf";
Location = new Uri(source.OriginalString.Replace("." + FileName, ""), UriKind.RelativeOrAbsolute);
}
if (source.Scheme == "res")
{
FileName = source.AbsolutePath.Split('/').Last();
}
}
else
{
Location = source;
}
}
public string FriendlyName { get; }
public Uri Location { get; }
public Uri BaseUri { get; }
public string FileName { get; }
public override int GetHashCode()
{
@ -44,14 +74,14 @@ namespace Avalonia.Media
{
var hash = (int)2166136261;
if (FriendlyName != null)
if (Location != null)
{
hash = (hash * 16777619) ^ FriendlyName.GetHashCode();
hash = (hash * 16777619) ^ Location.GetHashCode();
}
if (BaseUri != null)
if (FileName != null)
{
hash = (hash * 16777619) ^ BaseUri.GetHashCode();
hash = (hash * 16777619) ^ FileName.GetHashCode();
}
return hash;
@ -62,117 +92,242 @@ namespace Avalonia.Media
{
if (!(obj is FontFamilyKey other)) return false;
if (FriendlyName != other.FriendlyName) return false;
if (Location != other.Location) return false;
if (BaseUri != other.BaseUri) return false;
if (FileName != other.FileName) return false;
return true;
}
public override string ToString()
{
if (BaseUri != null)
if (FileName != null)
{
return BaseUri + "#" + FriendlyName;
if (Location.Scheme == "resm")
{
return Location + "." + FileName;
}
return Location + "/" + FileName;
}
return FriendlyName;
return Location.ToString();
}
}
//public class FamilyTypeface
//{
// public FamilyTypeface(Uri resourceUri = null, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal)
// {
// ResourceUri = resourceUri;
// FontStyle = fontStyle;
// FontWeight = fontWeight;
// }
// public Uri ResourceUri { get; }
// public FontWeight FontWeight { get; }
// public FontStyle FontStyle { get; }
//}
//public class FamilyTypefaceKey
//{
// public FamilyTypefaceKey(FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal)
// {
// FontWeight = fontWeight;
// FontStyle = fontStyle;
// }
// public FontWeight FontWeight { get; }
// public FontStyle FontStyle { get; }
// public override int GetHashCode()
// {
// unchecked
// {
// var hash = (int)2166136261;
// hash = (hash * 16777619) ^ FontWeight.GetHashCode();
// hash = (hash * 16777619) ^ FontStyle.GetHashCode();
// return hash;
// }
// }
// 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;
// }
//}
//public class CachedFontFamily
//{
// private readonly ConcurrentDictionary<FamilyTypefaceKey, FamilyTypeface> _typefaces =
// new ConcurrentDictionary<FamilyTypefaceKey, FamilyTypeface>();
// public bool TryGetFamilyTypeface(out FamilyTypeface typeface, FontWeight fontWeight = FontWeight.Normal,
// FontStyle fontStyle = FontStyle.Normal)
// {
// return _typefaces.TryGetValue(new FamilyTypefaceKey(fontWeight, fontStyle), out typeface);
// }
// public bool TryAddFamilyTypeface(Uri resourceUri, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal)
// {
// var familyTypefaceKeytypefaceKey = new FamilyTypefaceKey(fontWeight, fontStyle);
// return _typefaces.TryAdd(familyTypefaceKeytypefaceKey, CreateFamilyTypeface(familyTypefaceKeytypefaceKey, resourceUri));
// }
// private static FamilyTypeface CreateFamilyTypeface(FamilyTypefaceKey familyTypefaceKey, Uri resourceUri)
// {
// return new FamilyTypeface(resourceUri, familyTypefaceKey.FontWeight, familyTypefaceKey.FontStyle);
// }
//}
//public class FontFamilyCache
//{
// private readonly ConcurrentDictionary<FontFamilyKey, CachedFontFamily> _cachedFontFamilies = new ConcurrentDictionary<FontFamilyKey, CachedFontFamily>();
// public bool TryGetCachedFontFamily(FontFamily fontFamily, out CachedFontFamily cachedFontFamily)
// {
// return _cachedFontFamilies.TryGetValue(fontFamily.Key, out cachedFontFamily);
// }
// public CachedFontFamily GetOrAddCachedFontFamily(FontFamily fontFamily)
// {
// return _cachedFontFamilies.GetOrAdd(fontFamily.Key, CreateCachedFontFamily);
// }
// private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey)
// {
// return new CachedFontFamily();
// }
//}
public class FontResource
{
public FontResource(Uri source)
{
Source = source;
}
public Uri Source { get; }
}
public class FontResourceCollection
{
private Dictionary<Uri, FontResource> _fontResources;
private readonly IFontResourceLoader _fontResourceLoader = new FontResourceLoader();
public FontResourceCollection(FontFamilyKey key)
{
Key = key;
}
public FontFamilyKey Key { get; }
public IEnumerable<FontResource> FontResources
{
get
{
if (_fontResources == null)
{
_fontResources = CreateFontResources();
}
return _fontResources.Values;
}
}
private Dictionary<Uri, FontResource> CreateFontResources()
{
return _fontResourceLoader.GetFontResources(Key).ToDictionary(x => x.Source);
}
}
public interface IFontResourceLoader
{
IEnumerable<FontResource> GetFontResources(FontFamilyKey fontFamilyKey);
}
public class FontResourceLoader : IFontResourceLoader
{
private static readonly Dictionary<string, AssemblyDescriptor> s_assemblyNameCache
= new Dictionary<string, AssemblyDescriptor>();
private readonly AssemblyDescriptor _defaultAssembly;
public FontResourceLoader(Assembly assembly = null)
{
if (assembly == null)
{
assembly = Assembly.GetEntryAssembly();
}
if (assembly != null)
{
_defaultAssembly = new AssemblyDescriptor(assembly);
}
}
public IEnumerable<FontResource> GetFontResources(FontFamilyKey fontFamilyKey)
{
return fontFamilyKey.FileName != null
? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName)
: GetFontResourcesByLocation(fontFamilyKey.Location);
}
private IEnumerable<FontResource> GetFontResourcesByLocation(Uri location)
{
var assembly = GetAssembly(location);
var locationPath = GetLocationPath(location);
var matchingResources = assembly.Resources.Where(x => x.Contains(locationPath));
return matchingResources.Select(x => new FontResource(GetResourceUri(x, assembly.Name)));
}
private IEnumerable<FontResource> GetFontResourcesByFileName(Uri location, string fileName)
{
var assembly = GetAssembly(location);
var compareTo = fileName.Split('*').First();
var matchingResources = assembly.Resources.Where(x => x.Contains(compareTo));
return matchingResources.Select(x => new FontResource(GetResourceUri(x, assembly.Name)));
}
private static Uri GetResourceUri(string path, string assemblyName)
{
return new Uri("resm:" + path + "?assembly=" + assemblyName);
}
private static string GetLocationPath(Uri uri)
{
if (uri.Scheme == "resm") return uri.AbsolutePath;
var path = new StringBuilder();
for (var index = 0; index < uri.Segments.Length; index++)
{
path.Append(uri.Segments[index]);
if (index < uri.Segments.Length - 1)
{
path.Append('.');
}
}
return path.ToString();
}
private AssemblyDescriptor GetAssembly(Uri uri)
{
if (uri == null) return null;
var parameters = ParseParameters(uri);
return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : null;
}
private AssemblyDescriptor GetAssembly(string name)
{
if (name == null)
{
return _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;
}
private static Dictionary<string, string> ParseParameters(Uri uri)
{
return uri.Query.TrimStart('?')
.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;
}
public string Name { get; }
public Assembly Assembly { get; }
public List<string> Resources { get; }
}
}
public class CachedFontFamily
{
private readonly FontResourceCollection _fontResourceCollection;
public CachedFontFamily(FontFamilyKey key, FontResourceCollection fontResourceCollection)
{
Key = key;
_fontResourceCollection = fontResourceCollection;
}
public FontFamilyKey Key { get; }
public IEnumerable<FontResource> FontResources => _fontResourceCollection.FontResources;
}
public class FontFamilyCache
{
private static readonly ConcurrentDictionary<FontFamilyKey, CachedFontFamily> s_cachedFontFamilies = new ConcurrentDictionary<FontFamilyKey, CachedFontFamily>();
public CachedFontFamily GetOrAddFontFamily(FontFamilyKey key)
{
return s_cachedFontFamilies.GetOrAdd(key, CreateCachedFontFamily);
}
private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey)
{
return new CachedFontFamily(fontFamilyKey, new FontResourceCollection(fontFamilyKey));
}
}
}

13
src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs

@ -18,13 +18,16 @@ namespace Avalonia.Markup.Xaml.Converters
if (string.IsNullOrEmpty(s)) throw new ArgumentException("Specified family is not supported.");
if (!s.StartsWith("resm:")) return new FontFamily(s);
var fontFamilyExpression = s.Split('#');
if (fontFamilyExpression.Length == 1)
{
return new FontFamily(s);
}
string familyName;
Uri baseUri = null;
Uri source = null;
switch (fontFamilyExpression.Length)
{
@ -35,7 +38,7 @@ namespace Avalonia.Markup.Xaml.Converters
}
case 2:
{
baseUri = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute);
source = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute);
familyName = fontFamilyExpression[1];
break;
}
@ -45,7 +48,7 @@ namespace Avalonia.Markup.Xaml.Converters
}
}
return new FontFamily(familyName, baseUri);
return new FontFamily(familyName, source);
}
}
}

8
src/Shared/PlatformSupport/AssetLoader.cs

@ -106,9 +106,8 @@ namespace Avalonia.Shared.PlatformSupport
if (uri != null)
{
var qs = ParseQueryString(uri);
string assemblyName;
if (qs.TryGetValue("assembly", out assemblyName))
if (qs.TryGetValue("assembly", out var assemblyName))
{
return GetAssembly(assemblyName);
}
@ -124,8 +123,7 @@ namespace Avalonia.Shared.PlatformSupport
return _defaultAssembly;
}
AssemblyDescriptor rv;
if (!AssemblyNameCache.TryGetValue(name, out rv))
if (!AssemblyNameCache.TryGetValue(name, out var rv))
{
var loadedAssemblies = AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetLoadedAssemblies();
var match = loadedAssemblies.FirstOrDefault(a => a.GetName().Name == name);
@ -199,5 +197,5 @@ namespace Avalonia.Shared.PlatformSupport
public Dictionary<string, IAssetDescriptor> Resources { get; }
public string Name { get; }
}
}
}
}

18
src/Skia/Avalonia.Skia/TypefaceCache.cs

@ -56,21 +56,21 @@ namespace Avalonia.Skia
if (!entry.TryGetValue(key, out var typeface))
{
if (fontFamily.BaseUri != null)
{
var stream = AvaloniaLocator.Current.GetService<IAssetLoader>().Open(fontFamily.BaseUri);
typeface = SKTypeface.FromStream(stream);
}
else
{
//if (fontFamily.BaseUri != null)
//{
// var stream = AvaloniaLocator.Current.GetService<IAssetLoader>().Open(fontFamily.BaseUri);
// typeface = SKTypeface.FromStream(stream);
//}
//else
//{
typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant);
if (typeface == null)
{
typeface = SKTypeface.FromFamilyName(null, SKTypefaceStyle.Normal);
}
}
//}
entry[key] = typeface;
}

47
src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs

@ -4,7 +4,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Avalonia.Media;
using Avalonia.Platform;
using SharpDX;
@ -24,13 +26,17 @@ namespace Avalonia.Direct2D1.Media
{
Text = text;
var factory = AvaloniaLocator.Current.GetService<DWrite.Factory>();
var factory = AvaloniaLocator.Current.GetService<DWrite.Factory>();
DWrite.TextFormat textFormat;
if (typeface.FontFamily.BaseUri != null)
if (typeface.FontFamily.Key != null)
{
var fontCollection = Direct2D1CustomFontResourceCache.GetOrAddCustomFontResource(typeface.FontFamily, factory);
var fontFamilyCache = new FontFamilyCache();
var fontFamily = fontFamilyCache.GetOrAddFontFamily(typeface.FontFamily.Key);
var fontCollection = Direct2D1CustomFontCollectionCache.GetOrAddCustomFontCollection(fontFamily, factory);
textFormat = new DWrite.TextFormat(
factory,
@ -81,11 +87,6 @@ namespace Avalonia.Direct2D1.Media
public DWrite.TextLayout TextLayout { get; }
//public void Dispose()
//{
// TextLayout.Dispose();
//}
public IEnumerable<FormattedTextLine> GetLines()
{
var result = TextLayout.GetLineMetrics();
@ -148,19 +149,19 @@ namespace Avalonia.Direct2D1.Media
}
}
internal static class Direct2D1CustomFontResourceCache
internal static class Direct2D1CustomFontCollectionCache
{
private static readonly ConcurrentDictionary<FontFamilyKey, DWrite.FontCollection> s_cachedFonts =
new ConcurrentDictionary<FontFamilyKey, DWrite.FontCollection>();
public static DWrite.FontCollection GetOrAddCustomFontResource(FontFamily fontFamily, DWrite.Factory factory)
public static DWrite.FontCollection GetOrAddCustomFontCollection(CachedFontFamily fontFamily, DWrite.Factory factory)
{
return s_cachedFonts.GetOrAdd(fontFamily.Key, x => CreateCustomFontResource(x, factory));
return s_cachedFonts.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(fontFamily, factory));
}
private static DWrite.FontCollection CreateCustomFontResource(FontFamilyKey fontFamilyKey, DWrite.Factory factory)
private static DWrite.FontCollection CreateCustomFontCollection(CachedFontFamily fontFamily, DWrite.Factory factory)
{
var fontLoader = new ResourceFontLoader(factory, fontFamilyKey.BaseUri);
var fontLoader = new ResourceFontLoader(factory, fontFamily.FontResources);
return new DWrite.FontCollection(factory, fontLoader, fontLoader.Key);
}
@ -172,27 +173,29 @@ namespace Avalonia.Direct2D1.Media
private readonly List<ResourceFontFileEnumerator> _enumerators = new List<ResourceFontFileEnumerator>();
private readonly DataStream _keyStream;
/// <summary>
/// Initializes a new instance of the <see cref="ResourceFontLoader"/> class.
/// </summary>
/// <param name="factory">The factory.</param>
/// <param name="fontResource"></param>
public ResourceFontLoader(DWrite.Factory factory, Uri fontResource)
/// <param name="fontResources"></param>
public ResourceFontLoader(DWrite.Factory factory, IEnumerable<FontResource> fontResources)
{
var factory1 = factory;
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
var assetLoader = AvaloniaLocator.Current.GetService<IAssetLoader>();
var resourceStream = assets.Open(fontResource);
foreach (var font in fontResources)
{
var resourceStream = assetLoader.Open(font.Source);
var dataStream = new DataStream((int)resourceStream.Length, true, true);
var dataStream = new DataStream((int)resourceStream.Length, true, true);
resourceStream.CopyTo(dataStream);
resourceStream.CopyTo(dataStream);
dataStream.Position = 0;
dataStream.Position = 0;
_fontStreams.Add(new ResourceFontFileStream(dataStream));
_fontStreams.Add(new ResourceFontFileStream(dataStream));
}
// Build a Key storage that stores the index of the font
_keyStream = new DataStream(sizeof(int) * _fontStreams.Count, true, true);

Loading…
Cancel
Save