Browse Source

Introduce a static FontManager that uses a platform implementation under the hood.

pull/3195/head
Benedikt Schroeder 7 years ago
parent
commit
9d105c7dbb
  1. 7
      src/Avalonia.Visuals/Media/FontFamily.cs
  2. 92
      src/Avalonia.Visuals/Media/FontManager.cs
  3. 5
      src/Avalonia.Visuals/Media/GlyphTypeface.cs
  4. 9
      src/Avalonia.Visuals/Platform/IFontManagerImpl.cs
  5. 9
      src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
  6. 9
      src/Skia/Avalonia.Skia/FontManagerImpl.cs
  7. 9
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  8. 8
      src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
  9. 9
      src/Windows/Avalonia.Direct2D1/Media/FontManagerImpl.cs

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

@ -12,7 +12,7 @@ namespace Avalonia.Media
{
static FontFamily()
{
Default = new FontFamily(FontManager.Default.DefaultFontFamilyName);
Default = new FontFamily(FontManager.DefaultFontFamilyName);
}
/// <inheritdoc />
@ -60,8 +60,11 @@ namespace Avalonia.Media
/// <summary>
/// Represents all font families in the system. This can be an expensive call depending on platform implementation.
/// </summary>
/// <remarks>
/// Consider using the new <see cref="FontManager"/> instead.
/// </remarks>
public static IEnumerable<FontFamily> SystemFontFamilies =>
FontManager.Default.GetInstalledFontFamilyNames().Select(name => new FontFamily(name));
FontManager.GetInstalledFontFamilyNames().Select(name => new FontFamily(name));
/// <summary>
/// Gets the primary family name of the font family.

92
src/Avalonia.Visuals/Media/FontManager.cs

@ -1,99 +1,55 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using Avalonia.Platform;
namespace Avalonia.Media
{
public abstract class FontManager : IFontManagerImpl
public static class FontManager
{
public static readonly FontManager Default = CreateDefaultFontManger();
private static readonly IFontManagerImpl s_platformImpl = GetPlatformImpl();
/// <inheritdoc cref="IFontManagerImpl"/>
public string DefaultFontFamilyName { get; protected set; }
/// <inheritdoc cref="IFontManagerImpl.DefaultFontFamilyName"/>
public static string DefaultFontFamilyName => s_platformImpl.DefaultFontFamilyName;
private static FontManager CreateDefaultFontManger()
{
var platformImpl = AvaloniaLocator.Current.GetService<IFontManagerImpl>();
if(platformImpl == null)
{
return new EmptyFontManager();
}
return new PlatformFontManger(platformImpl);
}
/// <inheritdoc cref="IFontManagerImpl.GetInstalledFontFamilyNames"/>
public static IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false) =>
s_platformImpl.GetInstalledFontFamilyNames(checkForUpdates);
/// <inheritdoc cref="IFontManagerImpl"/>
public abstract IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false);
/// <inheritdoc cref="IFontManagerImpl.GetTypeface"/>
public static Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle) =>
s_platformImpl.GetTypeface(fontFamily, fontWeight, fontStyle);
/// <inheritdoc cref="IFontManagerImpl"/>
public abstract IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface);
/// <inheritdoc cref="IFontManagerImpl"/>
public abstract Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle);
/// <inheritdoc cref="IFontManagerImpl"/>
public abstract Typeface MatchCharacter(int codepoint, FontWeight fontWeight = default,
/// <inheritdoc cref="IFontManagerImpl.MatchCharacter"/>
public static Typeface MatchCharacter(int codepoint, FontWeight fontWeight = default,
FontStyle fontStyle = default,
FontFamily fontFamily = null, CultureInfo culture = null);
FontFamily fontFamily = null, CultureInfo culture = null) =>
s_platformImpl.MatchCharacter(codepoint, fontWeight, fontStyle, fontFamily, culture);
private class PlatformFontManger : FontManager
private static IFontManagerImpl GetPlatformImpl()
{
private readonly IFontManagerImpl _platformImpl;
public PlatformFontManger(IFontManagerImpl platformImpl)
{
_platformImpl = platformImpl;
DefaultFontFamilyName = _platformImpl.DefaultFontFamilyName;
}
public override IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false) =>
_platformImpl.GetInstalledFontFamilyNames(checkForUpdates);
public override IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface) => _platformImpl.CreateGlyphTypeface(typeface);
public override Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle) =>
_platformImpl.GetTypeface(fontFamily, fontWeight, fontStyle);
var platformImpl = AvaloniaLocator.Current.GetService<IFontManagerImpl>();
public override Typeface MatchCharacter(int codepoint, FontWeight fontWeight = default,
FontStyle fontStyle = default,
FontFamily fontFamily = null, CultureInfo culture = null) =>
_platformImpl.MatchCharacter(codepoint, fontWeight, fontStyle, fontFamily, culture);
return platformImpl ?? new EmptyFontManagerImpl();
}
private class EmptyFontManager : FontManager
private class EmptyFontManagerImpl : IFontManagerImpl
{
private readonly string[] _defaultFontFamilies = { "Arial" };
public EmptyFontManager()
{
DefaultFontFamilyName = "Arial";
}
public override IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false)
{
return _defaultFontFamilies;
}
public string DefaultFontFamilyName => "Arial";
public override IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
{
throw new NotSupportedException();
}
public IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false) => new[] { "Arial" };
public override Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
public Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
{
throw new NotSupportedException();
return new Typeface(fontFamily, fontWeight, fontStyle);
}
public override Typeface MatchCharacter(int codepoint, FontWeight fontWeight = default, FontStyle fontStyle = default,
public Typeface MatchCharacter(int codepoint, FontWeight fontWeight = default, FontStyle fontStyle = default,
FontFamily fontFamily = null, CultureInfo culture = null)
{
throw new NotSupportedException();
return null;
}
}
}

5
src/Avalonia.Visuals/Media/GlyphTypeface.cs

@ -9,7 +9,10 @@ namespace Avalonia.Media
{
public class GlyphTypeface : IDisposable
{
public GlyphTypeface(Typeface typeface) : this(FontManager.Default.CreateGlyphTypeface(typeface))
private static readonly IPlatformRenderInterface s_platformRenderInterface =
AvaloniaLocator.Current.GetService<IPlatformRenderInterface>();
public GlyphTypeface(Typeface typeface) : this(s_platformRenderInterface.CreateGlyphTypeface(typeface))
{
}

9
src/Avalonia.Visuals/Platform/IFontManagerImpl.cs

@ -20,15 +20,6 @@ namespace Avalonia.Platform
/// </summary>
IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false);
/// <summary>
/// Creates a glyph typeface for specified typeface.
/// </summary>
/// <param name="typeface">The typeface.</param>
/// <returns>
/// The glyph typeface implementation.
/// </returns>
IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface);
/// <summary>
/// Get a typeface from specified parameters.
/// </summary>

9
src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs

@ -111,5 +111,14 @@ namespace Avalonia.Platform
/// <param name="stride">The number of bytes per row.</param>
/// <returns>An <see cref="IBitmapImpl"/>.</returns>
IBitmapImpl LoadBitmap(PixelFormat format, IntPtr data, PixelSize size, Vector dpi, int stride);
/// <summary>
/// Creates a glyph typeface for specified typeface.
/// </summary>
/// <param name="typeface">The typeface.</param>
/// <returns>
/// The glyph typeface implementation.
/// </returns>
IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface);
}
}

9
src/Skia/Avalonia.Skia/FontManagerImpl.cs

@ -1,7 +1,6 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using Avalonia.Media;
@ -14,9 +13,6 @@ namespace Avalonia.Skia
{
private SKFontManager _skFontManager = SKFontManager.Default;
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
public FontManagerImpl()
{
DefaultFontFamilyName = SKTypeface.Default.FamilyName;
@ -34,11 +30,6 @@ namespace Avalonia.Skia
return _skFontManager.FontFamilies;
}
public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
{
return _glyphTypefaceCache.GetOrAdd(typeface, new GlyphTypefaceImpl(typeface));
}
public Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
{
return TypefaceCache.Get(fontFamily.Name, fontWeight, fontStyle).Typeface;

9
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -2,6 +2,7 @@
// 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.IO;
using Avalonia.Controls.Platform.Surfaces;
@ -17,6 +18,9 @@ namespace Avalonia.Skia
/// </summary>
internal class PlatformRenderInterface : IPlatformRenderInterface
{
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
private readonly ICustomSkiaGpu _customSkiaGpu;
private GRContext GrContext { get; }
@ -150,5 +154,10 @@ namespace Avalonia.Skia
{
return new WriteableBitmapImpl(size, dpi, format);
}
public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
{
return _glyphTypefaceCache.GetOrAdd(typeface, new GlyphTypefaceImpl(typeface));
}
}
}

8
src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

@ -2,6 +2,7 @@
// 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.IO;
using Avalonia.Controls;
@ -27,6 +28,8 @@ namespace Avalonia.Direct2D1
{
public class Direct2D1Platform : IPlatformRenderInterface
{
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
private static readonly Direct2D1Platform s_instance = new Direct2D1Platform();
public static SharpDX.Direct3D11.Device Direct3D11Device { get; private set; }
@ -190,5 +193,10 @@ namespace Avalonia.Direct2D1
{
return new WicBitmapImpl(format, data, size, dpi, stride);
}
public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
{
return _glyphTypefaceCache.GetOrAdd(typeface, new GlyphTypefaceImpl(typeface));
}
}
}

9
src/Windows/Avalonia.Direct2D1/Media/FontManagerImpl.cs

@ -1,7 +1,6 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using Avalonia.Media;
@ -15,9 +14,6 @@ namespace Avalonia.Direct2D1.Media
{
internal class FontManagerImpl : IFontManagerImpl
{
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
public FontManagerImpl()
{
//ToDo: Implement a real lookup of the system's default font.
@ -40,11 +36,6 @@ namespace Avalonia.Direct2D1.Media
return fontFamilies;
}
public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
{
return _glyphTypefaceCache.GetOrAdd(typeface, new GlyphTypefaceImpl(typeface));
}
public Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
{
//ToDo: Implement caching.

Loading…
Cancel
Save