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() static FontFamily()
{ {
Default = new FontFamily(FontManager.Default.DefaultFontFamilyName); Default = new FontFamily(FontManager.DefaultFontFamilyName);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -60,8 +60,11 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Represents all font families in the system. This can be an expensive call depending on platform implementation. /// Represents all font families in the system. This can be an expensive call depending on platform implementation.
/// </summary> /// </summary>
/// <remarks>
/// Consider using the new <see cref="FontManager"/> instead.
/// </remarks>
public static IEnumerable<FontFamily> SystemFontFamilies => public static IEnumerable<FontFamily> SystemFontFamilies =>
FontManager.Default.GetInstalledFontFamilyNames().Select(name => new FontFamily(name)); FontManager.GetInstalledFontFamilyNames().Select(name => new FontFamily(name));
/// <summary> /// <summary>
/// Gets the primary family name of the font family. /// 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. // 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. // 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.Collections.Generic;
using System.Globalization; using System.Globalization;
using Avalonia.Platform; using Avalonia.Platform;
namespace Avalonia.Media 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"/> /// <inheritdoc cref="IFontManagerImpl.DefaultFontFamilyName"/>
public string DefaultFontFamilyName { get; protected set; } public static string DefaultFontFamilyName => s_platformImpl.DefaultFontFamilyName;
private static FontManager CreateDefaultFontManger() /// <inheritdoc cref="IFontManagerImpl.GetInstalledFontFamilyNames"/>
{ public static IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false) =>
var platformImpl = AvaloniaLocator.Current.GetService<IFontManagerImpl>(); s_platformImpl.GetInstalledFontFamilyNames(checkForUpdates);
if(platformImpl == null)
{
return new EmptyFontManager();
}
return new PlatformFontManger(platformImpl);
}
/// <inheritdoc cref="IFontManagerImpl"/> /// <inheritdoc cref="IFontManagerImpl.GetTypeface"/>
public abstract IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false); public static Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle) =>
s_platformImpl.GetTypeface(fontFamily, fontWeight, fontStyle);
/// <inheritdoc cref="IFontManagerImpl"/> /// <inheritdoc cref="IFontManagerImpl.MatchCharacter"/>
public abstract IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface); public static Typeface MatchCharacter(int codepoint, FontWeight fontWeight = default,
/// <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,
FontStyle fontStyle = 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; var platformImpl = AvaloniaLocator.Current.GetService<IFontManagerImpl>();
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);
public override Typeface MatchCharacter(int codepoint, FontWeight fontWeight = default, return platformImpl ?? new EmptyFontManagerImpl();
FontStyle fontStyle = default,
FontFamily fontFamily = null, CultureInfo culture = null) =>
_platformImpl.MatchCharacter(codepoint, fontWeight, fontStyle, fontFamily, culture);
} }
private class EmptyFontManager : FontManager private class EmptyFontManagerImpl : IFontManagerImpl
{ {
private readonly string[] _defaultFontFamilies = { "Arial" }; public string DefaultFontFamilyName => "Arial";
public EmptyFontManager()
{
DefaultFontFamilyName = "Arial";
}
public override IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false)
{
return _defaultFontFamilies;
}
public override IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface) public IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false) => new[] { "Arial" };
{
throw new NotSupportedException();
}
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) 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 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> /// </summary>
IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false); 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> /// <summary>
/// Get a typeface from specified parameters. /// Get a typeface from specified parameters.
/// </summary> /// </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> /// <param name="stride">The number of bytes per row.</param>
/// <returns>An <see cref="IBitmapImpl"/>.</returns> /// <returns>An <see cref="IBitmapImpl"/>.</returns>
IBitmapImpl LoadBitmap(PixelFormat format, IntPtr data, PixelSize size, Vector dpi, int stride); 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. // 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. // 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.Collections.Generic;
using System.Globalization; using System.Globalization;
using Avalonia.Media; using Avalonia.Media;
@ -14,9 +13,6 @@ namespace Avalonia.Skia
{ {
private SKFontManager _skFontManager = SKFontManager.Default; private SKFontManager _skFontManager = SKFontManager.Default;
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
public FontManagerImpl() public FontManagerImpl()
{ {
DefaultFontFamilyName = SKTypeface.Default.FamilyName; DefaultFontFamilyName = SKTypeface.Default.FamilyName;
@ -34,11 +30,6 @@ namespace Avalonia.Skia
return _skFontManager.FontFamilies; return _skFontManager.FontFamilies;
} }
public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
{
return _glyphTypefaceCache.GetOrAdd(typeface, new GlyphTypefaceImpl(typeface));
}
public Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle) public Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
{ {
return TypefaceCache.Get(fontFamily.Name, fontWeight, fontStyle).Typeface; 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. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Controls.Platform.Surfaces;
@ -17,6 +18,9 @@ namespace Avalonia.Skia
/// </summary> /// </summary>
internal class PlatformRenderInterface : IPlatformRenderInterface internal class PlatformRenderInterface : IPlatformRenderInterface
{ {
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
private readonly ICustomSkiaGpu _customSkiaGpu; private readonly ICustomSkiaGpu _customSkiaGpu;
private GRContext GrContext { get; } private GRContext GrContext { get; }
@ -150,5 +154,10 @@ namespace Avalonia.Skia
{ {
return new WriteableBitmapImpl(size, dpi, format); 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. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Avalonia.Controls; using Avalonia.Controls;
@ -27,6 +28,8 @@ namespace Avalonia.Direct2D1
{ {
public class Direct2D1Platform : IPlatformRenderInterface public class Direct2D1Platform : IPlatformRenderInterface
{ {
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
private static readonly Direct2D1Platform s_instance = new Direct2D1Platform(); private static readonly Direct2D1Platform s_instance = new Direct2D1Platform();
public static SharpDX.Direct3D11.Device Direct3D11Device { get; private set; } public static SharpDX.Direct3D11.Device Direct3D11Device { get; private set; }
@ -190,5 +193,10 @@ namespace Avalonia.Direct2D1
{ {
return new WicBitmapImpl(format, data, size, dpi, stride); 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. // 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. // 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.Collections.Generic;
using System.Globalization; using System.Globalization;
using Avalonia.Media; using Avalonia.Media;
@ -15,9 +14,6 @@ namespace Avalonia.Direct2D1.Media
{ {
internal class FontManagerImpl : IFontManagerImpl internal class FontManagerImpl : IFontManagerImpl
{ {
private readonly ConcurrentDictionary<Typeface, GlyphTypefaceImpl> _glyphTypefaceCache =
new ConcurrentDictionary<Typeface, GlyphTypefaceImpl>();
public FontManagerImpl() public FontManagerImpl()
{ {
//ToDo: Implement a real lookup of the system's default font. //ToDo: Implement a real lookup of the system's default font.
@ -40,11 +36,6 @@ namespace Avalonia.Direct2D1.Media
return fontFamilies; return fontFamilies;
} }
public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
{
return _glyphTypefaceCache.GetOrAdd(typeface, new GlyphTypefaceImpl(typeface));
}
public Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle) public Typeface GetTypeface(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
{ {
//ToDo: Implement caching. //ToDo: Implement caching.

Loading…
Cancel
Save