From d15aeef92bc42c2551b0bb7ac93f3798baed151e Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Mon, 30 Apr 2018 08:59:42 +0200 Subject: [PATCH 01/36] Initial --- src/Avalonia.Visuals/Media/FontFamily.cs | 99 ++++++++++++++++++++++++ src/Avalonia.Visuals/Media/Typeface.cs | 33 ++++---- 2 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 src/Avalonia.Visuals/Media/FontFamily.cs diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs new file mode 100644 index 0000000000..ea2d3701b2 --- /dev/null +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -0,0 +1,99 @@ +// 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.Collections.ObjectModel; + +namespace Avalonia.Media +{ + public class FontFamily + { + private IFontFamily _loadedFamily; + + public FontFamily(string familyName) : this(familyName, null) { } + + public FontFamily(string familyName, Uri baseUri) + { + if (familyName == null) throw new ArgumentNullException(nameof(familyName)); + + FontFamilyKey = new FontFamilyKey(familyName, baseUri); + } + + public string Name => FontFamilyKey.FriendlyName; + + public Uri BaseUri => FontFamilyKey.BaseUri; + + internal FontFamilyKey FontFamilyKey { get; } + + internal IFontFamily LoadedFamily + { + get + { + if (_loadedFamily == null) + { + _loadedFamily = AvaloniaLocator.Current.GetService().LoadFontFamily(FontFamilyKey); + } + + return _loadedFamily; + } + } + + public IEnumerable AvailableTypefaces => LoadedFamily.SupportedTypefaces; + } + + public class FamilyTypeface + { + public FamilyTypeface() + { + FontStyle = FontStyle.Normal; + FontWeight = FontWeight.Normal; + } + + public FamilyTypeface(Typeface typeface) + { + FontStyle = typeface.Style; + FontWeight = typeface.Weight; + } + + public FontStyle FontStyle { get; } + public FontWeight FontWeight { get; } + } + + public class FontFamilyKey + { + public FontFamilyKey(string friendlyName) : this(friendlyName, null) { } + + public FontFamilyKey(string friendlyName, Uri baseUri) + { + FriendlyName = friendlyName; + BaseUri = baseUri; + } + + public string FriendlyName { get; } + + public Uri BaseUri { get; } + } + + internal interface IFontFamily + { + IEnumerable SupportedTypefaces { get; } + } + + internal class SystemFont : IFontFamily + { + public SystemFont() : this(new List { new FamilyTypeface() }) { } + + public SystemFont(IEnumerable supportedTypefaces) + { + SupportedTypefaces = new ReadOnlyCollection(new List(supportedTypefaces)); + } + + public IEnumerable SupportedTypefaces { get; } + } + + internal interface IFontFamilyLoader + { + IFontFamily LoadFontFamily(FontFamilyKey fontFamilyKey); + } +} diff --git a/src/Avalonia.Visuals/Media/Typeface.cs b/src/Avalonia.Visuals/Media/Typeface.cs index 12540b67e7..c85144d48e 100644 --- a/src/Avalonia.Visuals/Media/Typeface.cs +++ b/src/Avalonia.Visuals/Media/Typeface.cs @@ -7,18 +7,8 @@ namespace Avalonia.Media /// public class Typeface { - /// - /// Initializes a new instance of the class. - /// - /// The name of the font family. - /// The font size, in DIPs. - /// The font style. - /// The font weight. - public Typeface( - string fontFamilyName, - double fontSize, - FontStyle style = FontStyle.Normal, - FontWeight weight = FontWeight.Normal) + public Typeface(FontFamily fontFamily, double fontSize, FontStyle style = FontStyle.Normal, + FontWeight weight = FontWeight.Normal) { if (fontSize <= 0) { @@ -30,16 +20,29 @@ namespace Avalonia.Media throw new ArgumentException("Font weight must be > 0."); } - FontFamilyName = fontFamilyName; + FontFamily = fontFamily; FontSize = fontSize; Style = style; Weight = weight; } /// - /// Gets the name of the font family. + /// Initializes a new instance of the class. + /// + /// The name of the font family. + /// The font size, in DIPs. + /// The font style. + /// The font weight. + public Typeface( + string fontFamilyName, + double fontSize, + FontStyle style = FontStyle.Normal, + FontWeight weight = FontWeight.Normal) : this(new FontFamily(fontFamilyName), fontSize, style, weight) { } + + /// + /// Gets the font family. /// - public string FontFamilyName { get; } + public FontFamily FontFamily { get; } /// /// Gets the size of the font in DIPs. From 3b308d8d19149dec7cc4db594e062bdc1a06593a Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Mon, 30 Apr 2018 23:01:26 +0200 Subject: [PATCH 02/36] Direct2D1 experimental --- samples/ControlCatalog/Assets/kooten.ttf | Bin 0 -> 42164 bytes samples/ControlCatalog/ControlCatalog.csproj | 3 + samples/ControlCatalog/Pages/BorderPage.xaml | 40 +-- .../Primitives/TemplatedControl.cs | 4 +- src/Avalonia.Controls/TextBlock.cs | 10 +- src/Avalonia.Visuals/Media/FontFamily.cs | 27 +- src/Avalonia.Visuals/Media/Typeface.cs | 4 +- .../Rendering/RendererBase.cs | 2 +- .../Avalonia.Markup.Xaml.csproj | 1 + .../Converters/FontFamilyTypeConverter.cs | 40 +++ .../AvaloniaDefaultTypeConverters.cs | 1 + src/Skia/Avalonia.Skia/FormattedTextImpl.cs | 8 +- .../Media/FormattedTextImpl.cs | 303 +++++++++++++++++- 13 files changed, 383 insertions(+), 60 deletions(-) create mode 100644 samples/ControlCatalog/Assets/kooten.ttf create mode 100644 src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs diff --git a/samples/ControlCatalog/Assets/kooten.ttf b/samples/ControlCatalog/Assets/kooten.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3b052635fbc7c71317e8f90f450c3ac411f7554c GIT binary patch literal 42164 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�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 iC%0|Wwil1CT4JwVaCgR + + + diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml index a81bd13ddd..a95bc945ae 100644 --- a/samples/ControlCatalog/Pages/BorderPage.xaml +++ b/samples/ControlCatalog/Pages/BorderPage.xaml @@ -1,32 +1,36 @@ - - Border - A control which decorates a child with a border and background + + Border + A control which decorates a child with a border and background - - - Border - - + Border + + - Border and Background - - Border and Background + + - Rounded Corners - - Rounded Corners + + - Rounded Corners - - - + + Rounded Corners + Rounded Corners + Rounded Corners + + + + \ No newline at end of file diff --git a/src/Avalonia.Controls/Primitives/TemplatedControl.cs b/src/Avalonia.Controls/Primitives/TemplatedControl.cs index 77735f3f12..65b245e36c 100644 --- a/src/Avalonia.Controls/Primitives/TemplatedControl.cs +++ b/src/Avalonia.Controls/Primitives/TemplatedControl.cs @@ -38,7 +38,7 @@ namespace Avalonia.Controls.Primitives /// /// Defines the property. /// - public static readonly StyledProperty FontFamilyProperty = + public static readonly StyledProperty FontFamilyProperty = TextBlock.FontFamilyProperty.AddOwner(); /// @@ -141,7 +141,7 @@ namespace Avalonia.Controls.Primitives /// /// Gets or sets the font family used to draw the control's text. /// - public string FontFamily + public FontFamily FontFamily { get { return GetValue(FontFamilyProperty); } set { SetValue(FontFamilyProperty, value); } diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index 88a9fe077d..bb2bae2ac3 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/src/Avalonia.Controls/TextBlock.cs @@ -28,10 +28,10 @@ namespace Avalonia.Controls /// /// Defines the property. /// - public static readonly AttachedProperty FontFamilyProperty = - AvaloniaProperty.RegisterAttached( + public static readonly AttachedProperty FontFamilyProperty = + AvaloniaProperty.RegisterAttached( nameof(FontFamily), - defaultValue: "Courier New", + defaultValue: new FontFamily("Courier New"), inherits: true); /// @@ -146,7 +146,7 @@ namespace Avalonia.Controls /// /// Gets or sets the font family. /// - public string FontFamily + public FontFamily FontFamily { get { return GetValue(FontFamilyProperty); } set { SetValue(FontFamilyProperty, value); } @@ -227,7 +227,7 @@ namespace Avalonia.Controls /// /// The control. /// The font family. - public static string GetFontFamily(Control control) + public static FontFamily GetFontFamily(Control control) { return control.GetValue(FontFamilyProperty); } diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index ea2d3701b2..d702a311a2 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -26,18 +26,9 @@ namespace Avalonia.Media internal FontFamilyKey FontFamilyKey { get; } - internal IFontFamily LoadedFamily - { - get - { - if (_loadedFamily == null) - { - _loadedFamily = AvaloniaLocator.Current.GetService().LoadFontFamily(FontFamilyKey); - } - - return _loadedFamily; - } - } + internal IFontFamily LoadedFamily => _loadedFamily ?? (_loadedFamily = AvaloniaLocator.Current + .GetService() + .LoadFontFamily(FontFamilyKey)); public IEnumerable AvailableTypefaces => LoadedFamily.SupportedTypefaces; } @@ -92,6 +83,18 @@ namespace Avalonia.Media public IEnumerable SupportedTypefaces { get; } } + internal class CustomFont : IFontFamily + { + public CustomFont() : this(new List { new FamilyTypeface() }) { } + + public CustomFont(IEnumerable supportedTypefaces) + { + SupportedTypefaces = new ReadOnlyCollection(new List(supportedTypefaces)); + } + + public IEnumerable SupportedTypefaces { get; } + } + internal interface IFontFamilyLoader { IFontFamily LoadFontFamily(FontFamilyKey fontFamilyKey); diff --git a/src/Avalonia.Visuals/Media/Typeface.cs b/src/Avalonia.Visuals/Media/Typeface.cs index c85144d48e..6baec1a246 100644 --- a/src/Avalonia.Visuals/Media/Typeface.cs +++ b/src/Avalonia.Visuals/Media/Typeface.cs @@ -7,7 +7,7 @@ namespace Avalonia.Media /// public class Typeface { - public Typeface(FontFamily fontFamily, double fontSize, FontStyle style = FontStyle.Normal, + public Typeface(FontFamily fontFamily, double fontSize = 12, FontStyle style = FontStyle.Normal, FontWeight weight = FontWeight.Normal) { if (fontSize <= 0) @@ -35,7 +35,7 @@ namespace Avalonia.Media /// The font weight. public Typeface( string fontFamilyName, - double fontSize, + double fontSize = 12, FontStyle style = FontStyle.Normal, FontWeight weight = FontWeight.Normal) : this(new FontFamily(fontFamilyName), fontSize, style, weight) { } diff --git a/src/Avalonia.Visuals/Rendering/RendererBase.cs b/src/Avalonia.Visuals/Rendering/RendererBase.cs index eac362e997..ed464ec7f9 100644 --- a/src/Avalonia.Visuals/Rendering/RendererBase.cs +++ b/src/Avalonia.Visuals/Rendering/RendererBase.cs @@ -18,7 +18,7 @@ namespace Avalonia.Rendering { _fpsText = new FormattedText { - Typeface = new Typeface(null, 18), + Typeface = s_fpsTypeface }; } diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index bd6acfdad1..6447dca2b2 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -32,6 +32,7 @@ + diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs new file mode 100644 index 0000000000..51d35fabff --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs @@ -0,0 +1,40 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using Avalonia.Media; + +namespace Avalonia.Markup.Xaml.Converters +{ + public class FontFamilyTypeConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + var s = (string)value; + + if (string.IsNullOrEmpty(s)) throw new ArgumentException("Specified family is not supported."); + + var fontFamilyExpression = s.Split('#'); + + switch (fontFamilyExpression.Length) + { + case 1: + { + return new FontFamily(fontFamilyExpression[0]); + } + case 2: + { + return new FontFamily(fontFamilyExpression[1], new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute)); + } + default: + { + throw new ArgumentException("Specified family is not supported."); + } + } + } + } +} \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs index 1ae24c8a34..6b523cae6f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs @@ -49,6 +49,7 @@ namespace Avalonia.Markup.Xaml.PortableXaml { typeof(Cursor), typeof(CursorTypeConverter) }, { typeof(WindowIcon), typeof(IconTypeConverter) }, //{ typeof(FontWeight), typeof(FontWeightConverter) }, + { typeof(FontFamily), typeof(FontFamilyTypeConverter)} }; public static Type GetTypeConverter(Type type) diff --git a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs index f22722a0b5..baf3a210d5 100644 --- a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs +++ b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs @@ -26,9 +26,9 @@ namespace Avalonia.Skia Text = Text.Replace((char)0, (char)0x200B); var skiaTypeface = TypefaceCache.GetTypeface( - typeface?.FontFamilyName ?? "monospace", - typeface?.Style ?? FontStyle.Normal, - typeface?.Weight ?? FontWeight.Normal); + typeface.FontFamily.Name ?? "monospace", + typeface.Style, + typeface.Weight); _paint = new SKPaint(); @@ -40,7 +40,7 @@ namespace Avalonia.Skia _paint.LcdRenderText = true; _paint.SubpixelText = true; _paint.Typeface = skiaTypeface; - _paint.TextSize = (float)(typeface?.FontSize ?? 12); + _paint.TextSize = (float)typeface.FontSize; _paint.TextAlign = textAlignment.ToSKTextAlign(); _wrapping = wrapping; diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 5578abc32c..2b3aa31c64 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using Avalonia.Media; using Avalonia.Platform; +using SharpDX; using DWrite = SharpDX.DirectWrite; namespace Avalonia.Direct2D1.Media @@ -21,28 +23,56 @@ namespace Avalonia.Direct2D1.Media IReadOnlyList spans) { Text = text; + var factory = AvaloniaLocator.Current.GetService(); - using (var format = new DWrite.TextFormat( - factory, - typeface?.FontFamilyName ?? "Courier New", - (DWrite.FontWeight)(typeface?.Weight ?? FontWeight.Normal), - (DWrite.FontStyle)(typeface?.Style ?? FontStyle.Normal), - (float)(typeface?.FontSize ?? 12))) + if (typeface.FontFamily.BaseUri != null) { - format.WordWrapping = wrapping == TextWrapping.Wrap ? - DWrite.WordWrapping.Wrap : - DWrite.WordWrapping.NoWrap; + var fontLoader = new ResourceFontLoader(factory, typeface.FontFamily.BaseUri); + + var fontCollection = new DWrite.FontCollection(factory, fontLoader, fontLoader.Key); + + using (var textFormat = + new DWrite.TextFormat(factory, typeface.FontFamily.Name, fontCollection, DWrite.FontWeight.Normal, + DWrite.FontStyle.Normal, DWrite.FontStretch.Normal, (float)typeface.FontSize)) + { + textFormat.TextAlignment = DWrite.TextAlignment.Center; + textFormat.ParagraphAlignment = DWrite.ParagraphAlignment.Center; + + textFormat.WordWrapping = wrapping == TextWrapping.Wrap ? + DWrite.WordWrapping.Wrap : + DWrite.WordWrapping.NoWrap; - TextLayout = new DWrite.TextLayout( + TextLayout = new DWrite.TextLayout(factory, Text ?? string.Empty, textFormat, (float)constraint.Width, + (float)constraint.Height) + { + TextAlignment = textAlignment.ToDirect2D() + }; + } + } + else + { + using (var format = new DWrite.TextFormat( factory, - text ?? string.Empty, - format, - (float)constraint.Width, - (float)constraint.Height) + typeface?.FontFamily.Name ?? "Courier New", + (DWrite.FontWeight)(typeface.Weight), + (DWrite.FontStyle)(typeface.Style), + (float)typeface.FontSize)) { - TextAlignment = textAlignment.ToDirect2D() - }; + format.WordWrapping = wrapping == TextWrapping.Wrap ? + DWrite.WordWrapping.Wrap : + DWrite.WordWrapping.NoWrap; + + TextLayout = new DWrite.TextLayout( + factory, + text ?? string.Empty, + format, + (float)constraint.Width, + (float)constraint.Height) + { + TextAlignment = textAlignment.ToDirect2D() + }; + } } if (spans != null) @@ -140,4 +170,245 @@ namespace Avalonia.Direct2D1.Media return new Size(width, TextLayout.Metrics.Height); } } + + public class ResourceFontLoader : CallbackBase, DWrite.FontCollectionLoader, DWrite.FontFileLoader + { + private readonly List _fontStreams = new List(); + private readonly List _enumerators = new List(); + private readonly DataStream _keyStream; + private readonly DWrite.Factory _factory; + + + /// + /// Initializes a new instance of the class. + /// + /// The factory. + /// + public ResourceFontLoader(DWrite.Factory factory, Uri fontResource) + { + _factory = factory; + + var assets = AvaloniaLocator.Current.GetService(); + + var resourceStream = assets.Open(fontResource); + + var dataStream = new DataStream((int)resourceStream.Length, true, true); + + resourceStream.CopyTo(dataStream); + + dataStream.Position = 0; + + _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); + + for (int i = 0; i < _fontStreams.Count; i++) + { + _keyStream.Write(i); + } + + _keyStream.Position = 0; + + // Register the + _factory.RegisterFontFileLoader(this); + _factory.RegisterFontCollectionLoader(this); + } + + + /// + /// Gets the key used to identify the FontCollection as well as storing index for fonts. + /// + /// The key. + public DataStream Key + { + get + { + return _keyStream; + } + } + + /// + /// Creates a font file enumerator object that encapsulates a collection of font files. The font system calls back to this interface to create a font collection. + /// + /// Pointer to the object that was used to create the current font collection. + /// A font collection key that uniquely identifies the collection of font files within the scope of the font collection loader being used. The buffer allocated for this key must be at least the size, in bytes, specified by collectionKeySize. + /// + /// a reference to the newly created font file enumerator. + /// + /// HRESULT IDWriteFontCollectionLoader::CreateEnumeratorFromKey([None] IDWriteFactory* factory,[In, Buffer] const void* collectionKey,[None] int collectionKeySize,[Out] IDWriteFontFileEnumerator** fontFileEnumerator) + DWrite.FontFileEnumerator DWrite.FontCollectionLoader.CreateEnumeratorFromKey(DWrite.Factory factory, DataPointer collectionKey) + { + var enumerator = new ResourceFontFileEnumerator(factory, this, collectionKey); + + _enumerators.Add(enumerator); + + return enumerator; + } + + /// + /// Creates a font file stream object that encapsulates an open file resource. + /// + /// A reference to a font file reference key that uniquely identifies the font file resource within the scope of the font loader being used. The buffer allocated for this key must at least be the size, in bytes, specified by fontFileReferenceKeySize. + /// + /// a reference to the newly created object. + /// + /// + /// The resource is closed when the last reference to fontFileStream is released. + /// + /// HRESULT IDWriteFontFileLoader::CreateStreamFromKey([In, Buffer] const void* fontFileReferenceKey,[None] int fontFileReferenceKeySize,[Out] IDWriteFontFileStream** fontFileStream) + DWrite.FontFileStream DWrite.FontFileLoader.CreateStreamFromKey(DataPointer fontFileReferenceKey) + { + var index = SharpDX.Utilities.Read(fontFileReferenceKey.Pointer); + + return _fontStreams[index]; + } + } + + /// + /// This FontFileStream implem is reading data from a . + /// + public class ResourceFontFileStream : CallbackBase, DWrite.FontFileStream + { + private readonly DataStream _stream; + + /// + /// Initializes a new instance of the class. + /// + /// The stream. + public ResourceFontFileStream(DataStream stream) + { + this._stream = stream; + } + + /// + /// Reads a fragment from a font file. + /// + /// When this method returns, contains an address of a reference to the start of the font file fragment. This parameter is passed uninitialized. + /// The offset of the fragment, in bytes, from the beginning of the font file. + /// The size of the file fragment, in bytes. + /// When this method returns, contains the address of + /// + /// Note that ReadFileFragment implementations must check whether the requested font file fragment is within the file bounds. Otherwise, an error should be returned from ReadFileFragment. {{DirectWrite}} may invoke methods on the same object from multiple threads simultaneously. Therefore, ReadFileFragment implementations that rely on internal mutable state must serialize access to such state across multiple threads. For example, an implementation that uses separate Seek and Read operations to read a file fragment must place the code block containing Seek and Read calls under a lock or a critical section. + /// + /// HRESULT IDWriteFontFileStream::ReadFileFragment([Out, Buffer] const void** fragmentStart,[None] __int64 fileOffset,[None] __int64 fragmentSize,[Out] void** fragmentContext) + void DWrite.FontFileStream.ReadFileFragment(out IntPtr fragmentStart, long fileOffset, long fragmentSize, out IntPtr fragmentContext) + { + lock (this) + { + fragmentContext = IntPtr.Zero; + + _stream.Position = fileOffset; + + fragmentStart = _stream.PositionPointer; + + } + } + + /// + /// Releases a fragment from a file. + /// + /// A reference to the client-defined context of a font fragment returned from {{ReadFileFragment}}. + /// void IDWriteFontFileStream::ReleaseFileFragment([None] void* fragmentContext) + void DWrite.FontFileStream.ReleaseFileFragment(IntPtr fragmentContext) + { + // Nothing to release. No context are used + } + + /// + /// Obtains the total size of a file. + /// + /// the total size of the file. + /// + /// Implementing GetFileSize() for asynchronously loaded font files may require downloading the complete file contents. Therefore, this method should be used only for operations that either require a complete font file to be loaded (for example, copying a font file) or that need to make decisions based on the value of the file size (for example, validation against a persisted file size). + /// + /// HRESULT IDWriteFontFileStream::GetFileSize([Out] __int64* fileSize) + long DWrite.FontFileStream.GetFileSize() + { + return _stream.Length; + } + + /// + /// Obtains the last modified time of the file. + /// + /// + /// the last modified time of the file in the format that represents the number of 100-nanosecond intervals since January 1, 1601 (UTC). + /// + /// + /// The "last modified time" is used by DirectWrite font selection algorithms to determine whether one font resource is more up to date than another one. + /// + /// HRESULT IDWriteFontFileStream::GetLastWriteTime([Out] __int64* lastWriteTime) + long DWrite.FontFileStream.GetLastWriteTime() + { + return 0; + } + } + + /// + /// Resource FontFileEnumerator. + /// + public class ResourceFontFileEnumerator : CallbackBase, DWrite.FontFileEnumerator + { + private DWrite.Factory _factory; + private DWrite.FontFileLoader _loader; + private DataStream keyStream; + private DWrite.FontFile _currentFontFile; + + /// + /// Initializes a new instance of the class. + /// + /// The factory. + /// The loader. + /// The key. + public ResourceFontFileEnumerator(DWrite.Factory factory, DWrite.FontFileLoader loader, DataPointer key) + { + _factory = factory; + + _loader = loader; + + keyStream = new DataStream(key.Pointer, key.Size, true, false); + } + + /// + /// Advances to the next font file in the collection. When it is first created, the enumerator is positioned before the first element of the collection and the first call to MoveNext advances to the first file. + /// + /// + /// the value TRUE if the enumerator advances to a file; otherwise, FALSE if the enumerator advances past the last file in the collection. + /// + /// HRESULT IDWriteFontFileEnumerator::MoveNext([Out] BOOL* hasCurrentFile) + bool DWrite.FontFileEnumerator.MoveNext() + { + bool moveNext = keyStream.RemainingLength != 0; + + if (moveNext) + { + if (_currentFontFile != null) + { + _currentFontFile.Dispose(); + } + + _currentFontFile = new DWrite.FontFile(_factory, keyStream.PositionPointer, 4, _loader); + + keyStream.Position += 4; + } + + return moveNext; + } + + /// + /// Gets a reference to the current font file. + /// + /// + /// a reference to the newly created object. + /// HRESULT IDWriteFontFileEnumerator::GetCurrentFontFile([Out] IDWriteFontFile** fontFile) + DWrite.FontFile DWrite.FontFileEnumerator.CurrentFontFile + { + get + { + ((IUnknown)_currentFontFile).AddReference(); + + return _currentFontFile; + } + } + } } From 9f29e9a8f4f3ec24193d5c850315163069c2092b Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 1 May 2018 17:43:13 +0200 Subject: [PATCH 03/36] caching --- samples/ControlCatalog.Desktop/Program.cs | 4 +- src/Avalonia.Visuals/Media/FontFamily.cs | 137 +++++++++++++----- .../Converters/FontFamilyTypeConverter.cs | 38 ++++- .../Media/FormattedTextImpl.cs | 6 +- 4 files changed, 147 insertions(+), 38 deletions(-) diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index a2048005a4..df17aabb00 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -3,6 +3,7 @@ using System.Linq; using Avalonia; using Avalonia.Controls; using Avalonia.Logging.Serilog; +using Avalonia.Media; using Avalonia.Platform; using Serilog; @@ -15,6 +16,7 @@ namespace ControlCatalog { // TODO: Make this work with GTK/Skia/Cairo depending on command-line args // again. + AvaloniaLocator.CurrentMutable.Bind().ToConstant(new FontFamilyCache()); BuildAvaloniaApp().Start(); } @@ -28,7 +30,7 @@ namespace ControlCatalog { AvaloniaLocator.CurrentMutable .GetService() - .SetDefaultAssembly(typeof(App).Assembly); + .SetDefaultAssembly(typeof(App).Assembly); } } } diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index d702a311a2..9293432461 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -2,15 +2,15 @@ // 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.Collections.ObjectModel; +using System.Linq; namespace Avalonia.Media { public class FontFamily { - private IFontFamily _loadedFamily; - public FontFamily(string familyName) : this(familyName, null) { } public FontFamily(string familyName, Uri baseUri) @@ -25,30 +25,20 @@ namespace Avalonia.Media public Uri BaseUri => FontFamilyKey.BaseUri; internal FontFamilyKey FontFamilyKey { get; } - - internal IFontFamily LoadedFamily => _loadedFamily ?? (_loadedFamily = AvaloniaLocator.Current - .GetService() - .LoadFontFamily(FontFamilyKey)); - - public IEnumerable AvailableTypefaces => LoadedFamily.SupportedTypefaces; } public class FamilyTypeface { - public FamilyTypeface() - { - FontStyle = FontStyle.Normal; - FontWeight = FontWeight.Normal; - } - - public FamilyTypeface(Typeface typeface) + public FamilyTypeface(Uri resourceUri = null, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) { - FontStyle = typeface.Style; - FontWeight = typeface.Weight; + ResourceUri = resourceUri; + FontStyle = fontStyle; + FontWeight = fontWeight; } - public FontStyle FontStyle { get; } + public Uri ResourceUri { get; } public FontWeight FontWeight { get; } + public FontStyle FontStyle { get; } } public class FontFamilyKey @@ -64,39 +54,118 @@ namespace Avalonia.Media public string FriendlyName { get; } public Uri BaseUri { get; } - } - internal interface IFontFamily - { - IEnumerable SupportedTypefaces { get; } + public override int GetHashCode() + { + unchecked + { + var hash = (int)2166136261; + + if (FriendlyName != null) + { + hash = (hash * 16777619) ^ FriendlyName.GetHashCode(); + } + + if (BaseUri != null) + { + hash = (hash * 16777619) ^ BaseUri.GetHashCode(); + } + + return hash; + } + } + + public override bool Equals(object obj) + { + if (!(obj is FontFamilyKey other)) return false; + + if (FriendlyName != other.FriendlyName) return false; + + if (BaseUri != other.BaseUri) return false; + + return true; + } } - internal class SystemFont : IFontFamily + public class FamilyTypefaceKey { - public SystemFont() : this(new List { new FamilyTypeface() }) { } + public FamilyTypefaceKey(FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) + { + FontWeight = fontWeight; + FontStyle = fontStyle; + } + + public FontWeight FontWeight { get; } + + public FontStyle FontStyle { get; } - public SystemFont(IEnumerable supportedTypefaces) + public override int GetHashCode() { - SupportedTypefaces = new ReadOnlyCollection(new List(supportedTypefaces)); + unchecked + { + var hash = (int)2166136261; + + hash = (hash * 16777619) ^ FontWeight.GetHashCode(); + + hash = (hash * 16777619) ^ FontStyle.GetHashCode(); + + return hash; + } } - public IEnumerable SupportedTypefaces { get; } + 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; + } } - internal class CustomFont : IFontFamily + public class CachedFontFamily { - public CustomFont() : this(new List { new FamilyTypeface() }) { } + private readonly ConcurrentDictionary _typefaces = + new ConcurrentDictionary(); + + public IEnumerable SupportedTypefaces => _typefaces.Values; + + public bool TryGetFamilyTypeface(out FamilyTypeface typeface, FontWeight fontWeight = FontWeight.Normal, + FontStyle fontStyle = FontStyle.Normal) + { + return _typefaces.TryGetValue(new FamilyTypefaceKey(fontWeight, fontStyle), out typeface); + } - public CustomFont(IEnumerable supportedTypefaces) + public FamilyTypeface GetOrAddFamilyTypeface(Uri resourceUri, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) { - SupportedTypefaces = new ReadOnlyCollection(new List(supportedTypefaces)); + return _typefaces.GetOrAdd(new FamilyTypefaceKey(fontWeight, fontStyle), x => CreateFamilyTypeface(x, resourceUri)); } - public IEnumerable SupportedTypefaces { get; } + private static FamilyTypeface CreateFamilyTypeface(FamilyTypefaceKey familyTypefaceKey, Uri resourceUri) + { + return new FamilyTypeface(resourceUri, familyTypefaceKey.FontWeight, familyTypefaceKey.FontStyle); + } + } + + public interface IFontFamilyCache + { + CachedFontFamily GetOrAddFontFamily(FontFamily fontFamily); } - internal interface IFontFamilyLoader + public class FontFamilyCache : IFontFamilyCache { - IFontFamily LoadFontFamily(FontFamilyKey fontFamilyKey); + private readonly ConcurrentDictionary _cachedFontFamilies = new ConcurrentDictionary(); + + public CachedFontFamily GetOrAddFontFamily(FontFamily fontFamily) + { + return _cachedFontFamilies.GetOrAdd(fontFamily.FontFamilyKey, CreateCachedFontFamily); + } + + private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) + { + return new CachedFontFamily(); + } } } diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs index 51d35fabff..6689b47c2f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs @@ -20,21 +20,55 @@ namespace Avalonia.Markup.Xaml.Converters var fontFamilyExpression = s.Split('#'); + string familyName; + + Uri baseUri = null; + + var fontWeight = FontWeight.Normal; + + var fontStyle = FontStyle.Normal; + switch (fontFamilyExpression.Length) { case 1: { - return new FontFamily(fontFamilyExpression[0]); + familyName = fontFamilyExpression[0]; + break; } case 2: { - return new FontFamily(fontFamilyExpression[1], new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute)); + baseUri = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); + familyName = fontFamilyExpression[1]; + break; } + //case 3: + // { + // baseUri = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); + // familyName = fontFamilyExpression[1]; + // fontWeight = (FontWeight)Enum.Parse(typeof(FontWeight), fontFamilyExpression[2]); + // break; + // } + //case 4: + // { + // baseUri = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); + // familyName = fontFamilyExpression[1]; + // fontWeight = (FontWeight)Enum.Parse(typeof(FontWeight), fontFamilyExpression[2]); + // fontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), fontFamilyExpression[3]); + // break; + // } default: { throw new ArgumentException("Specified family is not supported."); } } + + var fontFamily = new FontFamily(familyName, baseUri); + + var cachedFontFamily = AvaloniaLocator.Current.GetService().GetOrAddFontFamily(fontFamily); + + cachedFontFamily.GetOrAddFamilyTypeface(baseUri, fontWeight, fontStyle); + + return fontFamily; } } } \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 2b3aa31c64..20fc956b5d 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -28,7 +28,11 @@ namespace Avalonia.Direct2D1.Media if (typeface.FontFamily.BaseUri != null) { - var fontLoader = new ResourceFontLoader(factory, typeface.FontFamily.BaseUri); + var fontFamily = AvaloniaLocator.Current.GetService().GetOrAddFontFamily(typeface.FontFamily); + + fontFamily.TryGetFamilyTypeface(out var familyTypeface); + + var fontLoader = new ResourceFontLoader(factory, familyTypeface.ResourceUri); var fontCollection = new DWrite.FontCollection(factory, fontLoader, fontLoader.Key); From 1ace4293427a3828dbd3bf78b5f58e13efafd7ae Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 1 May 2018 20:24:53 +0200 Subject: [PATCH 04/36] Direct2D1 caching --- samples/ControlCatalog.Desktop/Program.cs | 1 - .../Assets/octin_stencil_free.ttf | Bin 0 -> 103128 bytes samples/ControlCatalog/ControlCatalog.csproj | 1 + samples/ControlCatalog/Pages/BorderPage.xaml | 4 +- src/Avalonia.Visuals/Media/FontFamily.cs | 207 +++++++++--------- .../Converters/FontFamilyTypeConverter.cs | 29 +-- .../Media/FormattedTextImpl.cs | 152 ++++++------- 7 files changed, 181 insertions(+), 213 deletions(-) create mode 100644 samples/ControlCatalog/Assets/octin_stencil_free.ttf diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index df17aabb00..daa6ba69db 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -16,7 +16,6 @@ namespace ControlCatalog { // TODO: Make this work with GTK/Skia/Cairo depending on command-line args // again. - AvaloniaLocator.CurrentMutable.Bind().ToConstant(new FontFamilyCache()); BuildAvaloniaApp().Start(); } diff --git a/samples/ControlCatalog/Assets/octin_stencil_free.ttf b/samples/ControlCatalog/Assets/octin_stencil_free.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6acd53279b776e2b2cbd57f111b685050367ee4f GIT binary patch literal 103128 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 z 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 literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 291c9283be..beb51f42fc 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -13,6 +13,7 @@ + diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml index a95bc945ae..dc0b05686b 100644 --- a/samples/ControlCatalog/Pages/BorderPage.xaml +++ b/samples/ControlCatalog/Pages/BorderPage.xaml @@ -27,8 +27,8 @@ Padding="16"> Rounded Corners - Rounded Corners - Rounded Corners + Rounded Corners + Rounded Corners diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 9293432461..7442619b5c 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -2,50 +2,33 @@ // 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.Collections.ObjectModel; -using System.Linq; namespace Avalonia.Media { public class FontFamily { - public FontFamily(string familyName) : this(familyName, null) { } - - public FontFamily(string familyName, Uri baseUri) + public FontFamily(string familyName = "Courier New", Uri baseUri = null) { if (familyName == null) throw new ArgumentNullException(nameof(familyName)); - FontFamilyKey = new FontFamilyKey(familyName, baseUri); + Key = new FontFamilyKey(familyName, baseUri); } - public string Name => FontFamilyKey.FriendlyName; + public string Name => Key.FriendlyName; - public Uri BaseUri => FontFamilyKey.BaseUri; + public Uri BaseUri => Key.BaseUri; - internal FontFamilyKey FontFamilyKey { get; } - } + public FontFamilyKey Key { get; } - public class FamilyTypeface - { - public FamilyTypeface(Uri resourceUri = null, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) + public override string ToString() { - ResourceUri = resourceUri; - FontStyle = fontStyle; - FontWeight = fontWeight; + return Key.ToString(); } - - public Uri ResourceUri { get; } - public FontWeight FontWeight { get; } - public FontStyle FontStyle { get; } } public class FontFamilyKey { - public FontFamilyKey(string friendlyName) : this(friendlyName, null) { } - - public FontFamilyKey(string friendlyName, Uri baseUri) + public FontFamilyKey(string friendlyName, Uri baseUri = null) { FriendlyName = friendlyName; BaseUri = baseUri; @@ -85,87 +68,111 @@ namespace Avalonia.Media return true; } - } - 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() + public override string ToString() { - unchecked + if (BaseUri != null) { - var hash = (int)2166136261; - - hash = (hash * 16777619) ^ FontWeight.GetHashCode(); - - hash = (hash * 16777619) ^ FontStyle.GetHashCode(); - - return hash; + return BaseUri + "#" + FriendlyName; } - } - - 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; + return FriendlyName; } } - public class CachedFontFamily - { - private readonly ConcurrentDictionary _typefaces = - new ConcurrentDictionary(); - - public IEnumerable SupportedTypefaces => _typefaces.Values; - - public bool TryGetFamilyTypeface(out FamilyTypeface typeface, FontWeight fontWeight = FontWeight.Normal, - FontStyle fontStyle = FontStyle.Normal) - { - return _typefaces.TryGetValue(new FamilyTypefaceKey(fontWeight, fontStyle), out typeface); - } - - public FamilyTypeface GetOrAddFamilyTypeface(Uri resourceUri, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) - { - return _typefaces.GetOrAdd(new FamilyTypefaceKey(fontWeight, fontStyle), x => CreateFamilyTypeface(x, resourceUri)); - } - - private static FamilyTypeface CreateFamilyTypeface(FamilyTypefaceKey familyTypefaceKey, Uri resourceUri) - { - return new FamilyTypeface(resourceUri, familyTypefaceKey.FontWeight, familyTypefaceKey.FontStyle); - } - } - - public interface IFontFamilyCache - { - CachedFontFamily GetOrAddFontFamily(FontFamily fontFamily); - } - - public class FontFamilyCache : IFontFamilyCache - { - private readonly ConcurrentDictionary _cachedFontFamilies = new ConcurrentDictionary(); - - public CachedFontFamily GetOrAddFontFamily(FontFamily fontFamily) - { - return _cachedFontFamilies.GetOrAdd(fontFamily.FontFamilyKey, CreateCachedFontFamily); - } - - private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) - { - return new CachedFontFamily(); - } - } + //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 _typefaces = + // new ConcurrentDictionary(); + + // 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 _cachedFontFamilies = new ConcurrentDictionary(); + + // 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(); + // } + //} } diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs index 6689b47c2f..6cd7c24632 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs @@ -18,16 +18,14 @@ 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('#'); string familyName; Uri baseUri = null; - var fontWeight = FontWeight.Normal; - - var fontStyle = FontStyle.Normal; - switch (fontFamilyExpression.Length) { case 1: @@ -41,34 +39,13 @@ namespace Avalonia.Markup.Xaml.Converters familyName = fontFamilyExpression[1]; break; } - //case 3: - // { - // baseUri = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); - // familyName = fontFamilyExpression[1]; - // fontWeight = (FontWeight)Enum.Parse(typeof(FontWeight), fontFamilyExpression[2]); - // break; - // } - //case 4: - // { - // baseUri = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); - // familyName = fontFamilyExpression[1]; - // fontWeight = (FontWeight)Enum.Parse(typeof(FontWeight), fontFamilyExpression[2]); - // fontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), fontFamilyExpression[3]); - // break; - // } default: { throw new ArgumentException("Specified family is not supported."); } } - var fontFamily = new FontFamily(familyName, baseUri); - - var cachedFontFamily = AvaloniaLocator.Current.GetService().GetOrAddFontFamily(fontFamily); - - cachedFontFamily.GetOrAddFamilyTypeface(baseUri, fontWeight, fontStyle); - - return fontFamily; + return new FontFamily(familyName, baseUri); } } } \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 20fc956b5d..57beac652c 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -2,8 +2,8 @@ // 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 System.Linq; using Avalonia.Media; using Avalonia.Platform; @@ -26,59 +26,46 @@ namespace Avalonia.Direct2D1.Media var factory = AvaloniaLocator.Current.GetService(); + DWrite.TextFormat textFormat; + if (typeface.FontFamily.BaseUri != null) { - var fontFamily = AvaloniaLocator.Current.GetService().GetOrAddFontFamily(typeface.FontFamily); - - fontFamily.TryGetFamilyTypeface(out var familyTypeface); - - var fontLoader = new ResourceFontLoader(factory, familyTypeface.ResourceUri); + var fontCollection = Direct2D1CustomFontResourceCache.GetOrAddCustomFontResource(typeface.FontFamily, factory); - var fontCollection = new DWrite.FontCollection(factory, fontLoader, fontLoader.Key); - - using (var textFormat = - new DWrite.TextFormat(factory, typeface.FontFamily.Name, fontCollection, DWrite.FontWeight.Normal, - DWrite.FontStyle.Normal, DWrite.FontStretch.Normal, (float)typeface.FontSize)) - { - textFormat.TextAlignment = DWrite.TextAlignment.Center; - textFormat.ParagraphAlignment = DWrite.ParagraphAlignment.Center; - - textFormat.WordWrapping = wrapping == TextWrapping.Wrap ? - DWrite.WordWrapping.Wrap : - DWrite.WordWrapping.NoWrap; - - TextLayout = new DWrite.TextLayout(factory, Text ?? string.Empty, textFormat, (float)constraint.Width, - (float)constraint.Height) - { - TextAlignment = textAlignment.ToDirect2D() - }; - } + textFormat = new DWrite.TextFormat( + factory, + typeface.FontFamily.Name, + fontCollection, + (DWrite.FontWeight)typeface.Weight, + (DWrite.FontStyle)typeface.Style, + DWrite.FontStretch.Normal, + (float)typeface.FontSize); } else { - using (var format = new DWrite.TextFormat( + textFormat = new DWrite.TextFormat( factory, - typeface?.FontFamily.Name ?? "Courier New", - (DWrite.FontWeight)(typeface.Weight), - (DWrite.FontStyle)(typeface.Style), - (float)typeface.FontSize)) - { - format.WordWrapping = wrapping == TextWrapping.Wrap ? - DWrite.WordWrapping.Wrap : - DWrite.WordWrapping.NoWrap; - - TextLayout = new DWrite.TextLayout( - factory, - text ?? string.Empty, - format, - (float)constraint.Width, - (float)constraint.Height) - { - TextAlignment = textAlignment.ToDirect2D() - }; - } + typeface.FontFamily.Name, + (DWrite.FontWeight)typeface.Weight, + (DWrite.FontStyle)typeface.Style, + (float)typeface.FontSize); } + textFormat.TextAlignment = DWrite.TextAlignment.Center; + textFormat.ParagraphAlignment = DWrite.ParagraphAlignment.Center; + + textFormat.WordWrapping = wrapping == TextWrapping.Wrap ? + DWrite.WordWrapping.Wrap : + DWrite.WordWrapping.NoWrap; + + TextLayout = new DWrite.TextLayout(factory, Text ?? string.Empty, textFormat, (float)constraint.Width, + (float)constraint.Height) + { + TextAlignment = textAlignment.ToDirect2D() + }; + + textFormat.Dispose(); + if (spans != null) { foreach (var span in spans) @@ -98,10 +85,10 @@ namespace Avalonia.Direct2D1.Media public DWrite.TextLayout TextLayout { get; } - public void Dispose() - { - TextLayout.Dispose(); - } + //public void Dispose() + //{ + // TextLayout.Dispose(); + //} public IEnumerable GetLines() { @@ -111,14 +98,11 @@ namespace Avalonia.Direct2D1.Media public TextHitTestResult HitTestPoint(Point point) { - SharpDX.Mathematics.Interop.RawBool isTrailingHit; - SharpDX.Mathematics.Interop.RawBool isInside; - var result = TextLayout.HitTestPoint( (float)point.X, (float)point.Y, - out isTrailingHit, - out isInside); + out var isTrailingHit, + out var isInside); return new TextHitTestResult { @@ -130,14 +114,7 @@ namespace Avalonia.Direct2D1.Media public Rect HitTestTextPosition(int index) { - float x; - float y; - - var result = TextLayout.HitTestTextPosition( - index, - false, - out x, - out y); + var result = TextLayout.HitTestTextPosition(index, false, out _, out _); return new Rect(result.Left, result.Top, result.Width, result.Height); } @@ -175,12 +152,29 @@ namespace Avalonia.Direct2D1.Media } } + internal static class Direct2D1CustomFontResourceCache + { + private static readonly ConcurrentDictionary s_cachedFonts = + new ConcurrentDictionary(); + + public static DWrite.FontCollection GetOrAddCustomFontResource(FontFamily fontFamily, DWrite.Factory factory) + { + return s_cachedFonts.GetOrAdd(fontFamily.Key, x => CreateCustomFontResource(x, factory)); + } + + private static DWrite.FontCollection CreateCustomFontResource(FontFamilyKey fontFamilyKey, DWrite.Factory factory) + { + var fontLoader = new ResourceFontLoader(factory, fontFamilyKey.BaseUri); + + return new DWrite.FontCollection(factory, fontLoader, fontLoader.Key); + } + } + public class ResourceFontLoader : CallbackBase, DWrite.FontCollectionLoader, DWrite.FontFileLoader { private readonly List _fontStreams = new List(); private readonly List _enumerators = new List(); private readonly DataStream _keyStream; - private readonly DWrite.Factory _factory; ///

@@ -190,7 +184,7 @@ namespace Avalonia.Direct2D1.Media /// public ResourceFontLoader(DWrite.Factory factory, Uri fontResource) { - _factory = factory; + var factory1 = factory; var assets = AvaloniaLocator.Current.GetService(); @@ -215,8 +209,8 @@ namespace Avalonia.Direct2D1.Media _keyStream.Position = 0; // Register the - _factory.RegisterFontFileLoader(this); - _factory.RegisterFontCollectionLoader(this); + factory1.RegisterFontFileLoader(this); + factory1.RegisterFontCollectionLoader(this); } @@ -224,13 +218,7 @@ namespace Avalonia.Direct2D1.Media /// Gets the key used to identify the FontCollection as well as storing index for fonts. /// /// The key. - public DataStream Key - { - get - { - return _keyStream; - } - } + public DataStream Key => _keyStream; /// /// Creates a font file enumerator object that encapsulates a collection of font files. The font system calls back to this interface to create a font collection. @@ -282,7 +270,7 @@ namespace Avalonia.Direct2D1.Media /// The stream. public ResourceFontFileStream(DataStream stream) { - this._stream = stream; + _stream = stream; } /// @@ -384,19 +372,15 @@ namespace Avalonia.Direct2D1.Media { bool moveNext = keyStream.RemainingLength != 0; - if (moveNext) - { - if (_currentFontFile != null) - { - _currentFontFile.Dispose(); - } + if (!moveNext) return false; - _currentFontFile = new DWrite.FontFile(_factory, keyStream.PositionPointer, 4, _loader); + _currentFontFile?.Dispose(); - keyStream.Position += 4; - } + _currentFontFile = new DWrite.FontFile(_factory, keyStream.PositionPointer, 4, _loader); + + keyStream.Position += 4; - return moveNext; + return true; } /// From 53db6d75e92204437bdd33544a7fdd9004c78295 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 1 May 2018 20:39:45 +0200 Subject: [PATCH 05/36] Skia support --- samples/ControlCatalog.Desktop/Program.cs | 2 +- src/Skia/Avalonia.Skia/FormattedTextImpl.cs | 4 +- src/Skia/Avalonia.Skia/TypefaceCache.cs | 43 +++++++++++---------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index daa6ba69db..ae458f52c6 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -23,7 +23,7 @@ namespace ControlCatalog /// This method is needed for IDE previewer infrastructure /// public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure().LogToDebug().UsePlatformDetect(); + => AppBuilder.Configure().LogToDebug().UsePlatformDetect().UseSkia(); private static void ConfigureAssetAssembly(AppBuilder builder) { diff --git a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs index baf3a210d5..23a9ec615e 100644 --- a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs +++ b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs @@ -26,7 +26,7 @@ namespace Avalonia.Skia Text = Text.Replace((char)0, (char)0x200B); var skiaTypeface = TypefaceCache.GetTypeface( - typeface.FontFamily.Name ?? "monospace", + typeface.FontFamily, typeface.Style, typeface.Weight); @@ -37,7 +37,7 @@ namespace Avalonia.Skia _paint.TextEncoding = SKTextEncoding.Utf16; _paint.IsStroke = false; _paint.IsAntialias = true; - _paint.LcdRenderText = true; + _paint.LcdRenderText = true; _paint.SubpixelText = true; _paint.Typeface = skiaTypeface; _paint.TextSize = (float)typeface.FontSize; diff --git a/src/Skia/Avalonia.Skia/TypefaceCache.cs b/src/Skia/Avalonia.Skia/TypefaceCache.cs index c5f3d371ad..ed84d4818e 100644 --- a/src/Skia/Avalonia.Skia/TypefaceCache.cs +++ b/src/Skia/Avalonia.Skia/TypefaceCache.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Text; using Avalonia.Media; +using Avalonia.Platform; using SkiaSharp; namespace Avalonia.Skia @@ -15,9 +16,9 @@ namespace Avalonia.Skia public readonly SKFontStyleSlant Slant; public readonly SKFontStyleWeight Weight; - public FontKey(SKFontStyleWeight weight, SKFontStyleSlant slant) + public FontKey(SKFontStyleWeight weight, SKFontStyleSlant slant) { - Slant = slant; + Slant = slant; Weight = weight; } @@ -44,29 +45,31 @@ namespace Avalonia.Skia // Equals and GetHashCode ommitted } - unsafe static SKTypeface GetTypeface(string name, FontKey key) + unsafe static SKTypeface GetTypeface(FontFamily fontFamily, FontKey key) { - if (name == null) - { - name = "Arial"; - } + var familyKey = fontFamily.Key.ToString(); - Dictionary entry; - - if (!Cache.TryGetValue(name, out entry)) + if (!Cache.TryGetValue(familyKey, out var entry)) { - Cache[name] = entry = new Dictionary(); + Cache[familyKey] = entry = new Dictionary(); } - SKTypeface typeface = null; - - if (!entry.TryGetValue(key, out typeface)) + if (!entry.TryGetValue(key, out var typeface)) { - typeface = SKTypeface.FromFamilyName(name, key.Weight, SKFontStyleWidth.Normal, key.Slant); + if (fontFamily.BaseUri != null) + { + var stream = AvaloniaLocator.Current.GetService().Open(fontFamily.BaseUri); - if (typeface == null) + typeface = SKTypeface.FromStream(stream); + } + else { - typeface = SKTypeface.FromFamilyName(null, SKTypefaceStyle.Normal); + typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant); + + if (typeface == null) + { + typeface = SKTypeface.FromFamilyName(null, SKTypefaceStyle.Normal); + } } entry[key] = typeface; @@ -75,11 +78,11 @@ namespace Avalonia.Skia return typeface; } - public static SKTypeface GetTypeface(string name, FontStyle style, FontWeight weight) + public static SKTypeface GetTypeface(FontFamily fontFamily, FontStyle style, FontWeight weight) { SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; - switch(style) + switch (style) { case FontStyle.Italic: skStyle = SKFontStyleSlant.Italic; @@ -90,7 +93,7 @@ namespace Avalonia.Skia break; } - return GetTypeface(name, new FontKey((SKFontStyleWeight)weight, skStyle)); + return GetTypeface(fontFamily, new FontKey((SKFontStyleWeight)weight, skStyle)); } } From e96c6e4fe7d68ed0701b055d5134b9d6852cd81b Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 1 May 2018 20:44:21 +0200 Subject: [PATCH 06/36] Sample revert --- samples/ControlCatalog.Desktop/Program.cs | 2 +- samples/ControlCatalog/Pages/BorderPage.xaml | 44 +++++++++----------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index ae458f52c6..daa6ba69db 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -23,7 +23,7 @@ namespace ControlCatalog /// This method is needed for IDE previewer infrastructure /// public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure().LogToDebug().UsePlatformDetect().UseSkia(); + => AppBuilder.Configure().LogToDebug().UsePlatformDetect(); private static void ConfigureAssetAssembly(AppBuilder builder) { diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml index dc0b05686b..f0705362d7 100644 --- a/samples/ControlCatalog/Pages/BorderPage.xaml +++ b/samples/ControlCatalog/Pages/BorderPage.xaml @@ -1,36 +1,32 @@ - - Border - A control which decorates a child with a border and background + + Border + A control which decorates a child with a border and background - - - Border - - + Border + + - Border and Background - - Border and Background + + - Rounded Corners - - Rounded Corners + + - - Rounded Corners - Rounded Corners - Rounded Corners - - - + Rounded Corners + + \ No newline at end of file From 7082831021016192681fc5dee29edf5cc19004d2 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 1 May 2018 20:45:59 +0200 Subject: [PATCH 07/36] Assets revert --- samples/ControlCatalog/Assets/kooten.ttf | Bin 42164 -> 0 bytes .../Assets/octin_stencil_free.ttf | Bin 103128 -> 0 bytes samples/ControlCatalog/ControlCatalog.csproj | 4 ---- 3 files changed, 4 deletions(-) delete mode 100644 samples/ControlCatalog/Assets/kooten.ttf delete mode 100644 samples/ControlCatalog/Assets/octin_stencil_free.ttf diff --git a/samples/ControlCatalog/Assets/kooten.ttf b/samples/ControlCatalog/Assets/kooten.ttf deleted file mode 100644 index 3b052635fbc7c71317e8f90f450c3ac411f7554c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42164 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�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 iC%0|Wwil1CT4JwVaCgRpwh)p)2nkDBLJ3f4 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 z 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 diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index beb51f42fc..b8a8479a49 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -11,10 +11,6 @@ - - - - From d5ace4db8d3675a55018e95efe71d7954a15bebe Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Wed, 2 May 2018 14:47:07 +0200 Subject: [PATCH 08/36] tests fixed --- .../Media/FormattedTextImpl.cs | 8 ++------ .../Avalonia.RenderTests/Controls/BorderTests.cs | 16 ++++++++-------- .../Media/VisualBrushTests.cs | 2 +- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 57beac652c..c7356fde1f 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -51,12 +51,8 @@ namespace Avalonia.Direct2D1.Media (float)typeface.FontSize); } - textFormat.TextAlignment = DWrite.TextAlignment.Center; - textFormat.ParagraphAlignment = DWrite.ParagraphAlignment.Center; - - textFormat.WordWrapping = wrapping == TextWrapping.Wrap ? - DWrite.WordWrapping.Wrap : - DWrite.WordWrapping.NoWrap; + textFormat.WordWrapping = + wrapping == TextWrapping.Wrap ? DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap; TextLayout = new DWrite.TextLayout(factory, Text ?? string.Empty, textFormat, (float)constraint.Width, (float)constraint.Height) diff --git a/tests/Avalonia.RenderTests/Controls/BorderTests.cs b/tests/Avalonia.RenderTests/Controls/BorderTests.cs index 7d2e40c3b4..c82d616094 100644 --- a/tests/Avalonia.RenderTests/Controls/BorderTests.cs +++ b/tests/Avalonia.RenderTests/Controls/BorderTests.cs @@ -204,7 +204,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, HorizontalAlignment = HorizontalAlignment.Center, } @@ -231,7 +231,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, VerticalAlignment = VerticalAlignment.Center, } @@ -258,7 +258,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, HorizontalAlignment = HorizontalAlignment.Stretch, } @@ -285,7 +285,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, VerticalAlignment = VerticalAlignment.Stretch, } @@ -312,7 +312,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, HorizontalAlignment = HorizontalAlignment.Left, } @@ -339,7 +339,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, HorizontalAlignment = HorizontalAlignment.Right, } @@ -366,7 +366,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, VerticalAlignment = VerticalAlignment.Top, } @@ -393,7 +393,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { Text = "Foo", Background = Brushes.Red, - FontFamily = "Segoe UI", + FontFamily = new FontFamily("Segoe UI"), FontSize = 12, VerticalAlignment = VerticalAlignment.Bottom, } diff --git a/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs b/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs index cfa15ae304..f69d336271 100644 --- a/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs +++ b/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs @@ -48,7 +48,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media Child = new TextBlock { FontSize = 24, - FontFamily = "Arial", + FontFamily = new FontFamily("Arial"), Background = Brushes.Green, Foreground = Brushes.Yellow, Text = "VisualBrush", From ff230d4360ec7002331ada408d50f8e30e7d7637 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Sun, 6 May 2018 12:12:47 +0200 Subject: [PATCH 09/36] resm filename globbing --- samples/ControlCatalog/ControlCatalog.csproj | 18 + .../ControlCatalog/Fonts/Aspergit_Bold.ttf | Bin 0 -> 16860 bytes .../Fonts/Aspergit_Bold_Italic.ttf | Bin 0 -> 18256 bytes .../ControlCatalog/Fonts/Aspergit_Italic.ttf | Bin 0 -> 18248 bytes samples/ControlCatalog/Fonts/BolshevikBd.ttf | Bin 0 -> 6928 bytes .../ControlCatalog/Fonts/PinkHighwayBold.ttf | Bin 0 -> 43816 bytes .../Fonts/PixelOperator-Bold.ttf | Bin 0 -> 18068 bytes .../ControlCatalog/Fonts/PixelOperator.ttf | Bin 0 -> 19836 bytes samples/ControlCatalog/Pages/BorderPage.xaml | 40 +- src/Avalonia.Visuals/Media/FontFamily.cs | 387 ++++++++++++------ .../Converters/FontFamilyTypeConverter.cs | 13 +- src/Shared/PlatformSupport/AssetLoader.cs | 8 +- src/Skia/Avalonia.Skia/TypefaceCache.cs | 18 +- .../Media/FormattedTextImpl.cs | 47 ++- 14 files changed, 357 insertions(+), 174 deletions(-) create mode 100644 samples/ControlCatalog/Fonts/Aspergit_Bold.ttf create mode 100644 samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf create mode 100644 samples/ControlCatalog/Fonts/Aspergit_Italic.ttf create mode 100644 samples/ControlCatalog/Fonts/BolshevikBd.ttf create mode 100644 samples/ControlCatalog/Fonts/PinkHighwayBold.ttf create mode 100644 samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf create mode 100644 samples/ControlCatalog/Fonts/PixelOperator.ttf diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index b8a8479a49..74bf3ec4bb 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -11,6 +11,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/samples/ControlCatalog/Fonts/Aspergit_Bold.ttf b/samples/ControlCatalog/Fonts/Aspergit_Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c9d6b840e9e340fb6ab698c2e230a2a9c2593f7a GIT binary patch literal 16860 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 Q=>AUMY`hes{XYx-7Yu%bUH||9 literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf b/samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a5ba97f37749d88caeed4346b3151291063384db GIT binary patch literal 18256 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 Jm;Rra{|4kce7FDr literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Fonts/Aspergit_Italic.ttf b/samples/ControlCatalog/Fonts/Aspergit_Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d74ec43df22c7ff7e9df6eef9e2babedf76bfb05 GIT binary patch literal 18248 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 L$00h?@5B5Ll|r$X literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Fonts/BolshevikBd.ttf b/samples/ControlCatalog/Fonts/BolshevikBd.ttf new file mode 100644 index 0000000000000000000000000000000000000000..359ee1bc15d02b37194a2e1dfaca2327b280cbef GIT binary patch literal 6928 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 M6aBvW_;U~b4?>$VrvLx| literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf b/samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..154890a659f1d8c1ea956582dc58b56e4cc09e8f GIT binary patch literal 18068 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 F^8Ztzpb!86 literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Fonts/PixelOperator.ttf b/samples/ControlCatalog/Fonts/PixelOperator.ttf new file mode 100644 index 0000000000000000000000000000000000000000..277c408b5851e75ccbff95ae1ad462373e6fd309 GIT binary patch literal 19836 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 - - Border - A control which decorates a child with a border and background + + Border + A control which decorates a child with a border and background - - - Border - - + Border + + - Border and Background - - Border and Background + + - Rounded Corners - - Rounded Corners + + - Rounded Corners - + + Rounded Corners + Rounded Corners + Rounded Corners + Rounded Corners + Rounded Corners + + + - \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 7442619b5c..db4ecb2189 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/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 _typefaces = - // new ConcurrentDictionary(); - - // 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 _cachedFontFamilies = new ConcurrentDictionary(); - - // 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 _fontResources; + private readonly IFontResourceLoader _fontResourceLoader = new FontResourceLoader(); + + public FontResourceCollection(FontFamilyKey key) + { + Key = key; + } + + public FontFamilyKey Key { get; } + + public IEnumerable FontResources + { + get + { + if (_fontResources == null) + { + _fontResources = CreateFontResources(); + } + + return _fontResources.Values; + } + } + + private Dictionary CreateFontResources() + { + return _fontResourceLoader.GetFontResources(Key).ToDictionary(x => x.Source); + } + } + + public interface IFontResourceLoader + { + IEnumerable GetFontResources(FontFamilyKey fontFamilyKey); + } + + public class FontResourceLoader : IFontResourceLoader + { + private static readonly Dictionary s_assemblyNameCache + = new Dictionary(); + + private readonly AssemblyDescriptor _defaultAssembly; + + public FontResourceLoader(Assembly assembly = null) + { + if (assembly == null) + { + assembly = Assembly.GetEntryAssembly(); + } + if (assembly != null) + { + _defaultAssembly = new AssemblyDescriptor(assembly); + } + } + + public IEnumerable GetFontResources(FontFamilyKey fontFamilyKey) + { + return fontFamilyKey.FileName != null + ? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) + : GetFontResourcesByLocation(fontFamilyKey.Location); + } + + private IEnumerable 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 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().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 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 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 FontResources => _fontResourceCollection.FontResources; + } + + public class FontFamilyCache + { + private static readonly ConcurrentDictionary s_cachedFontFamilies = new ConcurrentDictionary(); + + public CachedFontFamily GetOrAddFontFamily(FontFamilyKey key) + { + return s_cachedFontFamilies.GetOrAdd(key, CreateCachedFontFamily); + } + + private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) + { + return new CachedFontFamily(fontFamilyKey, new FontResourceCollection(fontFamilyKey)); + } + } } diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs index 6cd7c24632..59742f8b12 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs +++ b/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); } } } \ No newline at end of file diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index 4287fd0b9e..659a72e9a5 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/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().GetLoadedAssemblies(); var match = loadedAssemblies.FirstOrDefault(a => a.GetName().Name == name); @@ -199,5 +197,5 @@ namespace Avalonia.Shared.PlatformSupport public Dictionary Resources { get; } public string Name { get; } } - } + } } diff --git a/src/Skia/Avalonia.Skia/TypefaceCache.cs b/src/Skia/Avalonia.Skia/TypefaceCache.cs index ed84d4818e..f4598df8ec 100644 --- a/src/Skia/Avalonia.Skia/TypefaceCache.cs +++ b/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().Open(fontFamily.BaseUri); - - typeface = SKTypeface.FromStream(stream); - } - else - { + //if (fontFamily.BaseUri != null) + //{ + // var stream = AvaloniaLocator.Current.GetService().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; } diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index c7356fde1f..732089b79d 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/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(); + var factory = AvaloniaLocator.Current.GetService(); 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 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 s_cachedFonts = new ConcurrentDictionary(); - 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 _enumerators = new List(); private readonly DataStream _keyStream; - ///

/// Initializes a new instance of the class. /// /// The factory. - /// - public ResourceFontLoader(DWrite.Factory factory, Uri fontResource) + /// + public ResourceFontLoader(DWrite.Factory factory, IEnumerable fontResources) { var factory1 = factory; - var assets = AvaloniaLocator.Current.GetService(); + var assetLoader = AvaloniaLocator.Current.GetService(); - 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); From 756db86316156232ed46c47b1dacdef4add67740 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Sun, 6 May 2018 18:46:02 +0200 Subject: [PATCH 10/36] res support finished --- samples/ControlCatalog/Pages/BorderPage.xaml | 10 +++---- src/Avalonia.Visuals/Media/FontFamily.cs | 30 +++++++------------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml index faebc3a61e..1ad18a2ac0 100644 --- a/samples/ControlCatalog/Pages/BorderPage.xaml +++ b/samples/ControlCatalog/Pages/BorderPage.xaml @@ -26,11 +26,11 @@ CornerRadius="8" Padding="16"> - Rounded Corners - Rounded Corners - Rounded Corners - Rounded Corners - Rounded Corners + Rounded Corners + Rounded Corners + Rounded Corners + Rounded Corners + Rounded Corners diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index db4ecb2189..0eb960018a 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -44,19 +44,18 @@ namespace Avalonia.Media { if (source.AbsolutePath.Contains(".ttf")) { - var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); - - if (source.Scheme == "resm") + if (source.Scheme == "res") + { + FileName = source.AbsolutePath.Split('/').Last(); + } + else { + var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); 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(); - } + Location = new Uri(source.OriginalString.Replace("." + FileName, ""), UriKind.RelativeOrAbsolute); } else { @@ -202,7 +201,7 @@ namespace Avalonia.Media { var assembly = GetAssembly(location); - var compareTo = fileName.Split('*').First(); + var compareTo = GetLocationPath(location) + fileName.Split('*').First(); var matchingResources = assembly.Resources.Where(x => x.Contains(compareTo)); @@ -218,18 +217,9 @@ namespace Avalonia.Media { 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('.'); - } - } + var path = uri.AbsolutePath.Replace("/", "."); - return path.ToString(); + return path; } private AssemblyDescriptor GetAssembly(Uri uri) From 5fe6276228abb9f5004ad16375212084d2285bc0 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Sun, 6 May 2018 20:43:50 +0200 Subject: [PATCH 11/36] Finished skia support --- samples/ControlCatalog.Desktop/Program.cs | 2 +- src/Avalonia.Visuals/Media/FontFamily.cs | 290 +----------------- .../Media/Fonts/CachedFontFamily.cs | 22 ++ .../Media/Fonts/FontFamilyCache.cs | 22 ++ .../Media/Fonts/FontFamilyKey.cs | 84 +++++ .../Media/Fonts/FontResource.cs | 17 + .../Media/Fonts/FontResourceCollection.cs | 40 +++ .../Media/Fonts/FontResourceLoader.cs | 142 +++++++++ .../Media/Fonts/IFontResourceLoader.cs | 12 + src/Skia/Avalonia.Skia/TypefaceCache.cs | 43 ++- .../Media/FormattedTextImpl.cs | 18 +- 11 files changed, 382 insertions(+), 310 deletions(-) create mode 100644 src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs create mode 100644 src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs create mode 100644 src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs create mode 100644 src/Avalonia.Visuals/Media/Fonts/FontResource.cs create mode 100644 src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs create mode 100644 src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs create mode 100644 src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index daa6ba69db..ae458f52c6 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -23,7 +23,7 @@ namespace ControlCatalog /// This method is needed for IDE previewer infrastructure ///
public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure().LogToDebug().UsePlatformDetect(); + => AppBuilder.Configure().LogToDebug().UsePlatformDetect().UseSkia(); private static void ConfigureAssetAssembly(AppBuilder builder) { diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 0eb960018a..7f63930f1a 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -2,12 +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.Linq; -using System.Reflection; -using System.Text; -using Avalonia.Platform; +using Avalonia.Media.Fonts; namespace Avalonia.Media { @@ -37,287 +32,4 @@ namespace Avalonia.Media return Name; } } - - public class FontFamilyKey - { - public FontFamilyKey(Uri source) - { - if (source.AbsolutePath.Contains(".ttf")) - { - if (source.Scheme == "res") - { - FileName = source.AbsolutePath.Split('/').Last(); - } - else - { - var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); - var fileNameWithoutExtension = filePathWithoutExtension.Split('.').Last(); - FileName = fileNameWithoutExtension + ".ttf"; - } - - Location = new Uri(source.OriginalString.Replace("." + FileName, ""), UriKind.RelativeOrAbsolute); - } - else - { - Location = source; - } - } - - public Uri Location { get; } - - public string FileName { get; } - - public override int GetHashCode() - { - unchecked - { - var hash = (int)2166136261; - - if (Location != null) - { - hash = (hash * 16777619) ^ Location.GetHashCode(); - } - - if (FileName != null) - { - hash = (hash * 16777619) ^ FileName.GetHashCode(); - } - - return hash; - } - } - - public override bool Equals(object obj) - { - if (!(obj is FontFamilyKey other)) return false; - - if (Location != other.Location) return false; - - if (FileName != other.FileName) return false; - - return true; - } - - public override string ToString() - { - if (FileName != null) - { - if (Location.Scheme == "resm") - { - return Location + "." + FileName; - } - - return Location + "/" + FileName; - } - - return Location.ToString(); - } - } - - public class FontResource - { - public FontResource(Uri source) - { - Source = source; - } - - public Uri Source { get; } - } - - public class FontResourceCollection - { - private Dictionary _fontResources; - private readonly IFontResourceLoader _fontResourceLoader = new FontResourceLoader(); - - public FontResourceCollection(FontFamilyKey key) - { - Key = key; - } - - public FontFamilyKey Key { get; } - - public IEnumerable FontResources - { - get - { - if (_fontResources == null) - { - _fontResources = CreateFontResources(); - } - - return _fontResources.Values; - } - } - - private Dictionary CreateFontResources() - { - return _fontResourceLoader.GetFontResources(Key).ToDictionary(x => x.Source); - } - } - - public interface IFontResourceLoader - { - IEnumerable GetFontResources(FontFamilyKey fontFamilyKey); - } - - public class FontResourceLoader : IFontResourceLoader - { - private static readonly Dictionary s_assemblyNameCache - = new Dictionary(); - - private readonly AssemblyDescriptor _defaultAssembly; - - public FontResourceLoader(Assembly assembly = null) - { - if (assembly == null) - { - assembly = Assembly.GetEntryAssembly(); - } - if (assembly != null) - { - _defaultAssembly = new AssemblyDescriptor(assembly); - } - } - - public IEnumerable GetFontResources(FontFamilyKey fontFamilyKey) - { - return fontFamilyKey.FileName != null - ? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) - : GetFontResourcesByLocation(fontFamilyKey.Location); - } - - private IEnumerable 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 GetFontResourcesByFileName(Uri location, string fileName) - { - var assembly = GetAssembly(location); - - var compareTo = GetLocationPath(location) + 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 = uri.AbsolutePath.Replace("/", "."); - - return path; - } - - 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().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 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 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 FontResources => _fontResourceCollection.FontResources; - } - - public class FontFamilyCache - { - private static readonly ConcurrentDictionary s_cachedFontFamilies = new ConcurrentDictionary(); - - public CachedFontFamily GetOrAddFontFamily(FontFamilyKey key) - { - return s_cachedFontFamilies.GetOrAdd(key, CreateCachedFontFamily); - } - - private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) - { - return new CachedFontFamily(fontFamilyKey, new FontResourceCollection(fontFamilyKey)); - } - } } diff --git a/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs b/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs new file mode 100644 index 0000000000..d53ee69a5b --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs @@ -0,0 +1,22 @@ +// 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.Generic; + +namespace Avalonia.Media.Fonts +{ + public class CachedFontFamily + { + private readonly FontResourceCollection _fontResourceCollection; + + public CachedFontFamily(FontFamilyKey key, FontResourceCollection fontResourceCollection) + { + Key = key; + _fontResourceCollection = fontResourceCollection; + } + + public FontFamilyKey Key { get; } + + public IEnumerable FontResources => _fontResourceCollection.FontResources; + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs new file mode 100644 index 0000000000..52a4ddb311 --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs @@ -0,0 +1,22 @@ +// 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; + +namespace Avalonia.Media.Fonts +{ + public static class FontFamilyCache + { + private static readonly ConcurrentDictionary s_cachedFontFamilies = new ConcurrentDictionary(); + + public static CachedFontFamily GetOrAddFontFamily(FontFamilyKey key) + { + return s_cachedFontFamilies.GetOrAdd(key, CreateCachedFontFamily); + } + + private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) + { + return new CachedFontFamily(fontFamilyKey, new FontResourceCollection(fontFamilyKey)); + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs new file mode 100644 index 0000000000..8ced4ea6bb --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -0,0 +1,84 @@ +// 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.Linq; + +namespace Avalonia.Media.Fonts +{ + public class FontFamilyKey + { + public FontFamilyKey(Uri source) + { + if (source.AbsolutePath.Contains(".ttf")) + { + if (source.Scheme == "res") + { + FileName = source.AbsolutePath.Split('/').Last(); + Location = new Uri(source.OriginalString.Replace("/" + FileName, ""), UriKind.RelativeOrAbsolute); + } + else + { + var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); + var fileNameWithoutExtension = filePathWithoutExtension.Split('.').Last(); + FileName = fileNameWithoutExtension + ".ttf"; + Location = new Uri(source.OriginalString.Replace("." + FileName, ""), UriKind.RelativeOrAbsolute); + } + } + else + { + Location = source; + } + } + + public Uri Location { get; } + + public string FileName { get; } + + public override int GetHashCode() + { + unchecked + { + var hash = (int)2166136261; + + if (Location != null) + { + hash = (hash * 16777619) ^ Location.GetHashCode(); + } + + if (FileName != null) + { + hash = (hash * 16777619) ^ FileName.GetHashCode(); + } + + return hash; + } + } + + public override bool Equals(object obj) + { + if (!(obj is FontFamilyKey other)) return false; + + if (Location != other.Location) return false; + + if (FileName != other.FileName) return false; + + return true; + } + + public override string ToString() + { + if (FileName != null) + { + if (Location.Scheme == "resm") + { + return Location.AbsolutePath + "." + FileName; + } + + return Location.AbsolutePath + "/" + FileName; + } + + return Location.AbsolutePath; + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs new file mode 100644 index 0000000000..470e17d7d6 --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs @@ -0,0 +1,17 @@ +// 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; + +namespace Avalonia.Media.Fonts +{ + public class FontResource + { + public FontResource(Uri source) + { + Source = source; + } + + public Uri Source { get; } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs new file mode 100644 index 0000000000..347380e121 --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs @@ -0,0 +1,40 @@ +// 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.Linq; + +namespace Avalonia.Media.Fonts +{ + public class FontResourceCollection + { + private Dictionary _fontResources; + private readonly IFontResourceLoader _fontResourceLoader = new FontResourceLoader(); + + public FontResourceCollection(FontFamilyKey key) + { + Key = key; + } + + public FontFamilyKey Key { get; } + + public IEnumerable FontResources + { + get + { + if (_fontResources == null) + { + _fontResources = CreateFontResources(); + } + + return _fontResources.Values; + } + } + + private Dictionary CreateFontResources() + { + return _fontResourceLoader.GetFontResources(Key).ToDictionary(x => x.Source); + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs new file mode 100644 index 0000000000..2f450679b1 --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs @@ -0,0 +1,142 @@ +// 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.Linq; +using System.Reflection; +using Avalonia.Platform; + +namespace Avalonia.Media.Fonts +{ + public class FontResourceLoader : IFontResourceLoader + { + private static readonly Dictionary s_assemblyNameCache + = new Dictionary(); + + private readonly AssemblyDescriptor _defaultAssembly; + + public FontResourceLoader(Assembly assembly = null) + { + if (assembly == null) + { + assembly = Assembly.GetEntryAssembly(); + } + if (assembly != null) + { + _defaultAssembly = new AssemblyDescriptor(assembly); + } + } + + public IEnumerable GetFontResources(FontFamilyKey fontFamilyKey) + { + return fontFamilyKey.FileName != null + ? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) + : GetFontResourcesByLocation(fontFamilyKey.Location); + } + + private IEnumerable 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 GetFontResourcesByFileName(Uri location, string fileName) + { + var assembly = GetAssembly(location); + + var compareTo = GetLocationPath(location) + "." + 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 = uri.AbsolutePath.Replace("/", "."); + + return path; + } + + 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().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 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 Resources { get; } + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs new file mode 100644 index 0000000000..44e665e3a1 --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs @@ -0,0 +1,12 @@ +// 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.Generic; + +namespace Avalonia.Media.Fonts +{ + public interface IFontResourceLoader + { + IEnumerable GetFontResources(FontFamilyKey fontFamilyKey); + } +} \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/TypefaceCache.cs b/src/Skia/Avalonia.Skia/TypefaceCache.cs index f4598df8ec..96696488c3 100644 --- a/src/Skia/Avalonia.Skia/TypefaceCache.cs +++ b/src/Skia/Avalonia.Skia/TypefaceCache.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Text; using Avalonia.Media; +using Avalonia.Media.Fonts; using Avalonia.Platform; using SkiaSharp; @@ -47,7 +48,7 @@ namespace Avalonia.Skia unsafe static SKTypeface GetTypeface(FontFamily fontFamily, FontKey key) { - var familyKey = fontFamily.Key.ToString(); + var familyKey = fontFamily.Name; if (!Cache.TryGetValue(familyKey, out var entry)) { @@ -56,21 +57,41 @@ namespace Avalonia.Skia if (!entry.TryGetValue(key, out var typeface)) { - //if (fontFamily.BaseUri != null) - //{ - // var stream = AvaloniaLocator.Current.GetService().Open(fontFamily.BaseUri); + if (fontFamily.Key != null) + { + var cachedFontFamily = FontFamilyCache.GetOrAddFontFamily(fontFamily.Key); - // typeface = SKTypeface.FromStream(stream); - //} - //else - //{ - typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant); + var assetLoader = AvaloniaLocator.Current.GetService(); + + foreach (var fontResource in cachedFontFamily.FontResources) + { + var stream = assetLoader.Open(fontResource.Source); + + typeface = SKTypeface.FromStream(stream); + + if (typeface.FamilyName != familyKey) continue; + + var fontKey = new FontKey((SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant); + + entry[fontKey] = typeface; + } + + entry.TryGetValue(key, out typeface); if (typeface == null) { - typeface = SKTypeface.FromFamilyName(null, SKTypefaceStyle.Normal); + typeface = SKTypeface.FromFamilyName(null); } - //} + + return typeface; + } + + typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant); + + if (typeface == null) + { + typeface = SKTypeface.FromFamilyName(null); + } entry[key] = typeface; } diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 732089b79d..b6457adc41 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Reflection; using Avalonia.Media; +using Avalonia.Media.Fonts; using Avalonia.Platform; using SharpDX; using DWrite = SharpDX.DirectWrite; @@ -26,17 +27,13 @@ namespace Avalonia.Direct2D1.Media { Text = text; - var factory = AvaloniaLocator.Current.GetService(); + var factory = AvaloniaLocator.Current.GetService(); DWrite.TextFormat textFormat; if (typeface.FontFamily.Key != null) { - var fontFamilyCache = new FontFamilyCache(); - - var fontFamily = fontFamilyCache.GetOrAddFontFamily(typeface.FontFamily.Key); - - var fontCollection = Direct2D1CustomFontCollectionCache.GetOrAddCustomFontCollection(fontFamily, factory); + var fontCollection = Direct2D1CustomFontCollectionCache.GetOrAddCustomFontCollection(typeface.FontFamily.Key, factory); textFormat = new DWrite.TextFormat( factory, @@ -54,6 +51,7 @@ namespace Avalonia.Direct2D1.Media typeface.FontFamily.Name, (DWrite.FontWeight)typeface.Weight, (DWrite.FontStyle)typeface.Style, + DWrite.FontStretch.Normal, (float)typeface.FontSize); } @@ -154,13 +152,15 @@ namespace Avalonia.Direct2D1.Media private static readonly ConcurrentDictionary s_cachedFonts = new ConcurrentDictionary(); - public static DWrite.FontCollection GetOrAddCustomFontCollection(CachedFontFamily fontFamily, DWrite.Factory factory) + public static DWrite.FontCollection GetOrAddCustomFontCollection(FontFamilyKey key, DWrite.Factory factory) { - return s_cachedFonts.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(fontFamily, factory)); + return s_cachedFonts.GetOrAdd(key, x => CreateCustomFontCollection(key, factory)); } - private static DWrite.FontCollection CreateCustomFontCollection(CachedFontFamily fontFamily, DWrite.Factory factory) + private static DWrite.FontCollection CreateCustomFontCollection(FontFamilyKey key, DWrite.Factory factory) { + var fontFamily = FontFamilyCache.GetOrAddFontFamily(key); + var fontLoader = new ResourceFontLoader(factory, fontFamily.FontResources); return new DWrite.FontCollection(factory, fontLoader, fontLoader.Key); From 0da9083ba30345b9a0b67f91cd547c63d8d4e8ec Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Mon, 7 May 2018 13:49:38 +0200 Subject: [PATCH 12/36] Added comments --- samples/ControlCatalog.Desktop/Program.cs | 5 +- samples/ControlCatalog/Pages/BorderPage.xaml | 48 ++++++------ src/Avalonia.Visuals/Media/FontFamily.cs | 29 +++++++ .../Media/Fonts/CachedFontFamily.cs | 20 +++++ .../Media/Fonts/FontFamilyCache.cs | 13 ++++ .../Media/Fonts/FontFamilyKey.cs | 26 +++++++ .../Media/Fonts/FontResource.cs | 6 ++ .../Media/Fonts/FontResourceCollection.cs | 19 +++++ .../Media/Fonts/FontResourceLoader.cs | 75 +++++++++++++++++++ .../Media/Fonts/IFontResourceLoader.cs | 8 ++ 10 files changed, 219 insertions(+), 30 deletions(-) diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index ae458f52c6..a2048005a4 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -3,7 +3,6 @@ using System.Linq; using Avalonia; using Avalonia.Controls; using Avalonia.Logging.Serilog; -using Avalonia.Media; using Avalonia.Platform; using Serilog; @@ -23,13 +22,13 @@ namespace ControlCatalog /// This method is needed for IDE previewer infrastructure ///
public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure().LogToDebug().UsePlatformDetect().UseSkia(); + => AppBuilder.Configure().LogToDebug().UsePlatformDetect(); private static void ConfigureAssetAssembly(AppBuilder builder) { AvaloniaLocator.CurrentMutable .GetService() - .SetDefaultAssembly(typeof(App).Assembly); + .SetDefaultAssembly(typeof(App).Assembly); } } } diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml index 1ad18a2ac0..a81bd13ddd 100644 --- a/samples/ControlCatalog/Pages/BorderPage.xaml +++ b/samples/ControlCatalog/Pages/BorderPage.xaml @@ -1,38 +1,32 @@ - - Border - A control which decorates a child with a border and background + + Border + A control which decorates a child with a border and background - - - Border - - + Border + + - Border and Background - - Border and Background + + - Rounded Corners - - Rounded Corners + + - - Rounded Corners - Rounded Corners - Rounded Corners - Rounded Corners - Rounded Corners - - - - + Rounded Corners + + + \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 7f63930f1a..df933eb0ff 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -8,20 +8,49 @@ namespace Avalonia.Media { public class FontFamily { + /// + /// Initializes a new instance of the class. + /// + /// The name. + /// name public FontFamily(string name = "Courier New") { Name = name ?? throw new ArgumentNullException(nameof(name)); } + /// + /// + /// Initializes a new instance of the class. + /// + /// The name. + /// The source. public FontFamily(string name, Uri source) : this(name) { Key = new FontFamilyKey(source); } + /// + /// Gets the name. + /// + /// + /// The name. + /// public string Name { get; } + /// + /// Gets the key. + /// + /// + /// The key. + /// public FontFamilyKey Key { get; } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// public override string ToString() { if (Key != null) diff --git a/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs b/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs index d53ee69a5b..30bc4203c5 100644 --- a/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs +++ b/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs @@ -5,18 +5,38 @@ using System.Collections.Generic; namespace Avalonia.Media.Fonts { + /// + /// Holds a quantity of that belongs to a specific + /// public class CachedFontFamily { private readonly FontResourceCollection _fontResourceCollection; + /// + /// Initializes a new instance of the class. + /// + /// The key. + /// The font resource collection. public CachedFontFamily(FontFamilyKey key, FontResourceCollection fontResourceCollection) { Key = key; _fontResourceCollection = fontResourceCollection; } + /// + /// Gets the key. + /// + /// + /// The key. + /// public FontFamilyKey Key { get; } + /// + /// Gets the font resources. + /// + /// + /// The font resources. + /// public IEnumerable FontResources => _fontResourceCollection.FontResources; } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs index 52a4ddb311..6c8172ca2a 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs @@ -5,15 +5,28 @@ using System.Collections.Concurrent; namespace Avalonia.Media.Fonts { + /// + /// Caches all instances to reduce memory usage and speed up loading times of custom font families + /// public static class FontFamilyCache { private static readonly ConcurrentDictionary s_cachedFontFamilies = new ConcurrentDictionary(); + /// + /// Gets the or add cached font family. + /// + /// The key. + /// public static CachedFontFamily GetOrAddFontFamily(FontFamilyKey key) { return s_cachedFontFamilies.GetOrAdd(key, CreateCachedFontFamily); } + /// + /// Creates the cached font family. + /// + /// The font family key. + /// private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) { return new CachedFontFamily(fontFamilyKey, new FontResourceCollection(fontFamilyKey)); diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index 8ced4ea6bb..93c8b47d1d 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -6,8 +6,15 @@ using System.Linq; namespace Avalonia.Media.Fonts { + /// + /// Unique idetifier for a quantity of that is stored at a given location. + /// public class FontFamilyKey { + /// + /// Creates a new instance of and extracts and from given + /// + /// public FontFamilyKey(Uri source) { if (source.AbsolutePath.Contains(".ttf")) @@ -31,8 +38,14 @@ namespace Avalonia.Media.Fonts } } + /// + /// Location of stored that belong to a + /// public Uri Location { get; } + /// + /// Optional filename for that belong to a + /// public string FileName { get; } public override int GetHashCode() @@ -55,6 +68,13 @@ namespace Avalonia.Media.Fonts } } + /// + /// Determines whether the specified , is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// public override bool Equals(object obj) { if (!(obj is FontFamilyKey other)) return false; @@ -66,6 +86,12 @@ namespace Avalonia.Media.Fonts return true; } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// public override string ToString() { if (FileName != null) diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs index 470e17d7d6..67761bbc80 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs @@ -5,6 +5,9 @@ using System; namespace Avalonia.Media.Fonts { + /// + /// Represents a font resource + /// public class FontResource { public FontResource(Uri source) @@ -12,6 +15,9 @@ namespace Avalonia.Media.Fonts Source = source; } + /// + /// Source of the font resource. + /// public Uri Source { get; } } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs index 347380e121..a2a8c48de3 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs @@ -7,6 +7,9 @@ using System.Linq; namespace Avalonia.Media.Fonts { + /// + /// Represents a collection of that is identified by a unique + /// public class FontResourceCollection { private Dictionary _fontResources; @@ -17,8 +20,20 @@ namespace Avalonia.Media.Fonts Key = key; } + /// + /// Gets the key. + /// + /// + /// The key. + /// public FontFamilyKey Key { get; } + /// + /// Gets the font resources. + /// + /// + /// The font resources. + /// public IEnumerable FontResources { get @@ -32,6 +47,10 @@ namespace Avalonia.Media.Fonts } } + /// + /// Creates the font resources. + /// + /// private Dictionary CreateFontResources() { return _fontResourceLoader.GetFontResources(Key).ToDictionary(x => x.Source); diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs index 2f450679b1..e8fad17289 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs @@ -9,6 +9,10 @@ using Avalonia.Platform; namespace Avalonia.Media.Fonts { + /// + /// + /// Implementation of + /// public class FontResourceLoader : IFontResourceLoader { private static readonly Dictionary s_assemblyNameCache @@ -16,6 +20,10 @@ namespace Avalonia.Media.Fonts private readonly AssemblyDescriptor _defaultAssembly; + /// + /// Initializes a new instance of the class. + /// + /// The default assembly. public FontResourceLoader(Assembly assembly = null) { if (assembly == null) @@ -28,6 +36,12 @@ namespace Avalonia.Media.Fonts } } + /// + /// + /// Returns a quanity of that belongs to a given + /// + /// + /// public IEnumerable GetFontResources(FontFamilyKey fontFamilyKey) { return fontFamilyKey.FileName != null @@ -35,6 +49,11 @@ namespace Avalonia.Media.Fonts : GetFontResourcesByLocation(fontFamilyKey.Location); } + /// + /// Searches for font resources at a given location and returns a quanity of found resources + /// + /// + /// private IEnumerable GetFontResourcesByLocation(Uri location) { var assembly = GetAssembly(location); @@ -46,6 +65,13 @@ namespace Avalonia.Media.Fonts return matchingResources.Select(x => new FontResource(GetResourceUri(x, assembly.Name))); } + /// + /// Searches for font resources at a given location and only accepts resources that fit to a given filename expression. + /// Filenames can target multible files with * wildcard. For example "FontFile*.ttf" + /// + /// + /// + /// private IEnumerable GetFontResourcesByFileName(Uri location, string fileName) { var assembly = GetAssembly(location); @@ -57,11 +83,22 @@ namespace Avalonia.Media.Fonts return matchingResources.Select(x => new FontResource(GetResourceUri(x, assembly.Name))); } + /// + /// Returns a valid resource that follows the resm scheme + /// + /// + /// + /// private static Uri GetResourceUri(string path, string assemblyName) { return new Uri("resm:" + path + "?assembly=" + assemblyName); } + /// + /// Translates a given to a that follows the resm scheme. + /// + /// + /// private static string GetLocationPath(Uri uri) { if (uri.Scheme == "resm") return uri.AbsolutePath; @@ -71,6 +108,11 @@ namespace Avalonia.Media.Fonts return path; } + /// + /// Extracts a from a given + /// + /// + /// private AssemblyDescriptor GetAssembly(Uri uri) { if (uri == null) return null; @@ -80,6 +122,14 @@ namespace Avalonia.Media.Fonts return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : null; } + /// + /// Returns a that is identified by a given name. + /// + /// If name is null the default assembly is used. + /// + /// + /// + /// private AssemblyDescriptor GetAssembly(string name) { if (name == null) @@ -113,6 +163,11 @@ namespace Avalonia.Media.Fonts return rv; } + /// + /// Parses the parameters. + /// + /// The URI. + /// private static Dictionary ParseParameters(Uri uri) { return uri.Query.TrimStart('?') @@ -134,8 +189,28 @@ namespace Avalonia.Media.Fonts Name = Assembly.GetName().Name; } + /// + /// Gets the name. + /// + /// + /// The name. + /// public string Name { get; } + + /// + /// Gets the assembly. + /// + /// + /// The assembly. + /// public Assembly Assembly { get; } + + /// + /// Gets the resources. + /// + /// + /// The resources. + /// public List Resources { get; } } } diff --git a/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs index 44e665e3a1..c639d62623 100644 --- a/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs @@ -5,8 +5,16 @@ using System.Collections.Generic; namespace Avalonia.Media.Fonts { + /// + /// Loads that can be identified by a given + /// public interface IFontResourceLoader { + /// + /// Returns a quanity of that belongs to a given + /// + /// + /// IEnumerable GetFontResources(FontFamilyKey fontFamilyKey); } } \ No newline at end of file From 36d5aad6fee09d74a6e333e6f1f2efa57c66eb72 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Mon, 7 May 2018 13:50:23 +0200 Subject: [PATCH 13/36] Removed fonts --- samples/ControlCatalog/ControlCatalog.csproj | 18 ------------------ .../ControlCatalog/Fonts/Aspergit_Bold.ttf | Bin 16860 -> 0 bytes .../Fonts/Aspergit_Bold_Italic.ttf | Bin 18256 -> 0 bytes .../ControlCatalog/Fonts/Aspergit_Italic.ttf | Bin 18248 -> 0 bytes samples/ControlCatalog/Fonts/BolshevikBd.ttf | Bin 6928 -> 0 bytes .../ControlCatalog/Fonts/PinkHighwayBold.ttf | Bin 43816 -> 0 bytes .../Fonts/PixelOperator-Bold.ttf | Bin 18068 -> 0 bytes .../ControlCatalog/Fonts/PixelOperator.ttf | Bin 19836 -> 0 bytes 8 files changed, 18 deletions(-) delete mode 100644 samples/ControlCatalog/Fonts/Aspergit_Bold.ttf delete mode 100644 samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf delete mode 100644 samples/ControlCatalog/Fonts/Aspergit_Italic.ttf delete mode 100644 samples/ControlCatalog/Fonts/BolshevikBd.ttf delete mode 100644 samples/ControlCatalog/Fonts/PinkHighwayBold.ttf delete mode 100644 samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf delete mode 100644 samples/ControlCatalog/Fonts/PixelOperator.ttf diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 74bf3ec4bb..b8a8479a49 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -11,24 +11,6 @@ - - - - - - - - - - - - - - - - - - diff --git a/samples/ControlCatalog/Fonts/Aspergit_Bold.ttf b/samples/ControlCatalog/Fonts/Aspergit_Bold.ttf deleted file mode 100644 index c9d6b840e9e340fb6ab698c2e230a2a9c2593f7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16860 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 Q=>AUMY`hes{XYx-7Yu%bUH||9 diff --git a/samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf b/samples/ControlCatalog/Fonts/Aspergit_Bold_Italic.ttf deleted file mode 100644 index a5ba97f37749d88caeed4346b3151291063384db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18256 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 Jm;Rra{|4kce7FDr diff --git a/samples/ControlCatalog/Fonts/Aspergit_Italic.ttf b/samples/ControlCatalog/Fonts/Aspergit_Italic.ttf deleted file mode 100644 index d74ec43df22c7ff7e9df6eef9e2babedf76bfb05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18248 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 L$00h?@5B5Ll|r$X diff --git a/samples/ControlCatalog/Fonts/BolshevikBd.ttf b/samples/ControlCatalog/Fonts/BolshevikBd.ttf deleted file mode 100644 index 359ee1bc15d02b37194a2e1dfaca2327b280cbef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6928 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 M6aBvW_;U~b4?>$VrvLx| diff --git a/samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf b/samples/ControlCatalog/Fonts/PixelOperator-Bold.ttf deleted file mode 100644 index 154890a659f1d8c1ea956582dc58b56e4cc09e8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18068 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 F^8Ztzpb!86 diff --git a/samples/ControlCatalog/Fonts/PixelOperator.ttf b/samples/ControlCatalog/Fonts/PixelOperator.ttf deleted file mode 100644 index 277c408b5851e75ccbff95ae1ad462373e6fd309..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19836 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 Date: Mon, 7 May 2018 14:33:57 +0200 Subject: [PATCH 14/36] Introduce FontFamily.Parse --- src/Avalonia.Visuals/Media/FontFamily.cs | 45 +++++++++++++++++++ .../Converters/FontFamilyTypeConverter.cs | 36 +-------------- .../PortableXaml/portable.xaml.github | 2 +- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index df933eb0ff..1cb20411ef 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -60,5 +60,50 @@ namespace Avalonia.Media return Name; } + + /// + /// Parses a string. + /// + /// The string. + /// + /// + /// Specified family is not supported. + /// + public static FontFamily Parse(string s) + { + if (string.IsNullOrEmpty(s)) throw new ArgumentException("Specified family is not supported."); + + var fontFamilyExpression = s.Split('#'); + + if (fontFamilyExpression.Length == 1) + { + return new FontFamily(s); + } + + string familyName; + + Uri source = null; + + switch (fontFamilyExpression.Length) + { + case 1: + { + familyName = fontFamilyExpression[0]; + break; + } + case 2: + { + source = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); + familyName = fontFamilyExpression[1]; + break; + } + default: + { + throw new ArgumentException("Specified family is not supported."); + } + } + + return new FontFamily(familyName, source); + } } } diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs index 59742f8b12..9d03db5fa8 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs @@ -14,41 +14,7 @@ namespace Avalonia.Markup.Xaml.Converters public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { - var s = (string)value; - - if (string.IsNullOrEmpty(s)) throw new ArgumentException("Specified family is not supported."); - - var fontFamilyExpression = s.Split('#'); - - if (fontFamilyExpression.Length == 1) - { - return new FontFamily(s); - } - - string familyName; - - Uri source = null; - - switch (fontFamilyExpression.Length) - { - case 1: - { - familyName = fontFamilyExpression[0]; - break; - } - case 2: - { - source = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); - familyName = fontFamilyExpression[1]; - break; - } - default: - { - throw new ArgumentException("Specified family is not supported."); - } - } - - return new FontFamily(familyName, source); + return FontFamily.Parse((string)value); } } } \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github index cdf46d7892..c066401445 160000 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github @@ -1 +1 @@ -Subproject commit cdf46d7892def8a6ba29f12a9339147377f7cf5c +Subproject commit c0664014455392ac221a765e66f9837704339b6f From 3cd8368e54ecbc3a2bc34ac204e85fb2d858e494 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Mon, 7 May 2018 15:48:03 +0200 Subject: [PATCH 15/36] Rebase for portable.xaml submodule --- .../Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github index c066401445..cdf46d7892 160000 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github @@ -1 +1 @@ -Subproject commit c0664014455392ac221a765e66f9837704339b6f +Subproject commit cdf46d7892def8a6ba29f12a9339147377f7cf5c From 9cc53eb693cfeb658441f7ecc15becb2f6c46ae0 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 8 May 2018 21:15:14 +0200 Subject: [PATCH 16/36] Minor fixes; Removed res scheme support --- .../Media/Fonts/FontFamilyKey.cs | 23 ++++-------------- .../Media/Fonts/FontResourceLoader.cs | 24 ++++++------------- 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index 93c8b47d1d..0926df0744 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -19,18 +19,10 @@ namespace Avalonia.Media.Fonts { if (source.AbsolutePath.Contains(".ttf")) { - if (source.Scheme == "res") - { - FileName = source.AbsolutePath.Split('/').Last(); - Location = new Uri(source.OriginalString.Replace("/" + FileName, ""), UriKind.RelativeOrAbsolute); - } - else - { - var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); - var fileNameWithoutExtension = filePathWithoutExtension.Split('.').Last(); - FileName = fileNameWithoutExtension + ".ttf"; - Location = new Uri(source.OriginalString.Replace("." + FileName, ""), UriKind.RelativeOrAbsolute); - } + var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); + var fileNameWithoutExtension = filePathWithoutExtension.Split('.').Last(); + FileName = fileNameWithoutExtension + ".ttf"; + Location = new Uri(source.OriginalString.Replace("." + FileName, ""), UriKind.RelativeOrAbsolute); } else { @@ -96,12 +88,7 @@ namespace Avalonia.Media.Fonts { if (FileName != null) { - if (Location.Scheme == "resm") - { - return Location.AbsolutePath + "." + FileName; - } - - return Location.AbsolutePath + "/" + FileName; + return Location.AbsolutePath + "." + FileName; } return Location.AbsolutePath; diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs index e8fad17289..7286f5ad16 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs @@ -58,7 +58,9 @@ namespace Avalonia.Media.Fonts { var assembly = GetAssembly(location); - var locationPath = GetLocationPath(location); + if (assembly == null) return Enumerable.Empty(); + + var locationPath = location.AbsolutePath; var matchingResources = assembly.Resources.Where(x => x.Contains(locationPath)); @@ -76,7 +78,9 @@ namespace Avalonia.Media.Fonts { var assembly = GetAssembly(location); - var compareTo = GetLocationPath(location) + "." + fileName.Split('*').First(); + if (assembly == null) return Enumerable.Empty(); + + var compareTo = location.AbsolutePath + "." + fileName.Split('*').First(); var matchingResources = assembly.Resources.Where(x => x.Contains(compareTo)); @@ -94,20 +98,6 @@ namespace Avalonia.Media.Fonts return new Uri("resm:" + path + "?assembly=" + assemblyName); } - /// - /// Translates a given to a that follows the resm scheme. - /// - /// - /// - private static string GetLocationPath(Uri uri) - { - if (uri.Scheme == "resm") return uri.AbsolutePath; - - var path = uri.AbsolutePath.Replace("/", "."); - - return path; - } - /// /// Extracts a from a given /// @@ -119,7 +109,7 @@ namespace Avalonia.Media.Fonts var parameters = ParseParameters(uri); - return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : null; + return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : _defaultAssembly; } /// From fe1d7058e7ecc615c533593c03c0fa23eb7127ff Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 8 May 2018 22:48:19 +0200 Subject: [PATCH 17/36] Made font API internal Add FamilyNameList Add SKTypefaceCollection --- src/Avalonia.Visuals/Media/FontFamily.cs | 66 +++++---- .../Media/Fonts/CachedFontFamily.cs | 2 +- .../Media/Fonts/FontFamilyCache.cs | 2 +- .../Media/Fonts/FontFamilyKey.cs | 2 +- .../Media/Fonts/FontResource.cs | 2 +- .../Media/Fonts/FontResourceCollection.cs | 2 +- .../Media/Fonts/FontResourceLoader.cs | 2 +- .../Media/Fonts/IFontResourceLoader.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 + src/Skia/Avalonia.Skia/FormattedTextImpl.cs | 18 ++- src/Skia/Avalonia.Skia/TypefaceCache.cs | 140 ++++++++++++++---- .../Media/FormattedTextImpl.cs | 10 +- 12 files changed, 175 insertions(+), 75 deletions(-) diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 1cb20411ef..37faa1a068 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.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.Generic; using Avalonia.Media.Fonts; namespace Avalonia.Media @@ -15,7 +16,14 @@ namespace Avalonia.Media /// name public FontFamily(string name = "Courier New") { - Name = name ?? throw new ArgumentNullException(nameof(name)); + if (name == null) throw new ArgumentNullException(nameof(name)); + FamilyNames = new FamilyNameList(name); + } + + public FontFamily(IEnumerable names) + { + if (names == null) throw new ArgumentNullException(nameof(names)); + FamilyNames = new FamilyNameList(names); } /// @@ -35,7 +43,7 @@ namespace Avalonia.Media /// /// The name. /// - public string Name { get; } + public string Name => FamilyNames.FirstFamilyName; /// /// Gets the key. @@ -43,7 +51,9 @@ namespace Avalonia.Media /// /// The key. /// - public FontFamilyKey Key { get; } + internal FontFamilyKey Key { get; } + + internal FamilyNameList FamilyNames { get; } /// /// Returns a that represents this instance. @@ -61,6 +71,22 @@ namespace Avalonia.Media return Name; } + internal class FamilyNameList : List + { + public FamilyNameList(string familyName) + { + Add(familyName); + FirstFamilyName = familyName; + } + + public FamilyNameList(IEnumerable familyNames) : base(familyNames) + { + FirstFamilyName = this[0]; + } + + public string FirstFamilyName { get; } + } + /// /// Parses a string. /// @@ -75,35 +101,23 @@ namespace Avalonia.Media var fontFamilyExpression = s.Split('#'); - if (fontFamilyExpression.Length == 1) - { - return new FontFamily(s); - } - - string familyName; - - Uri source = null; - switch (fontFamilyExpression.Length) { case 1: - { - familyName = fontFamilyExpression[0]; - break; - } + { + var familyNames = fontFamilyExpression[0].Split(';'); + return new FontFamily(familyNames); + } case 2: - { - source = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); - familyName = fontFamilyExpression[1]; - break; - } + { + var source = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); + return new FontFamily(fontFamilyExpression[1], source); + } default: - { - throw new ArgumentException("Specified family is not supported."); - } + { + throw new ArgumentException("Specified family is not supported."); + } } - - return new FontFamily(familyName, source); } } } diff --git a/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs b/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs index 30bc4203c5..dc0cb8b305 100644 --- a/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs +++ b/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs @@ -8,7 +8,7 @@ namespace Avalonia.Media.Fonts /// /// Holds a quantity of that belongs to a specific /// - public class CachedFontFamily + internal class CachedFontFamily { private readonly FontResourceCollection _fontResourceCollection; diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs index 6c8172ca2a..4ce140b7e9 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs @@ -8,7 +8,7 @@ namespace Avalonia.Media.Fonts /// /// Caches all instances to reduce memory usage and speed up loading times of custom font families /// - public static class FontFamilyCache + internal static class FontFamilyCache { private static readonly ConcurrentDictionary s_cachedFontFamilies = new ConcurrentDictionary(); diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index 0926df0744..a6115b30e1 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -9,7 +9,7 @@ namespace Avalonia.Media.Fonts /// /// Unique idetifier for a quantity of that is stored at a given location. /// - public class FontFamilyKey + internal class FontFamilyKey { /// /// Creates a new instance of and extracts and from given diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs index 67761bbc80..50df3efefd 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs @@ -8,7 +8,7 @@ namespace Avalonia.Media.Fonts /// /// Represents a font resource /// - public class FontResource + internal class FontResource { public FontResource(Uri source) { diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs index a2a8c48de3..427ba25277 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs @@ -10,7 +10,7 @@ namespace Avalonia.Media.Fonts /// /// Represents a collection of that is identified by a unique /// - public class FontResourceCollection + internal class FontResourceCollection { private Dictionary _fontResources; private readonly IFontResourceLoader _fontResourceLoader = new FontResourceLoader(); diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs index 7286f5ad16..df7571ed3b 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs @@ -13,7 +13,7 @@ namespace Avalonia.Media.Fonts /// /// Implementation of /// - public class FontResourceLoader : IFontResourceLoader + internal class FontResourceLoader : IFontResourceLoader { private static readonly Dictionary s_assemblyNameCache = new Dictionary(); diff --git a/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs index c639d62623..16d512f743 100644 --- a/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs @@ -8,7 +8,7 @@ namespace Avalonia.Media.Fonts /// /// Loads that can be identified by a given /// - public interface IFontResourceLoader + internal interface IFontResourceLoader { /// /// Returns a quanity of that belongs to a given diff --git a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs index 900746d05a..6b93dedb29 100644 --- a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs @@ -11,5 +11,7 @@ using Avalonia.Metadata; [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")] +[assembly: InternalsVisibleTo("Avalonia.Direct2D1")] [assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests")] +[assembly: InternalsVisibleTo("Avalonia.Skia")] [assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests")] \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs index 23a9ec615e..ec00eb4148 100644 --- a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs +++ b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs @@ -25,10 +25,20 @@ namespace Avalonia.Skia // Replace 0 characters with zero-width spaces (200B) Text = Text.Replace((char)0, (char)0x200B); - var skiaTypeface = TypefaceCache.GetTypeface( - typeface.FontFamily, - typeface.Style, - typeface.Weight); + SKTypeface skiaTypeface; + + if (typeface.FontFamily.Key != null) + { + var typefaces = SKTypefaceCollectionCache.GetOrAddTypefaceCollection(typeface.FontFamily); + skiaTypeface = typefaces.GetTypeFace(typeface); + } + else + { + skiaTypeface = TypefaceCache.GetTypeface( + typeface.FontFamily, + typeface.Style, + typeface.Weight); + } _paint = new SKPaint(); diff --git a/src/Skia/Avalonia.Skia/TypefaceCache.cs b/src/Skia/Avalonia.Skia/TypefaceCache.cs index 96696488c3..c65336320c 100644 --- a/src/Skia/Avalonia.Skia/TypefaceCache.cs +++ b/src/Skia/Avalonia.Skia/TypefaceCache.cs @@ -1,6 +1,6 @@ -using System; +using System.Collections.Concurrent; using System.Collections.Generic; -using System.Text; +using System.Linq; using Avalonia.Media; using Avalonia.Media.Fonts; using Avalonia.Platform; @@ -40,13 +40,13 @@ namespace Avalonia.Skia public bool Equals(FontKey other) { return Slant == other.Slant && - Weight == other.Weight; + Weight == other.Weight; } // Equals and GetHashCode ommitted } - unsafe static SKTypeface GetTypeface(FontFamily fontFamily, FontKey key) + static SKTypeface GetTypeface(FontFamily fontFamily, FontKey key) { var familyKey = fontFamily.Name; @@ -57,53 +57,95 @@ namespace Avalonia.Skia if (!entry.TryGetValue(key, out var typeface)) { - if (fontFamily.Key != null) + typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant); + + if (typeface == null) { - var cachedFontFamily = FontFamilyCache.GetOrAddFontFamily(fontFamily.Key); + typeface = SKTypeface.FromFamilyName(null); + } - var assetLoader = AvaloniaLocator.Current.GetService(); + entry[key] = typeface; + } - foreach (var fontResource in cachedFontFamily.FontResources) - { - var stream = assetLoader.Open(fontResource.Source); + return typeface; + } - typeface = SKTypeface.FromStream(stream); + public static SKTypeface GetTypeface(FontFamily fontFamily, FontStyle style, FontWeight weight) + { + SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; - if (typeface.FamilyName != familyKey) continue; + switch (style) + { + case FontStyle.Italic: + skStyle = SKFontStyleSlant.Italic; + break; - var fontKey = new FontKey((SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant); + case FontStyle.Oblique: + skStyle = SKFontStyleSlant.Oblique; + break; + } - entry[fontKey] = typeface; - } + return GetTypeface(fontFamily, new FontKey((SKFontStyleWeight)weight, skStyle)); + } - entry.TryGetValue(key, out typeface); + } - if (typeface == null) - { - typeface = SKTypeface.FromFamilyName(null); - } + internal class SKTypefaceCollection + { + private static readonly SKTypeface s_defaultTypeface = SKTypeface.FromFamilyName(null); - return typeface; - } + struct FontKey + { + public readonly string Name; + public readonly SKFontStyleSlant Slant; + public readonly SKFontStyleWeight Weight; - typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant); + public FontKey(string name, SKFontStyleWeight weight, SKFontStyleSlant slant) + { + Name = name; + Slant = slant; + Weight = weight; + } - if (typeface == null) - { - typeface = SKTypeface.FromFamilyName(null); - } + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + Name.GetHashCode(); + hash = hash * 31 + (int)Slant; + hash = hash * 31 + (int)Weight; - entry[key] = typeface; + return hash; } - return typeface; + public override bool Equals(object other) + { + return other is FontKey ? Equals((FontKey)other) : false; + } + + public bool Equals(FontKey other) + { + return Name == other.Name && Slant == other.Slant && + Weight == other.Weight; + } + + // Equals and GetHashCode ommitted } - public static SKTypeface GetTypeface(FontFamily fontFamily, FontStyle style, FontWeight weight) + private readonly ConcurrentDictionary _cachedTypefaces = + new ConcurrentDictionary(); + + public void AddTypeFace(FontFamily fontFamily, SKTypeface typeface) + { + var key = new FontKey(fontFamily.Name, (SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant); + + _cachedTypefaces.TryAdd(key, typeface); + } + + public SKTypeface GetTypeFace(Typeface typeface) { SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; - switch (style) + switch (typeface.Style) { case FontStyle.Italic: skStyle = SKFontStyleSlant.Italic; @@ -114,8 +156,42 @@ namespace Avalonia.Skia break; } - return GetTypeface(fontFamily, new FontKey((SKFontStyleWeight)weight, skStyle)); + var key = new FontKey(typeface.FontFamily.Name, (SKFontStyleWeight)typeface.Weight, skStyle); + + return _cachedTypefaces.TryGetValue(key, out var skTypeface) ? skTypeface : s_defaultTypeface; + } + } + + internal static class SKTypefaceCollectionCache + { + private static readonly ConcurrentDictionary s_cachedCollections = + new ConcurrentDictionary(); + + public static SKTypefaceCollection GetOrAddTypefaceCollection(FontFamily fontFamily) + { + return s_cachedCollections.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(fontFamily)); } + private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) + { + var cachedFontFamily = FontFamilyCache.GetOrAddFontFamily(fontFamily.Key); + + var typeFaceCollection = new SKTypefaceCollection(); + + if (!cachedFontFamily.FontResources.Any()) return typeFaceCollection; + + var assetLoader = AvaloniaLocator.Current.GetService(); + + foreach (var fontResource in cachedFontFamily.FontResources) + { + var stream = assetLoader.Open(fontResource.Source); + + var typeface = SKTypeface.FromStream(stream); + + typeFaceCollection.AddTypeFace(fontFamily, typeface); + } + + return typeFaceCollection; + } } } \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index b6457adc41..3d2c6e64b9 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -4,9 +4,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Reflection; using Avalonia.Media; using Avalonia.Media.Fonts; using Avalonia.Platform; @@ -33,7 +31,7 @@ namespace Avalonia.Direct2D1.Media if (typeface.FontFamily.Key != null) { - var fontCollection = Direct2D1CustomFontCollectionCache.GetOrAddCustomFontCollection(typeface.FontFamily.Key, factory); + var fontCollection = Direct2D1CustomFontCollectionCache.GetOrAddCustomFontCollection(typeface.FontFamily, factory); textFormat = new DWrite.TextFormat( factory, @@ -152,9 +150,9 @@ namespace Avalonia.Direct2D1.Media private static readonly ConcurrentDictionary s_cachedFonts = new ConcurrentDictionary(); - public static DWrite.FontCollection GetOrAddCustomFontCollection(FontFamilyKey key, DWrite.Factory factory) + public static DWrite.FontCollection GetOrAddCustomFontCollection(FontFamily fontFamily, DWrite.Factory factory) { - return s_cachedFonts.GetOrAdd(key, x => CreateCustomFontCollection(key, factory)); + return s_cachedFonts.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(x, factory)); } private static DWrite.FontCollection CreateCustomFontCollection(FontFamilyKey key, DWrite.Factory factory) @@ -167,7 +165,7 @@ namespace Avalonia.Direct2D1.Media } } - public class ResourceFontLoader : CallbackBase, DWrite.FontCollectionLoader, DWrite.FontFileLoader + internal class ResourceFontLoader : CallbackBase, DWrite.FontCollectionLoader, DWrite.FontFileLoader { private readonly List _fontStreams = new List(); private readonly List _enumerators = new List(); From 01444ccfeee19cd3c0d5f023d3d0647079b7e79d Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 11 May 2018 21:36:27 +0200 Subject: [PATCH 18/36] FontFamily fallback --- src/Avalonia.Visuals/Media/FontFamily.cs | 92 +++--- .../Media/Fonts/CachedFontFamily.cs | 42 --- .../Media/Fonts/FamilyNameCollection.cs | 52 ++++ .../Media/Fonts/FontFamilyCache.cs | 35 --- .../Media/Fonts/FontFamilyKey.cs | 4 +- ...tResourceLoader.cs => FontFamilyLoader.cs} | 52 ++-- .../Media/Fonts/FontResource.cs | 12 +- .../Media/Fonts/FontResourceCollection.cs | 59 ---- .../Media/Fonts/IFontResourceLoader.cs | 20 -- src/Skia/Avalonia.Skia/FormattedTextImpl.cs | 30 +- .../Avalonia.Skia/SKTypefaceCollection.cs | 76 +++++ .../SKTypefaceCollectionCache.cs | 43 +++ src/Skia/Avalonia.Skia/TypefaceCache.cs | 121 +------- .../Avalonia.Direct2D1/Direct2D1Platform.cs | 2 +- .../Media/DWriteResourceFontFileEnumerator.cs | 67 +++++ .../Media/DWriteResourceFontFileStream.cs | 85 ++++++ .../Media/DWriteResourceFontLoader.cs | 97 ++++++ .../Media/Direct2D1FontCollectionCache.cs | 52 ++++ .../Media/FormattedTextImpl.cs | 282 +----------------- 19 files changed, 575 insertions(+), 648 deletions(-) delete mode 100644 src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs create mode 100644 src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs delete mode 100644 src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs rename src/Avalonia.Visuals/Media/Fonts/{FontResourceLoader.cs => FontFamilyLoader.cs} (76%) delete mode 100644 src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs delete mode 100644 src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs create mode 100644 src/Skia/Avalonia.Skia/SKTypefaceCollection.cs create mode 100644 src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs create mode 100644 src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs create mode 100644 src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs create mode 100644 src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs create mode 100644 src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 37faa1a068..5660156a1e 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -3,57 +3,73 @@ using System; using System.Collections.Generic; +using System.Linq; using Avalonia.Media.Fonts; namespace Avalonia.Media { public class FontFamily { + internal static FontFamily Default = new FontFamily("Courier New"); + /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The name. - /// name - public FontFamily(string name = "Courier New") + /// The name of the . + /// name + public FontFamily(string name) { - if (name == null) throw new ArgumentNullException(nameof(name)); - FamilyNames = new FamilyNameList(name); + if (name == null) throw new ArgumentNullException(); + FamilyNames = new FamilyNameCollection(new[] { name }); } + /// + /// Initializes a new instance of the class. + /// + /// The names of the . + /// name public FontFamily(IEnumerable names) { - if (names == null) throw new ArgumentNullException(nameof(names)); - FamilyNames = new FamilyNameList(names); + if (names == null) throw new ArgumentNullException(); + FamilyNames = new FamilyNameCollection(names); } - /// /// /// Initializes a new instance of the class. /// - /// The name. - /// The source. + /// The name of the . + /// The source of font resources. public FontFamily(string name, Uri source) : this(name) { Key = new FontFamilyKey(source); } /// - /// Gets the name. + /// Gets the name of the font family. /// /// - /// The name. + /// The name of the font family. /// - public string Name => FamilyNames.FirstFamilyName; + public string Name => FamilyNames.PrimaryFamilyName; /// - /// Gets the key. + /// Gets the family names. /// /// - /// The key. + /// The family familyNames. /// - internal FontFamilyKey Key { get; } + internal FamilyNameCollection FamilyNames + { + get; + } - internal FamilyNameList FamilyNames { get; } + /// + /// Gets the key for associated resources. + /// + /// + /// The family familyNames. + /// + internal FontFamilyKey Key { get; } /// /// Returns a that represents this instance. @@ -63,34 +79,13 @@ namespace Avalonia.Media /// public override string ToString() { - if (Key != null) - { - return Key + "#" + Name; - } - return Name; } - internal class FamilyNameList : List - { - public FamilyNameList(string familyName) - { - Add(familyName); - FirstFamilyName = familyName; - } - - public FamilyNameList(IEnumerable familyNames) : base(familyNames) - { - FirstFamilyName = this[0]; - } - - public string FirstFamilyName { get; } - } - /// - /// Parses a string. + /// Parses a string. /// - /// The string. + /// The string. /// /// /// Specified family is not supported. @@ -99,19 +94,20 @@ namespace Avalonia.Media { if (string.IsNullOrEmpty(s)) throw new ArgumentException("Specified family is not supported."); - var fontFamilyExpression = s.Split('#'); + var segments = s.Split('#'); - switch (fontFamilyExpression.Length) + switch (segments.Length) { case 1: - { - var familyNames = fontFamilyExpression[0].Split(';'); - return new FontFamily(familyNames); + { + var names = segments[0].Split(',') + .Select(x => x.Trim()) + .Where(x => !string.IsNullOrWhiteSpace(x)); + return new FontFamily(names); } case 2: { - var source = new Uri(fontFamilyExpression[0], UriKind.RelativeOrAbsolute); - return new FontFamily(fontFamilyExpression[1], source); + return new FontFamily(segments[1], new Uri(segments[0], UriKind.RelativeOrAbsolute)); } default: { diff --git a/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs b/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs deleted file mode 100644 index dc0cb8b305..0000000000 --- a/src/Avalonia.Visuals/Media/Fonts/CachedFontFamily.cs +++ /dev/null @@ -1,42 +0,0 @@ -// 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.Generic; - -namespace Avalonia.Media.Fonts -{ - /// - /// Holds a quantity of that belongs to a specific - /// - internal class CachedFontFamily - { - private readonly FontResourceCollection _fontResourceCollection; - - /// - /// Initializes a new instance of the class. - /// - /// The key. - /// The font resource collection. - public CachedFontFamily(FontFamilyKey key, FontResourceCollection fontResourceCollection) - { - Key = key; - _fontResourceCollection = fontResourceCollection; - } - - /// - /// Gets the key. - /// - /// - /// The key. - /// - public FontFamilyKey Key { get; } - - /// - /// Gets the font resources. - /// - /// - /// The font resources. - /// - public IEnumerable FontResources => _fontResourceCollection.FontResources; - } -} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs b/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs new file mode 100644 index 0000000000..6296b947cc --- /dev/null +++ b/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs @@ -0,0 +1,52 @@ +// 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; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace Avalonia.Media.Fonts +{ + internal class FamilyNameCollection : IEnumerable + { + private readonly ReadOnlyCollection _familyNames; + + public FamilyNameCollection(IEnumerable familyNames) + { + if (familyNames == null) throw new ArgumentNullException(nameof(familyNames)); + var names = new List(familyNames); + if (names.Count == 0) throw new ArgumentException($"{nameof(familyNames)} must not be empty."); + _familyNames = new ReadOnlyCollection(names); + PrimaryFamilyName = _familyNames.First(); + HasFallbacks = _familyNames.Count > 1; + } + + /// + /// Gets the primary family name. + /// + /// + /// The primary family name. + /// + public string PrimaryFamilyName { get; } + + /// + /// Gets a value indicating whether fallbacks are defined. + /// + /// + /// true if fallbacks are defined; otherwise, false. + /// + public bool HasFallbacks { get; } + + public IEnumerator GetEnumerator() + { + return _familyNames.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs deleted file mode 100644 index 4ce140b7e9..0000000000 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyCache.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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; - -namespace Avalonia.Media.Fonts -{ - /// - /// Caches all instances to reduce memory usage and speed up loading times of custom font families - /// - internal static class FontFamilyCache - { - private static readonly ConcurrentDictionary s_cachedFontFamilies = new ConcurrentDictionary(); - - /// - /// Gets the or add cached font family. - /// - /// The key. - /// - public static CachedFontFamily GetOrAddFontFamily(FontFamilyKey key) - { - return s_cachedFontFamilies.GetOrAdd(key, CreateCachedFontFamily); - } - - /// - /// Creates the cached font family. - /// - /// The font family key. - /// - private static CachedFontFamily CreateCachedFontFamily(FontFamilyKey fontFamilyKey) - { - return new CachedFontFamily(fontFamilyKey, new FontResourceCollection(fontFamilyKey)); - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index a6115b30e1..d0e3207c70 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -7,7 +7,7 @@ using System.Linq; namespace Avalonia.Media.Fonts { /// - /// Unique idetifier for a quantity of that is stored at a given location. + /// Represents an idetifier for a /// internal class FontFamilyKey { @@ -16,7 +16,7 @@ namespace Avalonia.Media.Fonts /// /// public FontFamilyKey(Uri source) - { + { if (source.AbsolutePath.Contains(".ttf")) { var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs similarity index 76% rename from src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs rename to src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs index df7571ed3b..d972c7571a 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResourceLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs @@ -9,40 +9,19 @@ using Avalonia.Platform; namespace Avalonia.Media.Fonts { - /// - /// - /// Implementation of - /// - internal class FontResourceLoader : IFontResourceLoader + internal static class FontFamilyLoader { private static readonly Dictionary s_assemblyNameCache = new Dictionary(); - private readonly AssemblyDescriptor _defaultAssembly; + private static readonly AssemblyDescriptor s_defaultAssembly; - /// - /// Initializes a new instance of the class. - /// - /// The default assembly. - public FontResourceLoader(Assembly assembly = null) + static FontFamilyLoader() { - if (assembly == null) - { - assembly = Assembly.GetEntryAssembly(); - } - if (assembly != null) - { - _defaultAssembly = new AssemblyDescriptor(assembly); - } + s_defaultAssembly = new AssemblyDescriptor(Assembly.GetEntryAssembly()); } - /// - /// - /// Returns a quanity of that belongs to a given - /// - /// - /// - public IEnumerable GetFontResources(FontFamilyKey fontFamilyKey) + public static IEnumerable GetFontResources(FontFamilyKey fontFamilyKey) { return fontFamilyKey.FileName != null ? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) @@ -54,7 +33,7 @@ namespace Avalonia.Media.Fonts /// /// /// - private IEnumerable GetFontResourcesByLocation(Uri location) + private static IEnumerable GetFontResourcesByLocation(Uri location) { var assembly = GetAssembly(location); @@ -64,7 +43,7 @@ namespace Avalonia.Media.Fonts var matchingResources = assembly.Resources.Where(x => x.Contains(locationPath)); - return matchingResources.Select(x => new FontResource(GetResourceUri(x, assembly.Name))); + return matchingResources.Select(x => CreateResource(GetResourceUri(x, assembly.Name))); } /// @@ -74,7 +53,7 @@ namespace Avalonia.Media.Fonts /// /// /// - private IEnumerable GetFontResourcesByFileName(Uri location, string fileName) + private static IEnumerable GetFontResourcesByFileName(Uri location, string fileName) { var assembly = GetAssembly(location); @@ -84,7 +63,12 @@ namespace Avalonia.Media.Fonts var matchingResources = assembly.Resources.Where(x => x.Contains(compareTo)); - return matchingResources.Select(x => new FontResource(GetResourceUri(x, assembly.Name))); + return matchingResources.Select(x => CreateResource(GetResourceUri(x, assembly.Name))); + } + + private static FontResource CreateResource(Uri source) + { + return new FontResource(source); } /// @@ -103,13 +87,13 @@ namespace Avalonia.Media.Fonts /// /// /// - private AssemblyDescriptor GetAssembly(Uri uri) + private static AssemblyDescriptor GetAssembly(Uri uri) { if (uri == null) return null; var parameters = ParseParameters(uri); - return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : _defaultAssembly; + return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : s_defaultAssembly; } /// @@ -120,11 +104,11 @@ namespace Avalonia.Media.Fonts /// /// /// - private AssemblyDescriptor GetAssembly(string name) + private static AssemblyDescriptor GetAssembly(string name) { if (name == null) { - return _defaultAssembly; + return s_defaultAssembly; } if (!s_assemblyNameCache.TryGetValue(name, out var rv)) diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs index 50df3efefd..84e2153b42 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontResource.cs @@ -5,19 +5,23 @@ using System; namespace Avalonia.Media.Fonts { - /// - /// Represents a font resource - /// internal class FontResource { + /// + /// Initializes a new instance of the class. + /// + /// The source. public FontResource(Uri source) { Source = source; } /// - /// Source of the font resource. + /// Gets the source. /// + /// + /// The source. + /// public Uri Source { get; } } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs b/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs deleted file mode 100644 index 427ba25277..0000000000 --- a/src/Avalonia.Visuals/Media/Fonts/FontResourceCollection.cs +++ /dev/null @@ -1,59 +0,0 @@ -// 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.Linq; - -namespace Avalonia.Media.Fonts -{ - /// - /// Represents a collection of that is identified by a unique - /// - internal class FontResourceCollection - { - private Dictionary _fontResources; - private readonly IFontResourceLoader _fontResourceLoader = new FontResourceLoader(); - - public FontResourceCollection(FontFamilyKey key) - { - Key = key; - } - - /// - /// Gets the key. - /// - /// - /// The key. - /// - public FontFamilyKey Key { get; } - - /// - /// Gets the font resources. - /// - /// - /// The font resources. - /// - public IEnumerable FontResources - { - get - { - if (_fontResources == null) - { - _fontResources = CreateFontResources(); - } - - return _fontResources.Values; - } - } - - /// - /// Creates the font resources. - /// - /// - private Dictionary CreateFontResources() - { - return _fontResourceLoader.GetFontResources(Key).ToDictionary(x => x.Source); - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs b/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs deleted file mode 100644 index 16d512f743..0000000000 --- a/src/Avalonia.Visuals/Media/Fonts/IFontResourceLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -// 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.Generic; - -namespace Avalonia.Media.Fonts -{ - /// - /// Loads that can be identified by a given - /// - internal interface IFontResourceLoader - { - /// - /// Returns a quanity of that belongs to a given - /// - /// - /// - IEnumerable GetFontResources(FontFamilyKey fontFamilyKey); - } -} \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs index ec00eb4148..00f0a48a7b 100644 --- a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs +++ b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs @@ -25,7 +25,7 @@ namespace Avalonia.Skia // Replace 0 characters with zero-width spaces (200B) Text = Text.Replace((char)0, (char)0x200B); - SKTypeface skiaTypeface; + SKTypeface skiaTypeface = TypefaceCache.Default; if (typeface.FontFamily.Key != null) { @@ -34,11 +34,25 @@ namespace Avalonia.Skia } else { - skiaTypeface = TypefaceCache.GetTypeface( - typeface.FontFamily, - typeface.Style, - typeface.Weight); - } + if (typeface.FontFamily.FamilyNames.HasFallbacks) + { + foreach (var familyName in typeface.FontFamily.FamilyNames) + { + skiaTypeface = TypefaceCache.GetTypeface( + familyName, + typeface.Style, + typeface.Weight); + if (skiaTypeface != TypefaceCache.Default) break; + } + } + else + { + skiaTypeface = TypefaceCache.GetTypeface( + typeface.FontFamily.Name, + typeface.Style, + typeface.Weight); + } + } _paint = new SKPaint(); @@ -46,7 +60,7 @@ namespace Avalonia.Skia //Paint.TextEncoding = SKTextEncoding.Utf8; _paint.TextEncoding = SKTextEncoding.Utf16; _paint.IsStroke = false; - _paint.IsAntialias = true; + _paint.IsAntialias = true; _paint.LcdRenderText = true; _paint.SubpixelText = true; _paint.Typeface = skiaTypeface; @@ -256,7 +270,7 @@ namespace Avalonia.Skia subStr = Text.Substring(i, len); ApplyWrapperTo(ref currentPaint, currentWrapper, ref currd, paint, canUseLcdRendering); - + canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint); i += len; diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs new file mode 100644 index 0000000000..00e5cf62b3 --- /dev/null +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs @@ -0,0 +1,76 @@ +using System.Collections.Concurrent; +using Avalonia.Media; +using SkiaSharp; + +namespace Avalonia.Skia +{ + internal class SKTypefaceCollection + { + struct FontKey + { + public readonly string Name; + public readonly SKFontStyleSlant Slant; + public readonly SKFontStyleWeight Weight; + + public FontKey(string name, SKFontStyleWeight weight, SKFontStyleSlant slant) + { + Name = name; + Slant = slant; + Weight = weight; + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + Name.GetHashCode(); + hash = hash * 31 + (int)Slant; + hash = hash * 31 + (int)Weight; + + return hash; + } + + public override bool Equals(object other) + { + return other is FontKey ? Equals((FontKey)other) : false; + } + + public bool Equals(FontKey other) + { + return Name == other.Name && Slant == other.Slant && + Weight == other.Weight; + } + + // Equals and GetHashCode ommitted + } + + private readonly ConcurrentDictionary _cachedTypefaces = + new ConcurrentDictionary(); + + public void AddTypeFace(SKTypeface typeface) + { + var key = new FontKey(typeface.FamilyName, (SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant); + + _cachedTypefaces.TryAdd(key, typeface); + } + + public SKTypeface GetTypeFace(Typeface typeface) + { + SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; + + switch (typeface.Style) + { + case FontStyle.Italic: + skStyle = SKFontStyleSlant.Italic; + break; + + case FontStyle.Oblique: + skStyle = SKFontStyleSlant.Oblique; + break; + } + + var key = new FontKey(typeface.FontFamily.Name, (SKFontStyleWeight)typeface.Weight, skStyle); + + return _cachedTypefaces.TryGetValue(key, out var skTypeface) ? skTypeface : TypefaceCache.Default; + } + } +} \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs new file mode 100644 index 0000000000..fddca39f3f --- /dev/null +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs @@ -0,0 +1,43 @@ +using System.Collections.Concurrent; +using Avalonia.Media; +using Avalonia.Media.Fonts; +using Avalonia.Platform; +using SkiaSharp; + +namespace Avalonia.Skia +{ + internal static class SKTypefaceCollectionCache + { + private static readonly ConcurrentDictionary s_cachedCollections; + + static SKTypefaceCollectionCache() + { + s_cachedCollections = new ConcurrentDictionary(); + } + + public static SKTypefaceCollection GetOrAddTypefaceCollection(FontFamily fontFamily) + { + return s_cachedCollections.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(fontFamily)); + } + + private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) + { + var resources = FontFamilyLoader.GetFontResources(fontFamily.Key); + + var typeFaceCollection = new SKTypefaceCollection(); + + var assetLoader = AvaloniaLocator.Current.GetService(); + + foreach (var fontResource in resources) + { + var stream = assetLoader.Open(fontResource.Source); + + var typeface = SKTypeface.FromStream(stream); + + typeFaceCollection.AddTypeFace(typeface); + } + + return typeFaceCollection; + } + } +} \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/TypefaceCache.cs b/src/Skia/Avalonia.Skia/TypefaceCache.cs index c65336320c..24674f3b22 100644 --- a/src/Skia/Avalonia.Skia/TypefaceCache.cs +++ b/src/Skia/Avalonia.Skia/TypefaceCache.cs @@ -1,15 +1,13 @@ -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using Avalonia.Media; -using Avalonia.Media.Fonts; -using Avalonia.Platform; using SkiaSharp; namespace Avalonia.Skia { static class TypefaceCache { + public static SKTypeface Default = SKTypeface.FromFamilyName(FontFamily.Default.Name); static readonly Dictionary> Cache = new Dictionary>(); struct FontKey @@ -46,9 +44,9 @@ namespace Avalonia.Skia // Equals and GetHashCode ommitted } - static SKTypeface GetTypeface(FontFamily fontFamily, FontKey key) + private static SKTypeface GetTypeface(string name, FontKey key) { - var familyKey = fontFamily.Name; + var familyKey = name; if (!Cache.TryGetValue(familyKey, out var entry)) { @@ -59,9 +57,9 @@ namespace Avalonia.Skia { typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant); - if (typeface == null) + if (typeface.FamilyName != name) { - typeface = SKTypeface.FromFamilyName(null); + typeface = Default; } entry[key] = typeface; @@ -70,7 +68,7 @@ namespace Avalonia.Skia return typeface; } - public static SKTypeface GetTypeface(FontFamily fontFamily, FontStyle style, FontWeight weight) + public static SKTypeface GetTypeface(string name, FontStyle style, FontWeight weight) { SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; @@ -85,113 +83,8 @@ namespace Avalonia.Skia break; } - return GetTypeface(fontFamily, new FontKey((SKFontStyleWeight)weight, skStyle)); + return GetTypeface(name, new FontKey((SKFontStyleWeight)weight, skStyle)); } } - - internal class SKTypefaceCollection - { - private static readonly SKTypeface s_defaultTypeface = SKTypeface.FromFamilyName(null); - - struct FontKey - { - public readonly string Name; - public readonly SKFontStyleSlant Slant; - public readonly SKFontStyleWeight Weight; - - public FontKey(string name, SKFontStyleWeight weight, SKFontStyleSlant slant) - { - Name = name; - Slant = slant; - Weight = weight; - } - - public override int GetHashCode() - { - int hash = 17; - hash = hash * 31 + Name.GetHashCode(); - hash = hash * 31 + (int)Slant; - hash = hash * 31 + (int)Weight; - - return hash; - } - - public override bool Equals(object other) - { - return other is FontKey ? Equals((FontKey)other) : false; - } - - public bool Equals(FontKey other) - { - return Name == other.Name && Slant == other.Slant && - Weight == other.Weight; - } - - // Equals and GetHashCode ommitted - } - - private readonly ConcurrentDictionary _cachedTypefaces = - new ConcurrentDictionary(); - - public void AddTypeFace(FontFamily fontFamily, SKTypeface typeface) - { - var key = new FontKey(fontFamily.Name, (SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant); - - _cachedTypefaces.TryAdd(key, typeface); - } - - public SKTypeface GetTypeFace(Typeface typeface) - { - SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; - - switch (typeface.Style) - { - case FontStyle.Italic: - skStyle = SKFontStyleSlant.Italic; - break; - - case FontStyle.Oblique: - skStyle = SKFontStyleSlant.Oblique; - break; - } - - var key = new FontKey(typeface.FontFamily.Name, (SKFontStyleWeight)typeface.Weight, skStyle); - - return _cachedTypefaces.TryGetValue(key, out var skTypeface) ? skTypeface : s_defaultTypeface; - } - } - - internal static class SKTypefaceCollectionCache - { - private static readonly ConcurrentDictionary s_cachedCollections = - new ConcurrentDictionary(); - - public static SKTypefaceCollection GetOrAddTypefaceCollection(FontFamily fontFamily) - { - return s_cachedCollections.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(fontFamily)); - } - - private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) - { - var cachedFontFamily = FontFamilyCache.GetOrAddFontFamily(fontFamily.Key); - - var typeFaceCollection = new SKTypefaceCollection(); - - if (!cachedFontFamily.FontResources.Any()) return typeFaceCollection; - - var assetLoader = AvaloniaLocator.Current.GetService(); - - foreach (var fontResource in cachedFontFamily.FontResources) - { - var stream = assetLoader.Open(fontResource.Source); - - var typeface = SKTypeface.FromStream(stream); - - typeFaceCollection.AddTypeFace(fontFamily, typeface); - } - - return typeFaceCollection; - } - } } \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 296edcb2d9..0c3b01bbf1 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -117,7 +117,7 @@ namespace Avalonia.Direct2D1 } public IFormattedTextImpl CreateFormattedText( - string text, + string text, Typeface typeface, TextAlignment textAlignment, TextWrapping wrapping, diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs new file mode 100644 index 0000000000..c144e12aea --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs @@ -0,0 +1,67 @@ +using SharpDX; +using SharpDX.DirectWrite; + +namespace Avalonia.Direct2D1.Media +{ + /// + /// Resource FontFileEnumerator. + /// + public class DWriteResourceFontFileEnumerator : CallbackBase, FontFileEnumerator + { + private readonly Factory _factory; + private readonly FontFileLoader _loader; + private readonly DataStream _keyStream; + private FontFile _currentFontFile; + + /// + /// Initializes a new instance of the class. + /// + /// The factory. + /// The loader. + /// The key. + public DWriteResourceFontFileEnumerator(Factory factory, FontFileLoader loader, DataPointer key) + { + _factory = factory; + _loader = loader; + _keyStream = new DataStream(key.Pointer, key.Size, true, false); + } + + /// + /// Advances to the next font file in the collection. When it is first created, the enumerator is positioned before the first element of the collection and the first call to MoveNext advances to the first file. + /// + /// + /// the value TRUE if the enumerator advances to a file; otherwise, FALSE if the enumerator advances past the last file in the collection. + /// + /// HRESULT IDWriteFontFileEnumerator::MoveNext([Out] BOOL* hasCurrentFile) + bool FontFileEnumerator.MoveNext() + { + bool moveNext = _keyStream.RemainingLength != 0; + + if (!moveNext) return false; + + _currentFontFile?.Dispose(); + + _currentFontFile = new FontFile(_factory, _keyStream.PositionPointer, 4, _loader); + + _keyStream.Position += 4; + + return true; + } + + /// + /// Gets a reference to the current font file. + /// + /// + /// a reference to the newly created object. + /// HRESULT IDWriteFontFileEnumerator::GetCurrentFontFile([Out] IDWriteFontFile** fontFile) + FontFile FontFileEnumerator.CurrentFontFile + { + get + { + ((IUnknown)_currentFontFile).AddReference(); + + return _currentFontFile; + } + } + } +} \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs new file mode 100644 index 0000000000..37f283c162 --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs @@ -0,0 +1,85 @@ +using System; +using SharpDX; +using SharpDX.DirectWrite; + +namespace Avalonia.Direct2D1.Media +{ + /// + /// This FontFileStream implem is reading data from a . + /// + public class DWriteResourceFontFileStream : CallbackBase, FontFileStream + { + private readonly DataStream _stream; + + /// + /// Initializes a new instance of the class. + /// + /// The stream. + public DWriteResourceFontFileStream(DataStream stream) + { + _stream = stream; + } + + /// + /// Reads a fragment from a font file. + /// + /// When this method returns, contains an address of a reference to the start of the font file fragment. This parameter is passed uninitialized. + /// The offset of the fragment, in bytes, from the beginning of the font file. + /// The size of the file fragment, in bytes. + /// When this method returns, contains the address of + /// + /// Note that ReadFileFragment implementations must check whether the requested font file fragment is within the file bounds. Otherwise, an error should be returned from ReadFileFragment. {{DirectWrite}} may invoke methods on the same object from multiple threads simultaneously. Therefore, ReadFileFragment implementations that rely on internal mutable state must serialize access to such state across multiple threads. For example, an implementation that uses separate Seek and Read operations to read a file fragment must place the code block containing Seek and Read calls under a lock or a critical section. + /// + /// HRESULT IDWriteFontFileStream::ReadFileFragment([Out, Buffer] const void** fragmentStart,[None] __int64 fileOffset,[None] __int64 fragmentSize,[Out] void** fragmentContext) + void FontFileStream.ReadFileFragment(out IntPtr fragmentStart, long fileOffset, long fragmentSize, out IntPtr fragmentContext) + { + lock (this) + { + fragmentContext = IntPtr.Zero; + + _stream.Position = fileOffset; + + fragmentStart = _stream.PositionPointer; + + } + } + + /// + /// Releases a fragment from a file. + /// + /// A reference to the client-defined context of a font fragment returned from {{ReadFileFragment}}. + /// void IDWriteFontFileStream::ReleaseFileFragment([None] void* fragmentContext) + void FontFileStream.ReleaseFileFragment(IntPtr fragmentContext) + { + // Nothing to release. No context are used + } + + /// + /// Obtains the total size of a file. + /// + /// the total size of the file. + /// + /// Implementing GetFileSize() for asynchronously loaded font files may require downloading the complete file contents. Therefore, this method should be used only for operations that either require a complete font file to be loaded (for example, copying a font file) or that need to make decisions based on the value of the file size (for example, validation against a persisted file size). + /// + /// HRESULT IDWriteFontFileStream::GetFileSize([Out] __int64* fileSize) + long FontFileStream.GetFileSize() + { + return _stream.Length; + } + + /// + /// Obtains the last modified time of the file. + /// + /// + /// the last modified time of the file in the format that represents the number of 100-nanosecond intervals since January 1, 1601 (UTC). + /// + /// + /// The "last modified time" is used by DirectWrite font selection algorithms to determine whether one font resource is more up to date than another one. + /// + /// HRESULT IDWriteFontFileStream::GetLastWriteTime([Out] __int64* lastWriteTime) + long FontFileStream.GetLastWriteTime() + { + return 0; + } + } +} \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs new file mode 100644 index 0000000000..da2ec8c0a6 --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs @@ -0,0 +1,97 @@ +using System.Collections.Generic; +using Avalonia.Media.Fonts; +using Avalonia.Platform; +using SharpDX; +using SharpDX.DirectWrite; + +namespace Avalonia.Direct2D1.Media +{ + internal class DWriteResourceFontLoader : CallbackBase, FontCollectionLoader, FontFileLoader + { + private readonly List _fontStreams = new List(); + private readonly List _enumerators = new List(); + private readonly DataStream _keyStream; + + /// + /// Initializes a new instance of the class. + /// + /// The factory. + /// + public DWriteResourceFontLoader(Factory factory, IEnumerable fontResources) + { + var factory1 = factory; + + var assetLoader = AvaloniaLocator.Current.GetService(); + + foreach (var font in fontResources) + { + var resourceStream = assetLoader.Open(font.Source); + + var dataStream = new DataStream((int)resourceStream.Length, true, true); + + resourceStream.CopyTo(dataStream); + + dataStream.Position = 0; + + _fontStreams.Add(new DWriteResourceFontFileStream(dataStream)); + } + + // Build a Key storage that stores the index of the font + _keyStream = new DataStream(sizeof(int) * _fontStreams.Count, true, true); + + for (int i = 0; i < _fontStreams.Count; i++) + { + _keyStream.Write(i); + } + + _keyStream.Position = 0; + + // Register the + factory1.RegisterFontFileLoader(this); + factory1.RegisterFontCollectionLoader(this); + } + + + /// + /// Gets the key used to identify the FontCollection as well as storing index for fonts. + /// + /// The key. + public DataStream Key => _keyStream; + + /// + /// Creates a font file enumerator object that encapsulates a collection of font files. The font system calls back to this interface to create a font collection. + /// + /// Pointer to the object that was used to create the current font collection. + /// A font collection key that uniquely identifies the collection of font files within the scope of the font collection loader being used. The buffer allocated for this key must be at least the size, in bytes, specified by collectionKeySize. + /// + /// a reference to the newly created font file enumerator. + /// + /// HRESULT IDWriteFontCollectionLoader::CreateEnumeratorFromKey([None] IDWriteFactory* factory,[In, Buffer] const void* collectionKey,[None] int collectionKeySize,[Out] IDWriteFontFileEnumerator** fontFileEnumerator) + FontFileEnumerator FontCollectionLoader.CreateEnumeratorFromKey(Factory factory, DataPointer collectionKey) + { + var enumerator = new DWriteResourceFontFileEnumerator(factory, this, collectionKey); + + _enumerators.Add(enumerator); + + return enumerator; + } + + /// + /// Creates a font file stream object that encapsulates an open file resource. + /// + /// A reference to a font file reference key that uniquely identifies the font file resource within the scope of the font loader being used. The buffer allocated for this key must at least be the size, in bytes, specified by fontFileReferenceKeySize. + /// + /// a reference to the newly created object. + /// + /// + /// The resource is closed when the last reference to fontFileStream is released. + /// + /// HRESULT IDWriteFontFileLoader::CreateStreamFromKey([In, Buffer] const void* fontFileReferenceKey,[None] int fontFileReferenceKeySize,[Out] IDWriteFontFileStream** fontFileStream) + FontFileStream FontFileLoader.CreateStreamFromKey(DataPointer fontFileReferenceKey) + { + var index = SharpDX.Utilities.Read(fontFileReferenceKey.Pointer); + + return _fontStreams[index]; + } + } +} \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs new file mode 100644 index 0000000000..bbb438b204 --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs @@ -0,0 +1,52 @@ +using System.Collections.Concurrent; +using Avalonia.Media; +using Avalonia.Media.Fonts; + +namespace Avalonia.Direct2D1.Media +{ + internal static class Direct2D1FontCollectionCache + { + private static readonly ConcurrentDictionary s_cachedCollections; + private static readonly SharpDX.DirectWrite.Factory s_factory; + private static readonly SharpDX.DirectWrite.FontCollection s_installedFontCollection; + + static Direct2D1FontCollectionCache() + { + s_cachedCollections = new ConcurrentDictionary(); + s_factory = AvaloniaLocator.Current.GetService(); + s_installedFontCollection = s_factory.GetSystemFontCollection(false); + } + + public static SharpDX.DirectWrite.FontCollection GetOrAddFontCollection(FontFamily fontFamily) + { + return fontFamily.Key == null ? s_installedFontCollection : s_cachedCollections.GetOrAdd(fontFamily.Key, CreateFontCollection); + } + + private static SharpDX.DirectWrite.FontCollection CreateFontCollection(FontFamilyKey key) + { + var resources = FontFamilyLoader.GetFontResources(key); + + var fontLoader = new DWriteResourceFontLoader(s_factory, resources); + + return new SharpDX.DirectWrite.FontCollection(s_factory, fontLoader, fontLoader.Key); + } + + public static SharpDX.DirectWrite.TextFormat GetTextFormat(Typeface typeface) + { + var fontFamily = typeface.FontFamily; + var fontCollection = GetOrAddFontCollection(fontFamily); + var fontFamilyName = FontFamily.Default.Name; + + //Should this be cached? + foreach (var familyName in fontFamily.FamilyNames) + { + if (!fontCollection.FindFamilyName(familyName, out _)) continue; + fontFamilyName = familyName; + break; + } + + return new SharpDX.DirectWrite.TextFormat(s_factory, fontFamilyName, fontCollection, (SharpDX.DirectWrite.FontWeight)typeface.Weight, + (SharpDX.DirectWrite.FontStyle)typeface.Style, SharpDX.DirectWrite.FontStretch.Normal, (float)typeface.FontSize); + } + } +} \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 3d2c6e64b9..61ed73d414 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -1,14 +1,10 @@ // 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.Concurrent; using System.Collections.Generic; using System.Linq; using Avalonia.Media; -using Avalonia.Media.Fonts; using Avalonia.Platform; -using SharpDX; using DWrite = SharpDX.DirectWrite; namespace Avalonia.Direct2D1.Media @@ -27,31 +23,7 @@ namespace Avalonia.Direct2D1.Media var factory = AvaloniaLocator.Current.GetService(); - DWrite.TextFormat textFormat; - - if (typeface.FontFamily.Key != null) - { - var fontCollection = Direct2D1CustomFontCollectionCache.GetOrAddCustomFontCollection(typeface.FontFamily, factory); - - textFormat = new DWrite.TextFormat( - factory, - typeface.FontFamily.Name, - fontCollection, - (DWrite.FontWeight)typeface.Weight, - (DWrite.FontStyle)typeface.Style, - DWrite.FontStretch.Normal, - (float)typeface.FontSize); - } - else - { - textFormat = new DWrite.TextFormat( - factory, - typeface.FontFamily.Name, - (DWrite.FontWeight)typeface.Weight, - (DWrite.FontStyle)typeface.Style, - DWrite.FontStretch.Normal, - (float)typeface.FontSize); - } + var textFormat = Direct2D1FontCollectionCache.GetTextFormat(typeface); textFormat.WordWrapping = wrapping == TextWrapping.Wrap ? DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap; @@ -144,256 +116,4 @@ namespace Avalonia.Direct2D1.Media return new Size(width, TextLayout.Metrics.Height); } } - - internal static class Direct2D1CustomFontCollectionCache - { - private static readonly ConcurrentDictionary s_cachedFonts = - new ConcurrentDictionary(); - - public static DWrite.FontCollection GetOrAddCustomFontCollection(FontFamily fontFamily, DWrite.Factory factory) - { - return s_cachedFonts.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(x, factory)); - } - - private static DWrite.FontCollection CreateCustomFontCollection(FontFamilyKey key, DWrite.Factory factory) - { - var fontFamily = FontFamilyCache.GetOrAddFontFamily(key); - - var fontLoader = new ResourceFontLoader(factory, fontFamily.FontResources); - - return new DWrite.FontCollection(factory, fontLoader, fontLoader.Key); - } - } - - internal class ResourceFontLoader : CallbackBase, DWrite.FontCollectionLoader, DWrite.FontFileLoader - { - private readonly List _fontStreams = new List(); - private readonly List _enumerators = new List(); - private readonly DataStream _keyStream; - - /// - /// Initializes a new instance of the class. - /// - /// The factory. - /// - public ResourceFontLoader(DWrite.Factory factory, IEnumerable fontResources) - { - var factory1 = factory; - - var assetLoader = AvaloniaLocator.Current.GetService(); - - foreach (var font in fontResources) - { - var resourceStream = assetLoader.Open(font.Source); - - var dataStream = new DataStream((int)resourceStream.Length, true, true); - - resourceStream.CopyTo(dataStream); - - dataStream.Position = 0; - - _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); - - for (int i = 0; i < _fontStreams.Count; i++) - { - _keyStream.Write(i); - } - - _keyStream.Position = 0; - - // Register the - factory1.RegisterFontFileLoader(this); - factory1.RegisterFontCollectionLoader(this); - } - - - /// - /// Gets the key used to identify the FontCollection as well as storing index for fonts. - /// - /// The key. - public DataStream Key => _keyStream; - - /// - /// Creates a font file enumerator object that encapsulates a collection of font files. The font system calls back to this interface to create a font collection. - /// - /// Pointer to the object that was used to create the current font collection. - /// A font collection key that uniquely identifies the collection of font files within the scope of the font collection loader being used. The buffer allocated for this key must be at least the size, in bytes, specified by collectionKeySize. - /// - /// a reference to the newly created font file enumerator. - /// - /// HRESULT IDWriteFontCollectionLoader::CreateEnumeratorFromKey([None] IDWriteFactory* factory,[In, Buffer] const void* collectionKey,[None] int collectionKeySize,[Out] IDWriteFontFileEnumerator** fontFileEnumerator) - DWrite.FontFileEnumerator DWrite.FontCollectionLoader.CreateEnumeratorFromKey(DWrite.Factory factory, DataPointer collectionKey) - { - var enumerator = new ResourceFontFileEnumerator(factory, this, collectionKey); - - _enumerators.Add(enumerator); - - return enumerator; - } - - /// - /// Creates a font file stream object that encapsulates an open file resource. - /// - /// A reference to a font file reference key that uniquely identifies the font file resource within the scope of the font loader being used. The buffer allocated for this key must at least be the size, in bytes, specified by fontFileReferenceKeySize. - /// - /// a reference to the newly created object. - /// - /// - /// The resource is closed when the last reference to fontFileStream is released. - /// - /// HRESULT IDWriteFontFileLoader::CreateStreamFromKey([In, Buffer] const void* fontFileReferenceKey,[None] int fontFileReferenceKeySize,[Out] IDWriteFontFileStream** fontFileStream) - DWrite.FontFileStream DWrite.FontFileLoader.CreateStreamFromKey(DataPointer fontFileReferenceKey) - { - var index = SharpDX.Utilities.Read(fontFileReferenceKey.Pointer); - - return _fontStreams[index]; - } - } - - /// - /// This FontFileStream implem is reading data from a . - /// - public class ResourceFontFileStream : CallbackBase, DWrite.FontFileStream - { - private readonly DataStream _stream; - - /// - /// Initializes a new instance of the class. - /// - /// The stream. - public ResourceFontFileStream(DataStream stream) - { - _stream = stream; - } - - /// - /// Reads a fragment from a font file. - /// - /// When this method returns, contains an address of a reference to the start of the font file fragment. This parameter is passed uninitialized. - /// The offset of the fragment, in bytes, from the beginning of the font file. - /// The size of the file fragment, in bytes. - /// When this method returns, contains the address of - /// - /// Note that ReadFileFragment implementations must check whether the requested font file fragment is within the file bounds. Otherwise, an error should be returned from ReadFileFragment. {{DirectWrite}} may invoke methods on the same object from multiple threads simultaneously. Therefore, ReadFileFragment implementations that rely on internal mutable state must serialize access to such state across multiple threads. For example, an implementation that uses separate Seek and Read operations to read a file fragment must place the code block containing Seek and Read calls under a lock or a critical section. - /// - /// HRESULT IDWriteFontFileStream::ReadFileFragment([Out, Buffer] const void** fragmentStart,[None] __int64 fileOffset,[None] __int64 fragmentSize,[Out] void** fragmentContext) - void DWrite.FontFileStream.ReadFileFragment(out IntPtr fragmentStart, long fileOffset, long fragmentSize, out IntPtr fragmentContext) - { - lock (this) - { - fragmentContext = IntPtr.Zero; - - _stream.Position = fileOffset; - - fragmentStart = _stream.PositionPointer; - - } - } - - /// - /// Releases a fragment from a file. - /// - /// A reference to the client-defined context of a font fragment returned from {{ReadFileFragment}}. - /// void IDWriteFontFileStream::ReleaseFileFragment([None] void* fragmentContext) - void DWrite.FontFileStream.ReleaseFileFragment(IntPtr fragmentContext) - { - // Nothing to release. No context are used - } - - /// - /// Obtains the total size of a file. - /// - /// the total size of the file. - /// - /// Implementing GetFileSize() for asynchronously loaded font files may require downloading the complete file contents. Therefore, this method should be used only for operations that either require a complete font file to be loaded (for example, copying a font file) or that need to make decisions based on the value of the file size (for example, validation against a persisted file size). - /// - /// HRESULT IDWriteFontFileStream::GetFileSize([Out] __int64* fileSize) - long DWrite.FontFileStream.GetFileSize() - { - return _stream.Length; - } - - /// - /// Obtains the last modified time of the file. - /// - /// - /// the last modified time of the file in the format that represents the number of 100-nanosecond intervals since January 1, 1601 (UTC). - /// - /// - /// The "last modified time" is used by DirectWrite font selection algorithms to determine whether one font resource is more up to date than another one. - /// - /// HRESULT IDWriteFontFileStream::GetLastWriteTime([Out] __int64* lastWriteTime) - long DWrite.FontFileStream.GetLastWriteTime() - { - return 0; - } - } - - /// - /// Resource FontFileEnumerator. - /// - public class ResourceFontFileEnumerator : CallbackBase, DWrite.FontFileEnumerator - { - private DWrite.Factory _factory; - private DWrite.FontFileLoader _loader; - private DataStream keyStream; - private DWrite.FontFile _currentFontFile; - - /// - /// Initializes a new instance of the class. - /// - /// The factory. - /// The loader. - /// The key. - public ResourceFontFileEnumerator(DWrite.Factory factory, DWrite.FontFileLoader loader, DataPointer key) - { - _factory = factory; - - _loader = loader; - - keyStream = new DataStream(key.Pointer, key.Size, true, false); - } - - /// - /// Advances to the next font file in the collection. When it is first created, the enumerator is positioned before the first element of the collection and the first call to MoveNext advances to the first file. - /// - /// - /// the value TRUE if the enumerator advances to a file; otherwise, FALSE if the enumerator advances past the last file in the collection. - /// - /// HRESULT IDWriteFontFileEnumerator::MoveNext([Out] BOOL* hasCurrentFile) - bool DWrite.FontFileEnumerator.MoveNext() - { - bool moveNext = keyStream.RemainingLength != 0; - - if (!moveNext) return false; - - _currentFontFile?.Dispose(); - - _currentFontFile = new DWrite.FontFile(_factory, keyStream.PositionPointer, 4, _loader); - - keyStream.Position += 4; - - return true; - } - - /// - /// Gets a reference to the current font file. - /// - /// - /// a reference to the newly created object. - /// HRESULT IDWriteFontFileEnumerator::GetCurrentFontFile([Out] IDWriteFontFile** fontFile) - DWrite.FontFile DWrite.FontFileEnumerator.CurrentFontFile - { - get - { - ((IUnknown)_currentFontFile).AddReference(); - - return _currentFontFile; - } - } - } } From 0c7c69dbe7069a2b101c32fa234b3b748a1032e9 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Sat, 12 May 2018 23:46:54 +0200 Subject: [PATCH 19/36] First unit tests --- .../Media/Fonts/FontFamilyKey.cs | 4 +- .../Media/Fonts/FontFamilyLoader.cs | 2 +- .../SKTypefaceCollectionCache.cs | 2 +- .../Media/Direct2D1FontCollectionCache.cs | 2 +- .../Assets/MyFont.ttf | 1 + .../Avalonia.Visuals.UnitTests.csproj | 6 ++ .../Media/FontFamilyTests.cs | 75 +++++++++++++++++++ .../Media/Fonts/FamilyNameCollectionTests.cs | 25 +++++++ .../Media/Fonts/FontFamilyKeyTests.cs | 43 +++++++++++ .../Media/Fonts/FontFamilyLoaderTests.cs | 38 ++++++++++ 10 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf create mode 100644 tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs create mode 100644 tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs create mode 100644 tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs create mode 100644 tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index d0e3207c70..204d419be4 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -16,7 +16,9 @@ namespace Avalonia.Media.Fonts /// /// public FontFamilyKey(Uri source) - { + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (source.AbsolutePath.Contains(".ttf")) { var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs index d972c7571a..89d5e07e5c 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs @@ -21,7 +21,7 @@ namespace Avalonia.Media.Fonts s_defaultAssembly = new AssemblyDescriptor(Assembly.GetEntryAssembly()); } - public static IEnumerable GetFontResources(FontFamilyKey fontFamilyKey) + public static IEnumerable LoadFontResources(FontFamilyKey fontFamilyKey) { return fontFamilyKey.FileName != null ? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs index fddca39f3f..254f6cff1b 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs @@ -22,7 +22,7 @@ namespace Avalonia.Skia private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) { - var resources = FontFamilyLoader.GetFontResources(fontFamily.Key); + var resources = FontFamilyLoader.LoadFontResources(fontFamily.Key); var typeFaceCollection = new SKTypefaceCollection(); diff --git a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs index bbb438b204..881f27351a 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs @@ -24,7 +24,7 @@ namespace Avalonia.Direct2D1.Media private static SharpDX.DirectWrite.FontCollection CreateFontCollection(FontFamilyKey key) { - var resources = FontFamilyLoader.GetFontResources(key); + var resources = FontFamilyLoader.LoadFontResources(key); var fontLoader = new DWriteResourceFontLoader(s_factory, resources); diff --git a/tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf b/tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj index 2b559c9c56..0b2a7faef0 100644 --- a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj +++ b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj @@ -7,6 +7,12 @@ + + + + + + diff --git a/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs new file mode 100644 index 0000000000..66aa1ab583 --- /dev/null +++ b/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs @@ -0,0 +1,75 @@ +// 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.Linq; +using Avalonia.Media; +using Avalonia.Media.Fonts; +using Xunit; + +namespace Avalonia.Visuals.UnitTests.Media +{ + public class FontFamilyTests + { + [Fact] + public void Exception_Should_Be_Thrown_If_Name_Is_Null() + { + Assert.Throws(() => new FontFamily((string)null)); + } + + [Fact] + public void Exception_Should_Be_Thrown_If_Names_Is_Null() + { + Assert.Throws(() => new FontFamily((IEnumerable)null)); + } + + [Fact] + public void Parse_Parses_FontFamily_With_Name() + { + var fontFamily = FontFamily.Parse("Courier New"); + + Assert.Equal("Courier New", fontFamily.Name); + } + + [Fact] + public void Parse_Parses_FontFamily_With_Names() + { + var fontFamily = FontFamily.Parse("Courier New, Times New Roman"); + + Assert.Equal("Courier New", fontFamily.Name); + + Assert.Equal(2, fontFamily.FamilyNames.Count()); + + Assert.Equal("Times New Roman", fontFamily.FamilyNames.Last()); + } + + [Fact] + public void Parse_Parses_FontFamily_With_Resource_Folder() + { + var source = new Uri("resm:Avalonia.Visuals.UnitTests#MyFont"); + + var key = new FontFamilyKey(source); + + var fontFamily = FontFamily.Parse(source.OriginalString); + + Assert.Equal("MyFont", fontFamily.Name); + + Assert.Equal(key, fontFamily.Key); + } + + [Fact] + public void Parse_Parses_FontFamily_With_Resource_Filename() + { + var source = new Uri("resm:Avalonia.Visuals.UnitTests.MyFont.ttf#MyFont"); + + var key = new FontFamilyKey(source); + + var fontFamily = FontFamily.Parse(source.OriginalString); + + Assert.Equal("MyFont", fontFamily.Name); + + Assert.Equal(key, fontFamily.Key); + } + } +} diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs new file mode 100644 index 0000000000..fef86ac4fc --- /dev/null +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs @@ -0,0 +1,25 @@ +// 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.Linq; +using Avalonia.Media.Fonts; +using Xunit; + +namespace Avalonia.Visuals.UnitTests.Media.Fonts +{ + public class FamilyNameCollectionTests + { + [Fact] + public void Exception_Should_Be_Thrown_If_Names_Is_Null() + { + Assert.Throws(() => new FamilyNameCollection(null)); + } + + [Fact] + public void Exception_Should_Be_Thrown_If_Names_Is_Empty() + { + Assert.Throws(() => new FamilyNameCollection(Enumerable.Empty())); + } + } +} diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs new file mode 100644 index 0000000000..d119ed2d47 --- /dev/null +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs @@ -0,0 +1,43 @@ +// 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 Avalonia.Media; +using Avalonia.Media.Fonts; +using Xunit; + +namespace Avalonia.Visuals.UnitTests.Media.Fonts +{ + public class FontFamilyKeyTests + { + [Fact] + public void Exception_Should_Be_Thrown_If_Source_Is_Null() + { + Assert.Throws(() => new FontFamilyKey(null)); + } + + [Fact] + public void Should_Initialize_With_Location() + { + var source = new Uri("resm:Avalonia.Visuals.UnitTests#MyFont"); + + var fontFamilyKey = new FontFamilyKey(source); + + Assert.Equal(new Uri("resm:Avalonia.Visuals.UnitTests"), fontFamilyKey.Location); + + Assert.Null(fontFamilyKey.FileName); + } + + [Fact] + public void Should_Initialize_With_Location_And_Filename() + { + var source = new Uri("resm:Avalonia.Visuals.UnitTests.MyFont.ttf#MyFont"); + + var fontFamilyKey = new FontFamilyKey(source); + + Assert.Equal(new Uri("resm:Avalonia.Visuals.UnitTests"), fontFamilyKey.Location); + + Assert.Equal("MyFont.ttf", fontFamilyKey.FileName); + } + } +} diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs new file mode 100644 index 0000000000..10a841ba84 --- /dev/null +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs @@ -0,0 +1,38 @@ +// 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.Linq; +using Avalonia.Media.Fonts; +using Avalonia.UnitTests; +using Xunit; + +namespace Avalonia.Visuals.UnitTests.Media.Fonts +{ + public class FontFamilyLoaderTests + { + [Fact] + public void Should_Load_Single_FontResource() + { + const string resourcePath = "resm:Avalonia.Visuals.UnitTests.Assets.MyFont.ttf?assembly=Avalonia.Visuals.UnitTests#MyFont"; + + using (StartWithResources((resourcePath, "MyFont.ttf"))) + { + var source = new Uri(resourcePath, UriKind.RelativeOrAbsolute); + + var key = new FontFamilyKey(source); + + var resources = FontFamilyLoader.LoadFontResources(key); + + Assert.Single(resources); + } + } + + private static IDisposable StartWithResources(params (string, string)[] assets) + { + var assetLoader = new MockAssetLoader(assets); + var services = new TestServices(assetLoader: assetLoader, platform: new AppBuilder().RuntimePlatform); + return UnitTestApplication.Start(services); + } + } +} From 3220e3130856b2099ece4162495d612cae0dd514 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Wed, 16 May 2018 22:32:46 +0200 Subject: [PATCH 20/36] TextBlock.SetFontFamily fix --- src/Avalonia.Controls/TextBlock.cs | 5 ++--- src/Avalonia.Visuals/Media/FontFamily.cs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index d865d7e5fe..3d2e505a03 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/src/Avalonia.Controls/TextBlock.cs @@ -4,7 +4,6 @@ using System; using System.Reactive; using System.Reactive.Linq; -using Avalonia.Data; using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Metadata; @@ -31,7 +30,7 @@ namespace Avalonia.Controls public static readonly AttachedProperty FontFamilyProperty = AvaloniaProperty.RegisterAttached( nameof(FontFamily), - defaultValue: new FontFamily("Courier New"), + defaultValue: FontFamily.Default, inherits: true); /// @@ -278,7 +277,7 @@ namespace Avalonia.Controls /// The control. /// The property value to set. /// The font family. - public static void SetFontFamily(Control control, string value) + public static void SetFontFamily(Control control, FontFamily value) { control.SetValue(FontFamilyProperty, value); } diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 5660156a1e..6383a58ac6 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -10,7 +10,7 @@ namespace Avalonia.Media { public class FontFamily { - internal static FontFamily Default = new FontFamily("Courier New"); + public static FontFamily Default => new FontFamily("Courier New"); /// /// Initializes a new instance of the class. From 5a5be9e767d3545a628305679000930421da880c Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 18 May 2018 01:02:09 +0200 Subject: [PATCH 21/36] Requested changes --- src/Avalonia.Visuals/Media/FontFamily.cs | 14 ++++++++++++++ src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs | 11 ++++++----- src/Avalonia.Visuals/Media/Typeface.cs | 7 +++++++ src/Shared/PlatformSupport/AssetLoader.cs | 2 +- .../Avalonia.Direct2D1/Direct2D1Platform.cs | 2 +- .../Media/FontFamilyTests.cs | 8 ++++++++ 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 6383a58ac6..e8709138c8 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -79,9 +79,23 @@ namespace Avalonia.Media /// public override string ToString() { + if (Key != null) + { + return Key + "#" + Name; + } + return Name; } + /// + /// Implicit conversion of FontFamily to string + /// + /// + public static implicit operator string(FontFamily fontFamily) + { + return fontFamily.ToString(); + } + /// /// Parses a string. /// diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index 204d419be4..b248b5145d 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -88,12 +88,13 @@ namespace Avalonia.Media.Fonts /// public override string ToString() { - if (FileName != null) - { - return Location.AbsolutePath + "." + FileName; - } + if (FileName == null) return Location.PathAndQuery; + + var builder = new UriBuilder(Location); + + builder.Path += "." + FileName; - return Location.AbsolutePath; + return builder.ToString(); } } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Typeface.cs b/src/Avalonia.Visuals/Media/Typeface.cs index 6baec1a246..ead15fe0f3 100644 --- a/src/Avalonia.Visuals/Media/Typeface.cs +++ b/src/Avalonia.Visuals/Media/Typeface.cs @@ -7,6 +7,13 @@ namespace Avalonia.Media /// public class Typeface { + /// + /// Initializes a new instance of the class. + /// + /// The font family. + /// The font size, in DIPs. + /// The font style. + /// The font weight. public Typeface(FontFamily fontFamily, double fontSize = 12, FontStyle style = FontStyle.Normal, FontWeight weight = FontWeight.Normal) { diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index 64c6d60bfb..6fee855352 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -216,5 +216,5 @@ namespace Avalonia.Shared.PlatformSupport public Dictionary Resources { get; } public string Name { get; } } - } + } } diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 0c3b01bbf1..296edcb2d9 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -117,7 +117,7 @@ namespace Avalonia.Direct2D1 } public IFormattedTextImpl CreateFormattedText( - string text, + string text, Typeface typeface, TextAlignment textAlignment, TextWrapping wrapping, diff --git a/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs index 66aa1ab583..c88a57ec9d 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs @@ -24,6 +24,14 @@ namespace Avalonia.Visuals.UnitTests.Media Assert.Throws(() => new FontFamily((IEnumerable)null)); } + [Fact] + public void ShouldImplicitlyConvertToString() + { + var fontFamily = new FontFamily("Arial"); + + Assert.Equal("Arial", fontFamily); + } + [Fact] public void Parse_Parses_FontFamily_With_Name() { From a10a756366e5c4f3a079c3fecb6efb15a2b06136 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Sun, 20 May 2018 16:22:02 +0200 Subject: [PATCH 22/36] IAssetLoader changes Rename resource to asset --- .../Assets/Fonts/SourceSansPro-Bold.ttf | Bin 0 -> 290916 bytes .../Assets/Fonts/SourceSansPro-BoldItalic.ttf | Bin 0 -> 103200 bytes .../Assets/Fonts/SourceSansPro-Italic.ttf | Bin 0 -> 103828 bytes .../Assets/Fonts/SourceSansPro-Regular.ttf | Bin 0 -> 293516 bytes samples/ControlCatalog/ControlCatalog.csproj | 12 ++ samples/ControlCatalog/Pages/TextBoxPage.xaml | 8 +- src/Avalonia.Base/Platform/IAssetLoader.cs | 10 +- src/Avalonia.Visuals/Media/FontFamily.cs | 11 +- .../Media/Fonts/FamilyNameCollection.cs | 26 ++- .../Fonts/{FontResource.cs => FontAsset.cs} | 8 +- .../Media/Fonts/FontFamilyKey.cs | 10 +- .../Media/Fonts/FontFamilyLoader.cs | 157 +++--------------- .../AvaloniaXamlLoader.cs | 4 +- src/Shared/PlatformSupport/AssetLoader.cs | 17 +- .../SKTypefaceCollectionCache.cs | 8 +- .../Media/DWriteResourceFontLoader.cs | 12 +- .../Media/Direct2D1FontCollectionCache.cs | 4 +- .../Media/Fonts/FontFamilyLoaderTests.cs | 2 +- 18 files changed, 122 insertions(+), 167 deletions(-) create mode 100644 samples/ControlCatalog/Assets/Fonts/SourceSansPro-Bold.ttf create mode 100644 samples/ControlCatalog/Assets/Fonts/SourceSansPro-BoldItalic.ttf create mode 100644 samples/ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf create mode 100644 samples/ControlCatalog/Assets/Fonts/SourceSansPro-Regular.ttf rename src/Avalonia.Visuals/Media/Fonts/{FontResource.cs => FontAsset.cs} (73%) diff --git a/samples/ControlCatalog/Assets/Fonts/SourceSansPro-Bold.ttf b/samples/ControlCatalog/Assets/Fonts/SourceSansPro-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f6986468bd9f5a3291d29950d5e7e342dc72c6c1 GIT binary patch literal 290916 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
i4#A^(@vMq} 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 z%0D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 I7l5-L03n*E+yDRo literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Assets/Fonts/SourceSansPro-BoldItalic.ttf b/samples/ControlCatalog/Assets/Fonts/SourceSansPro-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5c00b64faf181fe160ceb281e687df7f4b207705 GIT binary patch literal 103200 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

K8aI2 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

+ /// Gets all assets at a specific location. + /// + /// The location of resources. + /// A tuple containing the absolute path to the resource and the owner assembly + IEnumerable<(string AbsolutePath, Assembly Assembly)> GetAssets(Uri location); } } diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index e8709138c8..cdd3161171 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -19,7 +19,8 @@ namespace Avalonia.Media /// name public FontFamily(string name) { - if (name == null) throw new ArgumentNullException(); + Contract.Requires(name != null); + FamilyNames = new FamilyNameCollection(new[] { name }); } @@ -30,14 +31,16 @@ namespace Avalonia.Media /// name public FontFamily(IEnumerable names) { - if (names == null) throw new ArgumentNullException(); + Contract.Requires(names != null); + FamilyNames = new FamilyNameCollection(names); } + /// /// /// Initializes a new instance of the class. /// - /// The name of the . + /// The name of the . /// The source of font resources. public FontFamily(string name, Uri source) : this(name) { @@ -64,7 +67,7 @@ namespace Avalonia.Media } /// - /// Gets the key for associated resources. + /// Gets the key for associated assets. /// /// /// The family familyNames. diff --git a/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs b/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs index 6296b947cc..839f2ce34b 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs @@ -13,13 +13,23 @@ namespace Avalonia.Media.Fonts { private readonly ReadOnlyCollection _familyNames; + /// + /// Initializes a new instance of the class. + /// + /// The family names. + /// familyNames public FamilyNameCollection(IEnumerable familyNames) { - if (familyNames == null) throw new ArgumentNullException(nameof(familyNames)); + Contract.Requires(familyNames != null); + var names = new List(familyNames); + if (names.Count == 0) throw new ArgumentException($"{nameof(familyNames)} must not be empty."); + _familyNames = new ReadOnlyCollection(names); + PrimaryFamilyName = _familyNames.First(); + HasFallbacks = _familyNames.Count > 1; } @@ -39,11 +49,25 @@ namespace Avalonia.Media.Fonts /// public bool HasFallbacks { get; } + /// + /// + /// Returns an enumerator that iterates through the collection. + /// + /// + /// An enumerator that can be used to iterate through the collection. + /// public IEnumerator GetEnumerator() { return _familyNames.GetEnumerator(); } + /// + /// + /// Returns an enumerator that iterates through a collection. + /// + /// + /// An object that can be used to iterate through the collection. + /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); diff --git a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs b/src/Avalonia.Visuals/Media/Fonts/FontAsset.cs similarity index 73% rename from src/Avalonia.Visuals/Media/Fonts/FontResource.cs rename to src/Avalonia.Visuals/Media/Fonts/FontAsset.cs index 84e2153b42..a1cff79371 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontResource.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontAsset.cs @@ -5,19 +5,19 @@ using System; namespace Avalonia.Media.Fonts { - internal class FontResource + internal class FontAsset { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The source. - public FontResource(Uri source) + public FontAsset(Uri source) { Source = source; } /// - /// Gets the source. + /// Gets the source of the asset. /// /// /// The source. diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index b248b5145d..852b39615a 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -33,15 +33,21 @@ namespace Avalonia.Media.Fonts } /// - /// Location of stored that belong to a + /// Location of stored that belong to a /// public Uri Location { get; } /// - /// Optional filename for that belong to a + /// Optional filename for that belong to a /// public string FileName { get; } + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// public override int GetHashCode() { unchecked diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs index 89d5e07e5c..ffe6c10acb 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs @@ -11,181 +11,68 @@ namespace Avalonia.Media.Fonts { internal static class FontFamilyLoader { - private static readonly Dictionary s_assemblyNameCache - = new Dictionary(); - - private static readonly AssemblyDescriptor s_defaultAssembly; + private static readonly IAssetLoader s_assetLoader; static FontFamilyLoader() { - s_defaultAssembly = new AssemblyDescriptor(Assembly.GetEntryAssembly()); + s_assetLoader = AvaloniaLocator.Current.GetService(); } - public static IEnumerable LoadFontResources(FontFamilyKey fontFamilyKey) + public static IEnumerable LoadFontAssets(FontFamilyKey fontFamilyKey) { return fontFamilyKey.FileName != null - ? GetFontResourcesByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) - : GetFontResourcesByLocation(fontFamilyKey.Location); + ? GetFontAssetsByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) + : GetFontAssetsByLocation(fontFamilyKey.Location); } /// - /// 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 /// /// /// - private static IEnumerable GetFontResourcesByLocation(Uri location) + private static IEnumerable GetFontAssetsByLocation(Uri location) { - var assembly = GetAssembly(location); - - if (assembly == null) return Enumerable.Empty(); + var availableAssets = s_assetLoader.GetAssets(location); 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))); } /// - /// 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. /// Filenames can target multible files with * wildcard. For example "FontFile*.ttf" /// /// /// /// - private static IEnumerable GetFontResourcesByFileName(Uri location, string fileName) + private static IEnumerable GetFontAssetsByFileName(Uri location, string fileName) { - var assembly = GetAssembly(location); - - if (assembly == null) return Enumerable.Empty(); + var availableResources = s_assetLoader.GetAssets(location); var compareTo = location.AbsolutePath + "." + fileName.Split('*').First(); - var matchingResources = assembly.Resources.Where(x => x.Contains(compareTo)); - - return matchingResources.Select(x => CreateResource(GetResourceUri(x, assembly.Name))); - } - - private static FontResource CreateResource(Uri source) - { - return new FontResource(source); - } - - /// - /// Returns a valid resource that follows the resm scheme - /// - /// - /// - /// - private static Uri GetResourceUri(string path, string assemblyName) - { - return new Uri("resm:" + path + "?assembly=" + assemblyName); - } - - /// - /// Extracts a from a given - /// - /// - /// - private static AssemblyDescriptor GetAssembly(Uri uri) - { - if (uri == null) return null; - - var parameters = ParseParameters(uri); + var matchingResources = availableResources.Where(x => x.AbsolutePath.Contains(compareTo)); - return parameters.TryGetValue("assembly", out var assemblyName) ? GetAssembly(assemblyName) : s_defaultAssembly; + return matchingResources.Select(x => CreateFontAsset(GetAssetUri(x.AbsolutePath, x.Assembly))); } - /// - /// Returns a that is identified by a given name. - /// - /// If name is null the default assembly is used. - /// - /// - /// - /// - private static AssemblyDescriptor GetAssembly(string name) + private static FontAsset CreateFontAsset(Uri source) { - if (name == null) - { - return s_defaultAssembly; - } - - if (!s_assemblyNameCache.TryGetValue(name, out var rv)) - { - var loadedAssemblies = AvaloniaLocator.Current.GetService().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; + return new FontAsset(source); } /// - /// Parses the parameters. + /// Returns a for a font asset that follows the resm scheme /// - /// The URI. + /// + /// /// - private static Dictionary ParseParameters(Uri uri) + private static Uri GetAssetUri(string absolutePath, Assembly assembly) { - 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; - } - - /// - /// Gets the name. - /// - /// - /// The name. - /// - public string Name { get; } - - /// - /// Gets the assembly. - /// - /// - /// The assembly. - /// - public Assembly Assembly { get; } - - /// - /// Gets the resources. - /// - /// - /// The resources. - /// - public List Resources { get; } + return new Uri("resm:" + absolutePath + "?assembly=" + assembly.GetName().Name, UriKind.RelativeOrAbsolute); } } } \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs index 79523dd498..a6321f1452 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs @@ -126,11 +126,11 @@ namespace Avalonia.Markup.Xaml } var asset = assetLocator.OpenAndGetAssembly(uri, baseUri); - using (var stream = asset.Item1) + using (var stream = asset.Stream) { try { - return Load(stream, asset.Item2, rootInstance, uri); + return Load(stream, asset.Assembly, rootInstance, uri); } catch (Exception e) { diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index 6fee855352..2e331daeda 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -67,8 +67,8 @@ namespace Avalonia.Shared.PlatformSupport /// /// The resource was not found. /// - public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Item1; - + public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Stream; + /// /// Opens the resource with the requested URI and returns the resource string and the /// assembly containing the resource. @@ -83,7 +83,7 @@ namespace Avalonia.Shared.PlatformSupport /// /// The resource was not found. /// - public Tuple OpenAndGetAssembly(Uri uri, Uri baseUri = null) + public (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { var asset = GetAsset(uri, baseUri); @@ -92,9 +92,18 @@ namespace Avalonia.Shared.PlatformSupport 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) { if (!uri.IsAbsoluteUri || uri.Scheme == "resm") diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs index 254f6cff1b..13cce3f3da 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs @@ -22,17 +22,17 @@ namespace Avalonia.Skia private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) { - var resources = FontFamilyLoader.LoadFontResources(fontFamily.Key); + var assets = FontFamilyLoader.LoadFontAssets(fontFamily.Key); var typeFaceCollection = new SKTypefaceCollection(); var assetLoader = AvaloniaLocator.Current.GetService(); - 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); } diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs index da2ec8c0a6..ba8e48a02c 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs @@ -16,20 +16,20 @@ namespace Avalonia.Direct2D1.Media /// Initializes a new instance of the class. /// /// The factory. - /// - public DWriteResourceFontLoader(Factory factory, IEnumerable fontResources) + /// + public DWriteResourceFontLoader(Factory factory, IEnumerable fontAssets) { var factory1 = factory; var assetLoader = AvaloniaLocator.Current.GetService(); - 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; diff --git a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs index 881f27351a..4e80cd3ec1 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs @@ -24,9 +24,9 @@ namespace Avalonia.Direct2D1.Media 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); } diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs index 10a841ba84..ef7171d651 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs @@ -22,7 +22,7 @@ namespace Avalonia.Visuals.UnitTests.Media.Fonts var key = new FontFamilyKey(source); - var resources = FontFamilyLoader.LoadFontResources(key); + var resources = FontFamilyLoader.LoadFontAssets(key); Assert.Single(resources); } From 33ea1925c729eff9519399b3f3bf1575a2bef454 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Sun, 20 May 2018 20:36:14 +0200 Subject: [PATCH 23/36] Fixed unit tests --- tests/Avalonia.UnitTests/MockAssetLoader.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs index d6b70aee16..ca1135acbd 100644 --- a/tests/Avalonia.UnitTests/MockAssetLoader.cs +++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; -using System.Threading.Tasks; using Avalonia.Platform; namespace Avalonia.UnitTests @@ -28,9 +27,14 @@ namespace Avalonia.UnitTests return new MemoryStream(Encoding.UTF8.GetBytes(_assets[uri])); } - public Tuple OpenAndGetAssembly(Uri uri, Uri baseUri = null) + public (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { - return Tuple.Create(Open(uri, baseUri), (Assembly)null); + return (Open(uri, baseUri), (Assembly)null); + } + + public IEnumerable<(string AbsolutePath, Assembly Assembly)> GetAssets(Uri location) + { + return _assets.Keys.Select(x => (x.AbsolutePath, Assembly.GetEntryAssembly())); } public void SetDefaultAssembly(Assembly asm) From 2c8953de977829060db11eda7dc1bf1ea886b1b2 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Mon, 21 May 2018 22:54:24 +0200 Subject: [PATCH 24/36] Requested changes --- src/Avalonia.Base/Platform/IAssetLoader.cs | 6 +- src/Avalonia.Visuals/Media/FontFamily.cs | 116 ++++++++++-------- .../Media/Fonts/FamilyNameCollection.cs | 69 +++++++++-- src/Avalonia.Visuals/Media/Fonts/FontAsset.cs | 27 ---- .../Media/Fonts/FontFamilyKey.cs | 12 +- .../Media/Fonts/FontFamilyLoader.cs | 23 ++-- src/Avalonia.Visuals/Media/IFontFamily.cs | 35 ++++++ src/Avalonia.Visuals/Media/Typeface.cs | 14 ++- .../Properties/AssemblyInfo.cs | 2 - .../AvaloniaXamlLoader.cs | 4 +- src/Shared/PlatformSupport/AssetLoader.cs | 6 +- .../Avalonia.Skia/SKTypefaceCollection.cs | 68 +++++----- .../SKTypefaceCollectionCache.cs | 20 ++- .../Media/DWriteResourceFontFileStream.cs | 1 - .../Media/DWriteResourceFontLoader.cs | 8 +- .../Media/Direct2D1FontCollectionCache.cs | 34 +++-- .../Media/FormattedTextImpl.cs | 8 +- tests/Avalonia.UnitTests/MockAssetLoader.cs | 4 +- .../Media/FontFamilyTests.cs | 14 ++- .../Media/Fonts/FamilyNameCollectionTests.cs | 8 ++ 20 files changed, 300 insertions(+), 179 deletions(-) delete mode 100644 src/Avalonia.Visuals/Media/Fonts/FontAsset.cs create mode 100644 src/Avalonia.Visuals/Media/IFontFamily.cs diff --git a/src/Avalonia.Base/Platform/IAssetLoader.cs b/src/Avalonia.Base/Platform/IAssetLoader.cs index 26d79d5567..767ce4ad8e 100644 --- a/src/Avalonia.Base/Platform/IAssetLoader.cs +++ b/src/Avalonia.Base/Platform/IAssetLoader.cs @@ -59,13 +59,13 @@ namespace Avalonia.Platform /// /// The resource was not found. /// - (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null); + (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null); /// /// Gets all assets at a specific location. /// - /// The location of resources. + /// The location of assets. /// A tuple containing the absolute path to the resource and the owner assembly - IEnumerable<(string AbsolutePath, Assembly Assembly)> GetAssets(Uri location); + IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location); } } diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index cdd3161171..d7b7edd96f 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -8,10 +8,8 @@ using Avalonia.Media.Fonts; namespace Avalonia.Media { - public class FontFamily + public class FontFamily : IFontFamily { - public static FontFamily Default => new FontFamily("Courier New"); - /// /// Initializes a new instance of the class. /// @@ -47,56 +45,25 @@ namespace Avalonia.Media Key = new FontFamilyKey(source); } - /// - /// Gets the name of the font family. - /// - /// - /// The name of the font family. - /// + public static FontFamily Default => new FontFamily("Courier New"); + public string Name => FamilyNames.PrimaryFamilyName; + + FamilyNameCollection IFontFamily.FamilyNames => FamilyNames; - /// - /// Gets the family names. - /// - /// - /// The family familyNames. - /// - internal FamilyNameCollection FamilyNames - { - get; - } + FontFamilyKey IFontFamily.Key => Key; - /// - /// Gets the key for associated assets. - /// - /// - /// The family familyNames. - /// - internal FontFamilyKey Key { get; } + internal FamilyNameCollection FamilyNames { get; } - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - if (Key != null) - { - return Key + "#" + Name; - } - - return Name; - } + internal FontFamilyKey Key { get; } /// - /// Implicit conversion of FontFamily to string + /// Implicit conversion of string to FontFamily /// /// - public static implicit operator string(FontFamily fontFamily) + public static implicit operator FontFamily(string fontFamily) { - return fontFamily.ToString(); + return new FontFamily(fontFamily); } /// @@ -116,21 +83,74 @@ namespace Avalonia.Media switch (segments.Length) { case 1: - { - var names = segments[0].Split(',') - .Select(x => x.Trim()) - .Where(x => !string.IsNullOrWhiteSpace(x)); + { + var names = segments[0].Split(',') + .Select(x => x.Trim()) + .Where(x => !string.IsNullOrWhiteSpace(x)); return new FontFamily(names); } + case 2: { return new FontFamily(segments[1], new Uri(segments[0], UriKind.RelativeOrAbsolute)); } + default: { throw new ArgumentException("Specified family is not supported."); } } } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + if (Key != null) + { + return Key + "#" + FamilyNames; + } + + return FamilyNames.ToString(); + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + unchecked + { + var hash = (int)2186146271; + + hash = (hash * 15768619) ^ FamilyNames.GetHashCode(); + + if (Key != null) + { + hash = (hash * 15768619) ^ Key.GetHashCode(); + } + + return hash; + } + } + + public override bool Equals(object obj) + { + if (!(obj is FontFamily other)) return false; + + if (Key != null) + { + return other.FamilyNames.Equals(FamilyNames) && other.Key.Equals(Key); + } + + return other.FamilyNames.Equals(FamilyNames); + } } } diff --git a/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs b/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs index 839f2ce34b..50511d2fb7 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs @@ -9,10 +9,10 @@ using System.Linq; namespace Avalonia.Media.Fonts { - internal class FamilyNameCollection : IEnumerable - { - private readonly ReadOnlyCollection _familyNames; + using System.Text; + public class FamilyNameCollection : IEnumerable + { /// /// Initializes a new instance of the class. /// @@ -26,11 +26,11 @@ namespace Avalonia.Media.Fonts if (names.Count == 0) throw new ArgumentException($"{nameof(familyNames)} must not be empty."); - _familyNames = new ReadOnlyCollection(names); + Names = new ReadOnlyCollection(names); - PrimaryFamilyName = _familyNames.First(); + PrimaryFamilyName = Names.First(); - HasFallbacks = _familyNames.Count > 1; + HasFallbacks = Names.Count > 1; } /// @@ -49,6 +49,14 @@ namespace Avalonia.Media.Fonts /// public bool HasFallbacks { get; } + /// + /// Gets the internal collection of names. + /// + /// + /// The names. + /// + internal ReadOnlyCollection Names { get; } + /// /// /// Returns an enumerator that iterates through the collection. @@ -58,7 +66,7 @@ namespace Avalonia.Media.Fonts /// public IEnumerator GetEnumerator() { - return _familyNames.GetEnumerator(); + return Names.GetEnumerator(); } /// @@ -72,5 +80,52 @@ namespace Avalonia.Media.Fonts { return GetEnumerator(); } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + var builder = new StringBuilder(); + + for (var index = 0; index < Names.Count; index++) + { + builder.Append(Names[index]); + + if (index == Names.Count - 1) break; + + builder.Append(", "); + } + + return builder.ToString(); + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + return ToString().GetHashCode(); + } + + /// + /// Determines whether the specified , is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + if (!(obj is FamilyNameCollection other)) return false; + + return other.ToString().Equals(ToString()); + } } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontAsset.cs b/src/Avalonia.Visuals/Media/Fonts/FontAsset.cs deleted file mode 100644 index a1cff79371..0000000000 --- a/src/Avalonia.Visuals/Media/Fonts/FontAsset.cs +++ /dev/null @@ -1,27 +0,0 @@ -// 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; - -namespace Avalonia.Media.Fonts -{ - internal class FontAsset - { - /// - /// Initializes a new instance of the class. - /// - /// The source. - public FontAsset(Uri source) - { - Source = source; - } - - /// - /// Gets the source of the asset. - /// - /// - /// The source. - /// - public Uri Source { get; } - } -} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs index 852b39615a..c2005c9acb 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyKey.cs @@ -7,9 +7,9 @@ using System.Linq; namespace Avalonia.Media.Fonts { /// - /// Represents an idetifier for a + /// Represents an identifier for a /// - internal class FontFamilyKey + public class FontFamilyKey { /// /// Creates a new instance of and extracts and from given @@ -21,10 +21,10 @@ namespace Avalonia.Media.Fonts if (source.AbsolutePath.Contains(".ttf")) { - var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", ""); + var filePathWithoutExtension = source.AbsolutePath.Replace(".ttf", string.Empty); var fileNameWithoutExtension = filePathWithoutExtension.Split('.').Last(); FileName = fileNameWithoutExtension + ".ttf"; - Location = new Uri(source.OriginalString.Replace("." + FileName, ""), UriKind.RelativeOrAbsolute); + Location = new Uri(source.OriginalString.Replace("." + FileName, string.Empty), UriKind.RelativeOrAbsolute); } else { @@ -33,12 +33,12 @@ namespace Avalonia.Media.Fonts } /// - /// Location of stored that belong to a + /// Location of stored font asset that belongs to a /// public Uri Location { get; } /// - /// Optional filename for that belong to a + /// Optional filename for a font asset that belongs to a /// public string FileName { get; } diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs index ffe6c10acb..803d15d49f 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs @@ -9,7 +9,7 @@ using Avalonia.Platform; namespace Avalonia.Media.Fonts { - internal static class FontFamilyLoader + public static class FontFamilyLoader { private static readonly IAssetLoader s_assetLoader; @@ -18,7 +18,7 @@ namespace Avalonia.Media.Fonts s_assetLoader = AvaloniaLocator.Current.GetService(); } - public static IEnumerable LoadFontAssets(FontFamilyKey fontFamilyKey) + public static IEnumerable LoadFontAssets(FontFamilyKey fontFamilyKey) { return fontFamilyKey.FileName != null ? GetFontAssetsByFileName(fontFamilyKey.Location, fontFamilyKey.FileName) @@ -30,38 +30,33 @@ namespace Avalonia.Media.Fonts /// /// /// - private static IEnumerable GetFontAssetsByLocation(Uri location) + private static IEnumerable GetFontAssetsByLocation(Uri location) { var availableAssets = s_assetLoader.GetAssets(location); var locationPath = location.AbsolutePath; - var mathchingAssets = availableAssets.Where(x => x.AbsolutePath.Contains(locationPath) && x.AbsolutePath.EndsWith(".ttf")); + var matchingAssets = availableAssets.Where(x => x.absolutePath.Contains(locationPath) && x.absolutePath.EndsWith(".ttf")); - return mathchingAssets.Select(x => CreateFontAsset(GetAssetUri(x.AbsolutePath, x.Assembly))); + return matchingAssets.Select(x => GetAssetUri(x.absolutePath, x.assembly)); } /// /// Searches for font assets at a given location and only accepts assets that fit to a given filename expression. - /// Filenames can target multible files with * wildcard. For example "FontFile*.ttf" + /// File names can target multiple files with * wildcard. For example "FontFile*.ttf" /// /// /// /// - private static IEnumerable GetFontAssetsByFileName(Uri location, string fileName) + private static IEnumerable GetFontAssetsByFileName(Uri location, string fileName) { var availableResources = s_assetLoader.GetAssets(location); var compareTo = location.AbsolutePath + "." + fileName.Split('*').First(); - var matchingResources = availableResources.Where(x => x.AbsolutePath.Contains(compareTo)); + var matchingResources = availableResources.Where(x => x.absolutePath.Contains(compareTo)); - return matchingResources.Select(x => CreateFontAsset(GetAssetUri(x.AbsolutePath, x.Assembly))); - } - - private static FontAsset CreateFontAsset(Uri source) - { - return new FontAsset(source); + return matchingResources.Select(x => GetAssetUri(x.absolutePath, x.assembly)); } /// diff --git a/src/Avalonia.Visuals/Media/IFontFamily.cs b/src/Avalonia.Visuals/Media/IFontFamily.cs new file mode 100644 index 0000000000..b6a5201bf5 --- /dev/null +++ b/src/Avalonia.Visuals/Media/IFontFamily.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Avalonia.Media +{ + using Avalonia.Media.Fonts; + + public interface IFontFamily + { + /// + /// Gets the name of the font family. + /// + /// + /// The name of the font family. + /// + string Name { get; } + + /// + /// Gets the family names. + /// + /// + /// The family familyNames. + /// + FamilyNameCollection FamilyNames { get; } + + /// + /// Gets the key for associated assets. + /// + /// + /// The family familyNames. + /// + FontFamilyKey Key { get; } + } +} diff --git a/src/Avalonia.Visuals/Media/Typeface.cs b/src/Avalonia.Visuals/Media/Typeface.cs index ead15fe0f3..1c619f5f5c 100644 --- a/src/Avalonia.Visuals/Media/Typeface.cs +++ b/src/Avalonia.Visuals/Media/Typeface.cs @@ -14,8 +14,11 @@ namespace Avalonia.Media /// The font size, in DIPs. /// The font style. /// The font weight. - public Typeface(FontFamily fontFamily, double fontSize = 12, FontStyle style = FontStyle.Normal, - FontWeight weight = FontWeight.Normal) + public Typeface( + IFontFamily fontFamily, + double fontSize = 12, + FontStyle style = FontStyle.Normal, + FontWeight weight = FontWeight.Normal) { if (fontSize <= 0) { @@ -44,12 +47,15 @@ namespace Avalonia.Media string fontFamilyName, double fontSize = 12, FontStyle style = FontStyle.Normal, - FontWeight weight = FontWeight.Normal) : this(new FontFamily(fontFamilyName), fontSize, style, weight) { } + FontWeight weight = FontWeight.Normal) + : this(new FontFamily(fontFamilyName), fontSize, style, weight) + { + } /// /// Gets the font family. /// - public FontFamily FontFamily { get; } + public IFontFamily FontFamily { get; } /// /// Gets the size of the font in DIPs. diff --git a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs index a923407ca5..05c3d7e62a 100644 --- a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs @@ -10,7 +10,5 @@ using Avalonia.Metadata; [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")] -[assembly: InternalsVisibleTo("Avalonia.Direct2D1")] [assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests")] -[assembly: InternalsVisibleTo("Avalonia.Skia")] [assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests")] \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs index a6321f1452..f3fac3faf7 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs @@ -126,11 +126,11 @@ namespace Avalonia.Markup.Xaml } var asset = assetLocator.OpenAndGetAssembly(uri, baseUri); - using (var stream = asset.Stream) + using (var stream = asset.stream) { try { - return Load(stream, asset.Assembly, rootInstance, uri); + return Load(stream, asset.assembly, rootInstance, uri); } catch (Exception e) { diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index 2e331daeda..e869cad588 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -67,7 +67,7 @@ namespace Avalonia.Shared.PlatformSupport /// /// The resource was not found. /// - public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Stream; + public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).stream; /// /// Opens the resource with the requested URI and returns the resource string and the @@ -83,7 +83,7 @@ namespace Avalonia.Shared.PlatformSupport /// /// The resource was not found. /// - public (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) + public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { var asset = GetAsset(uri, baseUri); @@ -95,7 +95,7 @@ namespace Avalonia.Shared.PlatformSupport return (asset.GetStream(), asset.Assembly); } - public IEnumerable<(string AbsolutePath, Assembly Assembly)> GetAssets(Uri location) + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) { var assembly = GetAssembly(location); diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs index 00e5cf62b3..261e6667c3 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs @@ -6,7 +6,39 @@ namespace Avalonia.Skia { internal class SKTypefaceCollection { - struct FontKey + + + private readonly ConcurrentDictionary _cachedTypefaces = + new ConcurrentDictionary(); + + public void AddTypeFace(SKTypeface typeface) + { + var key = new FontKey(typeface.FamilyName, (SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant); + + _cachedTypefaces.TryAdd(key, typeface); + } + + public SKTypeface GetTypeFace(Typeface typeface) + { + SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; + + switch (typeface.Style) + { + case FontStyle.Italic: + skStyle = SKFontStyleSlant.Italic; + break; + + case FontStyle.Oblique: + skStyle = SKFontStyleSlant.Oblique; + break; + } + + var key = new FontKey(typeface.FontFamily.Name, (SKFontStyleWeight)typeface.Weight, skStyle); + + return _cachedTypefaces.TryGetValue(key, out var skTypeface) ? skTypeface : TypefaceCache.Default; + } + + private struct FontKey { public readonly string Name; public readonly SKFontStyleSlant Slant; @@ -34,43 +66,11 @@ namespace Avalonia.Skia return other is FontKey ? Equals((FontKey)other) : false; } - public bool Equals(FontKey other) + private bool Equals(FontKey other) { return Name == other.Name && Slant == other.Slant && Weight == other.Weight; } - - // Equals and GetHashCode ommitted - } - - private readonly ConcurrentDictionary _cachedTypefaces = - new ConcurrentDictionary(); - - public void AddTypeFace(SKTypeface typeface) - { - var key = new FontKey(typeface.FamilyName, (SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant); - - _cachedTypefaces.TryAdd(key, typeface); - } - - public SKTypeface GetTypeFace(Typeface typeface) - { - SKFontStyleSlant skStyle = SKFontStyleSlant.Upright; - - switch (typeface.Style) - { - case FontStyle.Italic: - skStyle = SKFontStyleSlant.Italic; - break; - - case FontStyle.Oblique: - skStyle = SKFontStyleSlant.Oblique; - break; - } - - var key = new FontKey(typeface.FontFamily.Name, (SKFontStyleWeight)typeface.Weight, skStyle); - - return _cachedTypefaces.TryGetValue(key, out var skTypeface) ? skTypeface : TypefaceCache.Default; } } } \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs index 13cce3f3da..f8ee62f1f2 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs @@ -15,22 +15,32 @@ namespace Avalonia.Skia s_cachedCollections = new ConcurrentDictionary(); } - public static SKTypefaceCollection GetOrAddTypefaceCollection(FontFamily fontFamily) + /// + /// Gets the or add typeface collection. + /// + /// The font family. + /// + public static SKTypefaceCollection GetOrAddTypefaceCollection(IFontFamily fontFamily) { return s_cachedCollections.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(fontFamily)); } - private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) + /// + /// Creates the custom font collection. + /// + /// The font family. + /// + private static SKTypefaceCollection CreateCustomFontCollection(IFontFamily fontFamily) { - var assets = FontFamilyLoader.LoadFontAssets(fontFamily.Key); + var fontAssets = FontFamilyLoader.LoadFontAssets(fontFamily.Key); var typeFaceCollection = new SKTypefaceCollection(); var assetLoader = AvaloniaLocator.Current.GetService(); - foreach (var fontAsset in assets) + foreach (var asset in fontAssets) { - var assetStream = assetLoader.Open(fontAsset.Source); + var assetStream = assetLoader.Open(asset); var typeface = SKTypeface.FromStream(assetStream); diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs index 37f283c162..1b1cb85495 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs @@ -40,7 +40,6 @@ namespace Avalonia.Direct2D1.Media _stream.Position = fileOffset; fragmentStart = _stream.PositionPointer; - } } diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs index ba8e48a02c..065da8d3e8 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontLoader.cs @@ -6,6 +6,8 @@ using SharpDX.DirectWrite; namespace Avalonia.Direct2D1.Media { + using System; + internal class DWriteResourceFontLoader : CallbackBase, FontCollectionLoader, FontFileLoader { private readonly List _fontStreams = new List(); @@ -17,15 +19,15 @@ namespace Avalonia.Direct2D1.Media /// /// The factory. /// - public DWriteResourceFontLoader(Factory factory, IEnumerable fontAssets) + public DWriteResourceFontLoader(Factory factory, IEnumerable fontAssets) { var factory1 = factory; var assetLoader = AvaloniaLocator.Current.GetService(); - foreach (var font in fontAssets) + foreach (var asset in fontAssets) { - var assetStream = assetLoader.Open(font.Source); + var assetStream = assetLoader.Open(asset); var dataStream = new DataStream((int)assetStream.Length, true, true); diff --git a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs index 4e80cd3ec1..0c69d9932e 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs @@ -13,31 +13,24 @@ namespace Avalonia.Direct2D1.Media static Direct2D1FontCollectionCache() { s_cachedCollections = new ConcurrentDictionary(); + s_factory = AvaloniaLocator.Current.GetService(); + s_installedFontCollection = s_factory.GetSystemFontCollection(false); } - public static SharpDX.DirectWrite.FontCollection GetOrAddFontCollection(FontFamily fontFamily) + public static SharpDX.DirectWrite.FontCollection GetOrAddFontCollection(IFontFamily fontFamily) { return fontFamily.Key == null ? s_installedFontCollection : s_cachedCollections.GetOrAdd(fontFamily.Key, CreateFontCollection); } - private static SharpDX.DirectWrite.FontCollection CreateFontCollection(FontFamilyKey key) - { - var assets = FontFamilyLoader.LoadFontAssets(key); - - var fontLoader = new DWriteResourceFontLoader(s_factory, assets); - - return new SharpDX.DirectWrite.FontCollection(s_factory, fontLoader, fontLoader.Key); - } - public static SharpDX.DirectWrite.TextFormat GetTextFormat(Typeface typeface) { var fontFamily = typeface.FontFamily; var fontCollection = GetOrAddFontCollection(fontFamily); var fontFamilyName = FontFamily.Default.Name; - //Should this be cached? + // Should this be cached? foreach (var familyName in fontFamily.FamilyNames) { if (!fontCollection.FindFamilyName(familyName, out _)) continue; @@ -45,8 +38,23 @@ namespace Avalonia.Direct2D1.Media break; } - return new SharpDX.DirectWrite.TextFormat(s_factory, fontFamilyName, fontCollection, (SharpDX.DirectWrite.FontWeight)typeface.Weight, - (SharpDX.DirectWrite.FontStyle)typeface.Style, SharpDX.DirectWrite.FontStretch.Normal, (float)typeface.FontSize); + return new SharpDX.DirectWrite.TextFormat( + s_factory, + fontFamilyName, + fontCollection, + (SharpDX.DirectWrite.FontWeight)typeface.Weight, + (SharpDX.DirectWrite.FontStyle)typeface.Style, + SharpDX.DirectWrite.FontStretch.Normal, + (float)typeface.FontSize); + } + + private static SharpDX.DirectWrite.FontCollection CreateFontCollection(FontFamilyKey key) + { + var assets = FontFamilyLoader.LoadFontAssets(key); + + var fontLoader = new DWriteResourceFontLoader(s_factory, assets); + + return new SharpDX.DirectWrite.FontCollection(s_factory, fontLoader, fontLoader.Key); } } } \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 61ed73d414..0f09a1827b 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -28,8 +28,12 @@ namespace Avalonia.Direct2D1.Media textFormat.WordWrapping = wrapping == TextWrapping.Wrap ? DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap; - TextLayout = new DWrite.TextLayout(factory, Text ?? string.Empty, textFormat, (float)constraint.Width, - (float)constraint.Height) + TextLayout = new DWrite.TextLayout( + factory, + Text ?? string.Empty, + textFormat, + (float)constraint.Width, + (float)constraint.Height) { TextAlignment = textAlignment.ToDirect2D() }; diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs index ca1135acbd..cebd88b6a0 100644 --- a/tests/Avalonia.UnitTests/MockAssetLoader.cs +++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs @@ -27,12 +27,12 @@ namespace Avalonia.UnitTests return new MemoryStream(Encoding.UTF8.GetBytes(_assets[uri])); } - public (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) + public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { return (Open(uri, baseUri), (Assembly)null); } - public IEnumerable<(string AbsolutePath, Assembly Assembly)> GetAssets(Uri location) + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) { return _assets.Keys.Select(x => (x.AbsolutePath, Assembly.GetEntryAssembly())); } diff --git a/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs index c88a57ec9d..4c7a89cbda 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/FontFamilyTests.cs @@ -25,11 +25,19 @@ namespace Avalonia.Visuals.UnitTests.Media } [Fact] - public void ShouldImplicitlyConvertToString() + public void Should_Implicitly_Convert_String_To_FontFamily() { - var fontFamily = new FontFamily("Arial"); + FontFamily fontFamily = "Arial"; - Assert.Equal("Arial", fontFamily); + Assert.Equal(new FontFamily("Arial"), fontFamily); + } + + [Fact] + public void Should_Be_Equal() + { + var fontFamily = new FontFamily("Arial"); + + Assert.Equal(new FontFamily("Arial"), fontFamily); } [Fact] diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs index fef86ac4fc..14daf5bd8b 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FamilyNameCollectionTests.cs @@ -21,5 +21,13 @@ namespace Avalonia.Visuals.UnitTests.Media.Fonts { Assert.Throws(() => new FamilyNameCollection(Enumerable.Empty())); } + + [Fact] + public void Should_Be_Equal() + { + var familyNames = new FamilyNameCollection(new[] { "Arial", "Times New Roman" }); + + Assert.Equal(new FamilyNameCollection(new[] { "Arial", "Times New Roman" }), familyNames); + } } } From b4848b20e3b2f77bb82a4a87bb834975ebc85efe Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Mon, 21 May 2018 22:56:49 +0200 Subject: [PATCH 25/36] Spacing fix --- src/Shared/PlatformSupport/AssetLoader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index e869cad588..d4f0ba6d17 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -103,7 +103,6 @@ namespace Avalonia.Shared.PlatformSupport Enumerable.Empty<(string AbsolutePath, Assembly Assembly)>(); } - private IAssetDescriptor GetAsset(Uri uri, Uri baseUri) { if (!uri.IsAbsoluteUri || uri.Scheme == "resm") From 3bec8036a7cb1eb85325da78d5be8404cea6a252 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Tue, 22 May 2018 22:45:53 +0200 Subject: [PATCH 26/36] Initial --- src/Avalonia.Base/Platform/IAssetLoader.cs | 24 ++++--- src/Shared/PlatformSupport/AssetLoader.cs | 70 ++++++++++++++------- tests/Avalonia.UnitTests/MockAssetLoader.cs | 13 ++-- 3 files changed, 71 insertions(+), 36 deletions(-) diff --git a/src/Avalonia.Base/Platform/IAssetLoader.cs b/src/Avalonia.Base/Platform/IAssetLoader.cs index ba30af60bf..3b459818dd 100644 --- a/src/Avalonia.Base/Platform/IAssetLoader.cs +++ b/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. using System; +using System.Collections.Generic; using System.IO; using System.Reflection; @@ -18,8 +19,8 @@ namespace Avalonia.Platform /// AssetLoader needs a refactor cause right now it lives in 3+ platforms which /// can all be loaded on Windows. /// - /// - void SetDefaultAssembly(Assembly asm); + /// + void SetDefaultAssembly(Assembly assembly); /// /// Checks if an asset with the specified URI exists. @@ -32,32 +33,39 @@ namespace Avalonia.Platform bool Exists(Uri uri, Uri baseUri = null); /// - /// Opens the resource with the requested URI. + /// Opens the asset with the requested URI. /// /// The URI. /// /// A base URI to use if is relative. /// - /// A stream containing the resource contents. + /// A stream containing the asset contents. /// /// The resource was not found. /// Stream Open(Uri uri, Uri baseUri = null); /// - /// Opens the resource with the requested URI and returns the resource string and the - /// assembly containing the resource. + /// Opens the asset with the requested URI and returns the asset stream and the + /// assembly containing the asset. /// /// The URI. /// /// A base URI to use if is relative. /// /// - /// The stream containing the resource contents together with the assembly. + /// The stream containing the asset contents together with the assembly. /// /// /// The resource was not found. /// - Tuple OpenAndGetAssembly(Uri uri, Uri baseUri = null); + (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null); + + /// + /// Gets all assets at a specific location. + /// + /// The location of assets. + /// A tuple containing the absolute path to the resource and the owner assembly + IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location); } } diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index fa11edb57b..b835170036 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -10,6 +10,7 @@ using Avalonia.Platform; namespace Avalonia.Shared.PlatformSupport { + /// /// /// Loads assets compiled into the application binary. /// @@ -34,21 +35,26 @@ namespace Avalonia.Shared.PlatformSupport _defaultAssembly = new AssemblyDescriptor(assembly); } + /// /// - /// Sets the default assembly from which to load assets for which no assembly is specified. + /// We need a way to override the default assembly selected by the host platform + /// because right now it is selecting the wrong one for PCL based Apps. The + /// AssetLoader needs a refactor cause right now it lives in 3+ platforms which + /// can all be loaded on Windows. /// - /// The default assembly. + /// public void SetDefaultAssembly(Assembly assembly) { _defaultAssembly = new AssemblyDescriptor(assembly); } + /// /// /// Checks if an asset with the specified URI exists. /// /// The URI. /// - /// A base URI to use if is relative. + /// A base URI to use if is relative. /// /// True if the asset could be found; otherwise false. public bool Exists(Uri uri, Uri baseUri = null) @@ -56,34 +62,37 @@ namespace Avalonia.Shared.PlatformSupport return GetAsset(uri, baseUri) != null; } + /// /// - /// Opens the resource with the requested URI. + /// Opens the asset with the requested URI. /// /// The URI. /// - /// A base URI to use if is relative. + /// A base URI to use if is relative. /// - /// A stream containing the resource contents. - /// + /// A stream containing the asset contents. + /// /// The resource was not found. /// - public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Item1; - + public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).stream; + + + /// /// - /// Opens the resource with the requested URI and returns the resource string and the - /// assembly containing the resource. + /// Opens the asset with the requested URI and returns the asset stream and the + /// assembly containing the asset. /// /// The URI. /// - /// A base URI to use if is relative. + /// A base URI to use if is relative. /// /// - /// The stream containing the resource contents together with the assembly. + /// The stream containing the asset contents together with the assembly. /// - /// + /// /// The resource was not found. /// - public Tuple OpenAndGetAssembly(Uri uri, Uri baseUri = null) + public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { var asset = GetAsset(uri, baseUri); @@ -92,7 +101,22 @@ namespace Avalonia.Shared.PlatformSupport throw new FileNotFoundException($"The resource {uri} could not be found."); } - return Tuple.Create(asset.GetStream(), asset.Assembly); + return (asset.GetStream(), asset.Assembly); + } + + /// + /// + /// Gets all assets at a specific location. + /// + /// The location of assets. + /// A tuple containing the absolute path to the resource and the owner assembly + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) + { + var assembly = GetAssembly(location); + + return assembly?.Assets.Where(x => x.Key.Contains(location.AbsolutePath)) + .Select(x => (x.Key, x.Value.Assembly)) ?? + Enumerable.Empty<(string AbsolutePath, Assembly Assembly)>(); } private IAssetDescriptor GetAsset(Uri uri, Uri baseUri) @@ -110,8 +134,8 @@ namespace Avalonia.Shared.PlatformSupport IAssetDescriptor rv; - var resourceKey = uri.AbsolutePath; - asm.Resources.TryGetValue(resourceKey, out rv); + var assetKey = uri.AbsolutePath; + asm.Assets.TryGetValue(assetKey, out rv); return rv; } throw new ArgumentException($"Invalid uri, see https://github.com/AvaloniaUI/Avalonia/issues/282#issuecomment-166982104", nameof(uri)); @@ -122,9 +146,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); } @@ -140,8 +163,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().GetLoadedAssemblies(); var match = loadedAssemblies.FirstOrDefault(a => a.GetName().Name == name); @@ -208,14 +230,14 @@ namespace Avalonia.Shared.PlatformSupport if (assembly != null) { - Resources = assembly.GetManifestResourceNames() + Assets = assembly.GetManifestResourceNames() .ToDictionary(n => n, n => (IAssetDescriptor)new AssemblyResourceDescriptor(assembly, n)); Name = assembly.GetName().Name; } } public Assembly Assembly { get; } - public Dictionary Resources { get; } + public Dictionary Assets { get; } public string Name { get; } } } diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs index d6b70aee16..abfac77a5e 100644 --- a/tests/Avalonia.UnitTests/MockAssetLoader.cs +++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; -using System.Threading.Tasks; using Avalonia.Platform; namespace Avalonia.UnitTests @@ -27,10 +26,16 @@ namespace Avalonia.UnitTests { return new MemoryStream(Encoding.UTF8.GetBytes(_assets[uri])); } - - public Tuple OpenAndGetAssembly(Uri uri, Uri baseUri = null) + + public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) + { + return (Open(uri, baseUri), (Assembly)null); + } + + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) { - return Tuple.Create(Open(uri, baseUri), (Assembly)null); + return _assets.Keys.Where(x => x.AbsolutePath.Contains(location.AbsolutePath)) + .Select(x => (x.AbsolutePath, Assembly.GetEntryAssembly())); } public void SetDefaultAssembly(Assembly asm) From 724bb45abb8ce55d8dfea9d91a746f386990a2cd Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Wed, 23 May 2018 00:26:42 +0200 Subject: [PATCH 27/36] comment fixes --- src/Avalonia.Base/Platform/IAssetLoader.cs | 6 +++--- src/Shared/PlatformSupport/AssetLoader.cs | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.Base/Platform/IAssetLoader.cs b/src/Avalonia.Base/Platform/IAssetLoader.cs index 3b459818dd..d3b6cafeae 100644 --- a/src/Avalonia.Base/Platform/IAssetLoader.cs +++ b/src/Avalonia.Base/Platform/IAssetLoader.cs @@ -41,7 +41,7 @@ namespace Avalonia.Platform /// /// A stream containing the asset contents. /// - /// The resource was not found. + /// The asset could not be found. /// Stream Open(Uri uri, Uri baseUri = null); @@ -57,7 +57,7 @@ namespace Avalonia.Platform /// The stream containing the asset contents together with the assembly. /// /// - /// The resource was not found. + /// The asset could not be found. /// (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null); @@ -65,7 +65,7 @@ namespace Avalonia.Platform /// Gets all assets at a specific location. /// /// The location of assets. - /// A tuple containing the absolute path to the resource and the owner assembly + /// A tuple containing the absolute path to the asset and the owner assembly IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location); } } diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index b835170036..0cf60a5e19 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -72,7 +72,7 @@ namespace Avalonia.Shared.PlatformSupport /// /// A stream containing the asset contents. /// - /// The resource was not found. + /// The asset could not be found. /// public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).stream; @@ -90,7 +90,7 @@ namespace Avalonia.Shared.PlatformSupport /// The stream containing the asset contents together with the assembly. /// /// - /// The resource was not found. + /// The asset could not be found. /// public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { @@ -98,7 +98,7 @@ namespace Avalonia.Shared.PlatformSupport if (asset == null) { - throw new FileNotFoundException($"The resource {uri} could not be found."); + throw new FileNotFoundException($"The asset {uri} could not be found."); } return (asset.GetStream(), asset.Assembly); @@ -114,6 +114,8 @@ namespace Avalonia.Shared.PlatformSupport { var assembly = GetAssembly(location); + var availableAssets = assembly?.Assets; + return assembly?.Assets.Where(x => x.Key.Contains(location.AbsolutePath)) .Select(x => (x.Key, x.Value.Assembly)) ?? Enumerable.Empty<(string AbsolutePath, Assembly Assembly)>(); @@ -129,7 +131,7 @@ namespace Avalonia.Shared.PlatformSupport { throw new ArgumentException( "No default assembly, entry assembly or explicit assembly specified; " + - "don't know where to look up for the resource, try specifiyng assembly explicitly."); + "don't know where to look up for the asset, try specifiyng assembly explicitly."); } IAssetDescriptor rv; From f609c9c5d99595c4749a5e5ad8c770886ce4e0fb Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Wed, 23 May 2018 01:46:16 +0200 Subject: [PATCH 28/36] Cleanup --- src/Avalonia.Base/Platform/IAssetLoader.cs | 8 +-- src/Shared/PlatformSupport/AssetLoader.cs | 62 +++++++++------------ tests/Avalonia.UnitTests/MockAssetLoader.cs | 4 +- 3 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/Avalonia.Base/Platform/IAssetLoader.cs b/src/Avalonia.Base/Platform/IAssetLoader.cs index d3b6cafeae..dda2cbc2d5 100644 --- a/src/Avalonia.Base/Platform/IAssetLoader.cs +++ b/src/Avalonia.Base/Platform/IAssetLoader.cs @@ -62,10 +62,10 @@ namespace Avalonia.Platform (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null); /// - /// Gets all assets at a specific location. + /// Gets all assets of a folder and subfolders that match specified uri. /// - /// The location of assets. - /// A tuple containing the absolute path to the asset and the owner assembly - IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location); + /// The URI. + /// All matching assets as a tuple of the absolute path to the asset and the assembly containing the asset + IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri uri); } } diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index 0cf60a5e19..b4d17b22a1 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -10,7 +10,6 @@ using Avalonia.Platform; namespace Avalonia.Shared.PlatformSupport { - /// /// /// Loads assets compiled into the application binary. /// @@ -35,26 +34,21 @@ namespace Avalonia.Shared.PlatformSupport _defaultAssembly = new AssemblyDescriptor(assembly); } - /// /// - /// We need a way to override the default assembly selected by the host platform - /// because right now it is selecting the wrong one for PCL based Apps. The - /// AssetLoader needs a refactor cause right now it lives in 3+ platforms which - /// can all be loaded on Windows. + /// Sets the default assembly from which to load assets for which no assembly is specified. /// - /// + /// The default assembly. public void SetDefaultAssembly(Assembly assembly) { _defaultAssembly = new AssemblyDescriptor(assembly); } - /// /// /// Checks if an asset with the specified URI exists. /// /// The URI. /// - /// A base URI to use if is relative. + /// A base URI to use if is relative. /// /// True if the asset could be found; otherwise false. public bool Exists(Uri uri, Uri baseUri = null) @@ -62,34 +56,31 @@ namespace Avalonia.Shared.PlatformSupport return GetAsset(uri, baseUri) != null; } - /// /// /// Opens the asset with the requested URI. /// /// The URI. /// - /// A base URI to use if is relative. + /// A base URI to use if is relative. /// /// A stream containing the asset contents. - /// + /// /// The asset could not be found. /// - public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).stream; + public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Item1; - - /// /// /// Opens the asset with the requested URI and returns the asset stream and the /// assembly containing the asset. /// /// The URI. /// - /// A base URI to use if is relative. + /// A base URI to use if is relative. /// /// - /// The stream containing the asset contents together with the assembly. + /// The stream containing the resource contents together with the assembly. /// - /// + /// /// The asset could not be found. /// public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) @@ -98,25 +89,22 @@ namespace Avalonia.Shared.PlatformSupport if (asset == null) { - throw new FileNotFoundException($"The asset {uri} could not be found."); + throw new FileNotFoundException($"The resource {uri} could not be found."); } return (asset.GetStream(), asset.Assembly); } - /// /// - /// Gets all assets at a specific location. + /// Gets all assets of a folder and subfolders that match specified uri. /// - /// The location of assets. - /// A tuple containing the absolute path to the resource and the owner assembly - public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) + /// The URI. + /// All matching assets as a tuple of the absolute path to the asset and the assembly containing the asset + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri uri) { - var assembly = GetAssembly(location); - - var availableAssets = assembly?.Assets; + var assembly = GetAssembly(uri); - return assembly?.Assets.Where(x => x.Key.Contains(location.AbsolutePath)) + return assembly?.Resources.Where(x => x.Key.Contains(uri.AbsolutePath)) .Select(x => (x.Key, x.Value.Assembly)) ?? Enumerable.Empty<(string AbsolutePath, Assembly Assembly)>(); } @@ -131,13 +119,13 @@ namespace Avalonia.Shared.PlatformSupport { throw new ArgumentException( "No default assembly, entry assembly or explicit assembly specified; " + - "don't know where to look up for the asset, try specifiyng assembly explicitly."); + "don't know where to look up for the resource, try specifiyng assembly explicitly."); } IAssetDescriptor rv; - var assetKey = uri.AbsolutePath; - asm.Assets.TryGetValue(assetKey, out rv); + var resourceKey = uri.AbsolutePath; + asm.Resources.TryGetValue(resourceKey, out rv); return rv; } throw new ArgumentException($"Invalid uri, see https://github.com/AvaloniaUI/Avalonia/issues/282#issuecomment-166982104", nameof(uri)); @@ -148,8 +136,9 @@ namespace Avalonia.Shared.PlatformSupport if (uri != null) { var qs = ParseQueryString(uri); + string assemblyName; - if (qs.TryGetValue("assembly", out var assemblyName)) + if (qs.TryGetValue("assembly", out assemblyName)) { return GetAssembly(assemblyName); } @@ -165,7 +154,8 @@ namespace Avalonia.Shared.PlatformSupport return _defaultAssembly; } - if (!AssemblyNameCache.TryGetValue(name, out var rv)) + AssemblyDescriptor rv; + if (!AssemblyNameCache.TryGetValue(name, out rv)) { var loadedAssemblies = AvaloniaLocator.Current.GetService().GetLoadedAssemblies(); var match = loadedAssemblies.FirstOrDefault(a => a.GetName().Name == name); @@ -232,15 +222,15 @@ namespace Avalonia.Shared.PlatformSupport if (assembly != null) { - Assets = assembly.GetManifestResourceNames() + Resources = assembly.GetManifestResourceNames() .ToDictionary(n => n, n => (IAssetDescriptor)new AssemblyResourceDescriptor(assembly, n)); Name = assembly.GetName().Name; } } public Assembly Assembly { get; } - public Dictionary Assets { get; } + public Dictionary Resources { get; } public string Name { get; } } } -} +} \ No newline at end of file diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs index abfac77a5e..11d66128a7 100644 --- a/tests/Avalonia.UnitTests/MockAssetLoader.cs +++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs @@ -32,9 +32,9 @@ namespace Avalonia.UnitTests return (Open(uri, baseUri), (Assembly)null); } - public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri uri) { - return _assets.Keys.Where(x => x.AbsolutePath.Contains(location.AbsolutePath)) + return _assets.Keys.Where(x => x.AbsolutePath.Contains(uri.AbsolutePath)) .Select(x => (x.AbsolutePath, Assembly.GetEntryAssembly())); } From a59cf3a135e4785571f1b80c569e0b6e2ec34f3b Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Wed, 23 May 2018 19:36:42 +0200 Subject: [PATCH 29/36] New asset loader Added unit test for wildcard --- src/Avalonia.Base/Platform/IAssetLoader.cs | 26 ++++++------ .../Media/Fonts/FontFamilyLoader.cs | 7 ++-- src/Shared/PlatformSupport/AssetLoader.cs | 34 +++++++++------ tests/Avalonia.UnitTests/MockAssetLoader.cs | 7 ++-- .../Media/Fonts/FontFamilyLoaderTests.cs | 42 ++++++++++++++++--- 5 files changed, 77 insertions(+), 39 deletions(-) diff --git a/src/Avalonia.Base/Platform/IAssetLoader.cs b/src/Avalonia.Base/Platform/IAssetLoader.cs index 767ce4ad8e..dda2cbc2d5 100644 --- a/src/Avalonia.Base/Platform/IAssetLoader.cs +++ b/src/Avalonia.Base/Platform/IAssetLoader.cs @@ -19,8 +19,8 @@ namespace Avalonia.Platform /// AssetLoader needs a refactor cause right now it lives in 3+ platforms which /// can all be loaded on Windows. /// - /// - void SetDefaultAssembly(Assembly asm); + /// + void SetDefaultAssembly(Assembly assembly); /// /// Checks if an asset with the specified URI exists. @@ -33,39 +33,39 @@ namespace Avalonia.Platform bool Exists(Uri uri, Uri baseUri = null); /// - /// Opens the resource with the requested URI. + /// Opens the asset with the requested URI. /// /// The URI. /// /// A base URI to use if is relative. /// - /// A stream containing the resource contents. + /// A stream containing the asset contents. /// - /// The resource was not found. + /// The asset could not be found. /// Stream Open(Uri uri, Uri baseUri = null); /// - /// Opens the resource with the requested URI and returns the resource string and the - /// assembly containing the resource. + /// Opens the asset with the requested URI and returns the asset stream and the + /// assembly containing the asset. /// /// The URI. /// /// A base URI to use if is relative. /// /// - /// The stream containing the resource contents together with the assembly. + /// The stream containing the asset contents together with the assembly. /// /// - /// The resource was not found. + /// The asset could not be found. /// (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null); /// - /// Gets all assets at a specific location. + /// Gets all assets of a folder and subfolders that match specified uri. /// - /// The location of assets. - /// A tuple containing the absolute path to the resource and the owner assembly - IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location); + /// The URI. + /// All matching assets as a tuple of the absolute path to the asset and the assembly containing the asset + IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri uri); } } diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs index 803d15d49f..2b77371bb5 100644 --- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs +++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs @@ -34,9 +34,7 @@ namespace Avalonia.Media.Fonts { var availableAssets = s_assetLoader.GetAssets(location); - var locationPath = location.AbsolutePath; - - var matchingAssets = availableAssets.Where(x => x.absolutePath.Contains(locationPath) && x.absolutePath.EndsWith(".ttf")); + var matchingAssets = availableAssets.Where(x => x.absolutePath.EndsWith(".ttf")); return matchingAssets.Select(x => GetAssetUri(x.absolutePath, x.assembly)); } @@ -54,7 +52,8 @@ namespace Avalonia.Media.Fonts var compareTo = location.AbsolutePath + "." + fileName.Split('*').First(); - var matchingResources = availableResources.Where(x => x.absolutePath.Contains(compareTo)); + var matchingResources = + availableResources.Where(x => x.absolutePath.Contains(compareTo) && x.absolutePath.EndsWith(".ttf")); return matchingResources.Select(x => GetAssetUri(x.absolutePath, x.assembly)); } diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index d4f0ba6d17..b4d17b22a1 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -57,21 +57,21 @@ namespace Avalonia.Shared.PlatformSupport } /// - /// Opens the resource with the requested URI. + /// Opens the asset with the requested URI. /// /// The URI. /// /// A base URI to use if is relative. /// - /// A stream containing the resource contents. + /// A stream containing the asset contents. /// - /// The resource was not found. + /// The asset could not be found. /// - public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).stream; + public Stream Open(Uri uri, Uri baseUri = null) => OpenAndGetAssembly(uri, baseUri).Item1; /// - /// Opens the resource with the requested URI and returns the resource string and the - /// assembly containing the resource. + /// Opens the asset with the requested URI and returns the asset stream and the + /// assembly containing the asset. /// /// The URI. /// @@ -81,7 +81,7 @@ namespace Avalonia.Shared.PlatformSupport /// The stream containing the resource contents together with the assembly. /// /// - /// The resource was not found. + /// The asset could not be found. /// public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { @@ -95,11 +95,17 @@ namespace Avalonia.Shared.PlatformSupport return (asset.GetStream(), asset.Assembly); } - public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) + /// + /// Gets all assets of a folder and subfolders that match specified uri. + /// + /// The URI. + /// All matching assets as a tuple of the absolute path to the asset and the assembly containing the asset + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri uri) { - var assembly = GetAssembly(location); + var assembly = GetAssembly(uri); - return assembly?.Resources.Select(x => (x.Key, x.Value.Assembly)) ?? + return assembly?.Resources.Where(x => x.Key.Contains(uri.AbsolutePath)) + .Select(x => (x.Key, x.Value.Assembly)) ?? Enumerable.Empty<(string AbsolutePath, Assembly Assembly)>(); } @@ -130,8 +136,9 @@ namespace Avalonia.Shared.PlatformSupport if (uri != null) { var qs = ParseQueryString(uri); + string assemblyName; - if (qs.TryGetValue("assembly", out var assemblyName)) + if (qs.TryGetValue("assembly", out assemblyName)) { return GetAssembly(assemblyName); } @@ -147,7 +154,8 @@ namespace Avalonia.Shared.PlatformSupport return _defaultAssembly; } - if (!AssemblyNameCache.TryGetValue(name, out var rv)) + AssemblyDescriptor rv; + if (!AssemblyNameCache.TryGetValue(name, out rv)) { var loadedAssemblies = AvaloniaLocator.Current.GetService().GetLoadedAssemblies(); var match = loadedAssemblies.FirstOrDefault(a => a.GetName().Name == name); @@ -225,4 +233,4 @@ namespace Avalonia.Shared.PlatformSupport public string Name { get; } } } -} +} \ No newline at end of file diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs index cebd88b6a0..11d66128a7 100644 --- a/tests/Avalonia.UnitTests/MockAssetLoader.cs +++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs @@ -26,15 +26,16 @@ namespace Avalonia.UnitTests { return new MemoryStream(Encoding.UTF8.GetBytes(_assets[uri])); } - + public (Stream stream, Assembly assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null) { return (Open(uri, baseUri), (Assembly)null); } - public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri location) + public IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri uri) { - return _assets.Keys.Select(x => (x.AbsolutePath, Assembly.GetEntryAssembly())); + return _assets.Keys.Where(x => x.AbsolutePath.Contains(uri.AbsolutePath)) + .Select(x => (x.AbsolutePath, Assembly.GetEntryAssembly())); } public void SetDefaultAssembly(Assembly asm) diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs index ef7171d651..81bf638f14 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs @@ -11,20 +11,50 @@ namespace Avalonia.Visuals.UnitTests.Media.Fonts { public class FontFamilyLoaderTests { + private const string fontName = "#MyFont"; + private const string assembly = "?assembly=Avalonia.Visuals.UnitTests"; + private const string assetLocation = "resm:Avalonia.Visuals.UnitTests.Assets"; + + [Fact] + public void Should_Load_Single_FontAsset() + { + const string fontAsset = assetLocation + ".MyFont-Regular.ttf" + assembly + fontName; + + using (StartWithResources((fontAsset, "AssetData"))) + { + var source = new Uri(fontAsset, UriKind.RelativeOrAbsolute); + + var key = new FontFamilyKey(source); + + var fontAssets = FontFamilyLoader.LoadFontAssets(key); + + Assert.Single(fontAssets); + } + } + [Fact] - public void Should_Load_Single_FontResource() + public void Should_Load_Matching_Assets() { - const string resourcePath = "resm:Avalonia.Visuals.UnitTests.Assets.MyFont.ttf?assembly=Avalonia.Visuals.UnitTests#MyFont"; + const string assetMyFontRegular = assetLocation + ".MyFont-Regular.ttf" + assembly + fontName; + const string assetMyFontBold = assetLocation + ".MyFont-Bold.ttf" + assembly + fontName; + const string assetYourFont = assetLocation + ".YourFont.ttf" + assembly + fontName; + + var fontLocations = new[] + { + (assetMyFontRegular, "AssetData"), + (assetMyFontBold, "AssetData"), + (assetYourFont, "AssetData") + }; - using (StartWithResources((resourcePath, "MyFont.ttf"))) + using (StartWithResources(fontLocations)) { - var source = new Uri(resourcePath, UriKind.RelativeOrAbsolute); + var source = new Uri(assetLocation + ".MyFont-*.ttf", UriKind.RelativeOrAbsolute); var key = new FontFamilyKey(source); - var resources = FontFamilyLoader.LoadFontAssets(key); + var fontAssets = FontFamilyLoader.LoadFontAssets(key); - Assert.Single(resources); + Assert.Equal(2, fontAssets.Count()); } } From f3f750cf867e4fc4d5e290388641593ff0d1f012 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Wed, 23 May 2018 19:46:48 +0200 Subject: [PATCH 30/36] Cleanup --- src/Skia/Avalonia.Skia/SKTypefaceCollection.cs | 2 -- tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf | 1 - .../Avalonia.Visuals.UnitTests.csproj | 6 ------ .../Media/Fonts/FontFamilyKeyTests.cs | 1 - 4 files changed, 10 deletions(-) delete mode 100644 tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs index 261e6667c3..bd951ef3a3 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs @@ -6,8 +6,6 @@ namespace Avalonia.Skia { internal class SKTypefaceCollection { - - private readonly ConcurrentDictionary _cachedTypefaces = new ConcurrentDictionary(); diff --git a/tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf b/tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf deleted file mode 100644 index 5f282702bb..0000000000 --- a/tests/Avalonia.Visuals.UnitTests/Assets/MyFont.ttf +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj index 0b2a7faef0..2b559c9c56 100644 --- a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj +++ b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj @@ -7,12 +7,6 @@ - - - - - - diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs index d119ed2d47..96464b5784 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyKeyTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; -using Avalonia.Media; using Avalonia.Media.Fonts; using Xunit; From d5505269368e1eb9ebdf71ee0b8e930ebcd4f17c Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Wed, 23 May 2018 22:24:05 +0200 Subject: [PATCH 31/36] Unit test fix --- .../Media/Fonts/FontFamilyLoaderTests.cs | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs index 81bf638f14..19716431b9 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs @@ -9,53 +9,66 @@ using Xunit; namespace Avalonia.Visuals.UnitTests.Media.Fonts { + using System.Diagnostics; + public class FontFamilyLoaderTests { - private const string fontName = "#MyFont"; - private const string assembly = "?assembly=Avalonia.Visuals.UnitTests"; - private const string assetLocation = "resm:Avalonia.Visuals.UnitTests.Assets"; + private const string FontName = "#MyFont"; + private const string Assembly = "?assembly=Avalonia.Visuals.UnitTests"; + private const string AssetLocation = "resm:Avalonia.Visuals.UnitTests.Assets"; + + private readonly IDisposable _testApplication; + + public FontFamilyLoaderTests() + { + const string AssetMyFontRegular = AssetLocation + ".MyFont-Regular.ttf" + Assembly + FontName; + const string AssetMyFontBold = AssetLocation + ".MyFont-Bold.ttf" + Assembly + FontName; + const string AssetYourFont = AssetLocation + ".YourFont.ttf" + Assembly + FontName; + + var fontAssets = new[] + { + (AssetMyFontRegular, "AssetData"), + (AssetMyFontBold, "AssetData"), + (AssetYourFont, "AssetData") + }; + + _testApplication = StartWithResources(fontAssets); + } + + ~FontFamilyLoaderTests() + { + _testApplication.Dispose(); + } [Fact] public void Should_Load_Single_FontAsset() { - const string fontAsset = assetLocation + ".MyFont-Regular.ttf" + assembly + fontName; + const string FontAsset = AssetLocation + ".MyFont-Regular.ttf" + Assembly + FontName; - using (StartWithResources((fontAsset, "AssetData"))) - { - var source = new Uri(fontAsset, UriKind.RelativeOrAbsolute); + var source = new Uri(FontAsset, UriKind.RelativeOrAbsolute); - var key = new FontFamilyKey(source); + var key = new FontFamilyKey(source); - var fontAssets = FontFamilyLoader.LoadFontAssets(key); + var fontAssets = FontFamilyLoader.LoadFontAssets(key); - Assert.Single(fontAssets); - } + Assert.Single(fontAssets); } [Fact] public void Should_Load_Matching_Assets() { - const string assetMyFontRegular = assetLocation + ".MyFont-Regular.ttf" + assembly + fontName; - const string assetMyFontBold = assetLocation + ".MyFont-Bold.ttf" + assembly + fontName; - const string assetYourFont = assetLocation + ".YourFont.ttf" + assembly + fontName; + var source = new Uri(AssetLocation + ".MyFont-*.ttf" + Assembly + FontName, UriKind.RelativeOrAbsolute); - var fontLocations = new[] - { - (assetMyFontRegular, "AssetData"), - (assetMyFontBold, "AssetData"), - (assetYourFont, "AssetData") - }; + var key = new FontFamilyKey(source); - using (StartWithResources(fontLocations)) - { - var source = new Uri(assetLocation + ".MyFont-*.ttf", UriKind.RelativeOrAbsolute); + var fontAssets = FontFamilyLoader.LoadFontAssets(key).ToArray(); - var key = new FontFamilyKey(source); - - var fontAssets = FontFamilyLoader.LoadFontAssets(key); - - Assert.Equal(2, fontAssets.Count()); + foreach (var fontAsset in fontAssets) + { + Debug.WriteLine(fontAsset); } + + Assert.Equal(2, fontAssets.Length); } private static IDisposable StartWithResources(params (string, string)[] assets) From e50f2d269a9ca870c5c3334fad9e76542d1ef480 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Thu, 24 May 2018 01:29:25 +0200 Subject: [PATCH 32/36] Removed IFontFamily Some code style fixes --- src/Avalonia.Visuals/Media/FontFamily.cs | 41 +++++++++++++++---- src/Avalonia.Visuals/Media/IFontFamily.cs | 35 ---------------- src/Avalonia.Visuals/Media/Typeface.cs | 4 +- .../SKTypefaceCollectionCache.cs | 4 +- .../Media/Direct2D1FontCollectionCache.cs | 17 +++++--- 5 files changed, 47 insertions(+), 54 deletions(-) delete mode 100644 src/Avalonia.Visuals/Media/IFontFamily.cs diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index d7b7edd96f..a4b4f5085a 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -8,7 +8,7 @@ using Avalonia.Media.Fonts; namespace Avalonia.Media { - public class FontFamily : IFontFamily + public class FontFamily { /// /// Initializes a new instance of the class. @@ -45,17 +45,34 @@ namespace Avalonia.Media Key = new FontFamilyKey(source); } + /// + /// Represents the default font family + /// public static FontFamily Default => new FontFamily("Courier New"); + /// + /// Gets the primary family name of the font family. + /// + /// + /// The primary name of the font family. + /// public string Name => FamilyNames.PrimaryFamilyName; - - FamilyNameCollection IFontFamily.FamilyNames => FamilyNames; - FontFamilyKey IFontFamily.Key => Key; - - internal FamilyNameCollection FamilyNames { get; } + /// + /// Gets the family names. + /// + /// + /// The family familyNames. + /// + public FamilyNameCollection FamilyNames { get; } - internal FontFamilyKey Key { get; } + /// + /// Gets the key for associated assets. + /// + /// + /// The family familyNames. + /// + public FontFamilyKey Key { get; } /// /// Implicit conversion of string to FontFamily @@ -76,7 +93,10 @@ namespace Avalonia.Media /// public static FontFamily Parse(string s) { - if (string.IsNullOrEmpty(s)) throw new ArgumentException("Specified family is not supported."); + if (string.IsNullOrEmpty(s)) + { + throw new ArgumentException("Specified family is not supported."); + } var segments = s.Split('#'); @@ -143,7 +163,10 @@ namespace Avalonia.Media public override bool Equals(object obj) { - if (!(obj is FontFamily other)) return false; + if (!(obj is FontFamily other)) + { + return false; + } if (Key != null) { diff --git a/src/Avalonia.Visuals/Media/IFontFamily.cs b/src/Avalonia.Visuals/Media/IFontFamily.cs deleted file mode 100644 index b6a5201bf5..0000000000 --- a/src/Avalonia.Visuals/Media/IFontFamily.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Avalonia.Media -{ - using Avalonia.Media.Fonts; - - public interface IFontFamily - { - /// - /// Gets the name of the font family. - /// - /// - /// The name of the font family. - /// - string Name { get; } - - /// - /// Gets the family names. - /// - /// - /// The family familyNames. - /// - FamilyNameCollection FamilyNames { get; } - - /// - /// Gets the key for associated assets. - /// - /// - /// The family familyNames. - /// - FontFamilyKey Key { get; } - } -} diff --git a/src/Avalonia.Visuals/Media/Typeface.cs b/src/Avalonia.Visuals/Media/Typeface.cs index 1c619f5f5c..40e98d1565 100644 --- a/src/Avalonia.Visuals/Media/Typeface.cs +++ b/src/Avalonia.Visuals/Media/Typeface.cs @@ -15,7 +15,7 @@ namespace Avalonia.Media /// The font style. /// The font weight. public Typeface( - IFontFamily fontFamily, + FontFamily fontFamily, double fontSize = 12, FontStyle style = FontStyle.Normal, FontWeight weight = FontWeight.Normal) @@ -55,7 +55,7 @@ namespace Avalonia.Media /// /// Gets the font family. /// - public IFontFamily FontFamily { get; } + public FontFamily FontFamily { get; } /// /// Gets the size of the font in DIPs. diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs index f8ee62f1f2..dc533cbf3c 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs @@ -20,7 +20,7 @@ namespace Avalonia.Skia /// /// The font family. /// - public static SKTypefaceCollection GetOrAddTypefaceCollection(IFontFamily fontFamily) + public static SKTypefaceCollection GetOrAddTypefaceCollection(FontFamily fontFamily) { return s_cachedCollections.GetOrAdd(fontFamily.Key, x => CreateCustomFontCollection(fontFamily)); } @@ -30,7 +30,7 @@ namespace Avalonia.Skia /// /// The font family. /// - private static SKTypefaceCollection CreateCustomFontCollection(IFontFamily fontFamily) + private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily) { var fontAssets = FontFamilyLoader.LoadFontAssets(fontFamily.Key); diff --git a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs index 0c69d9932e..4199c73c54 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs @@ -19,11 +19,6 @@ namespace Avalonia.Direct2D1.Media s_installedFontCollection = s_factory.GetSystemFontCollection(false); } - public static SharpDX.DirectWrite.FontCollection GetOrAddFontCollection(IFontFamily fontFamily) - { - return fontFamily.Key == null ? s_installedFontCollection : s_cachedCollections.GetOrAdd(fontFamily.Key, CreateFontCollection); - } - public static SharpDX.DirectWrite.TextFormat GetTextFormat(Typeface typeface) { var fontFamily = typeface.FontFamily; @@ -33,8 +28,13 @@ namespace Avalonia.Direct2D1.Media // Should this be cached? foreach (var familyName in fontFamily.FamilyNames) { - if (!fontCollection.FindFamilyName(familyName, out _)) continue; + if (!fontCollection.FindFamilyName(familyName, out _)) + { + continue; + } + fontFamilyName = familyName; + break; } @@ -48,6 +48,11 @@ namespace Avalonia.Direct2D1.Media (float)typeface.FontSize); } + private static SharpDX.DirectWrite.FontCollection GetOrAddFontCollection(FontFamily fontFamily) + { + return fontFamily.Key == null ? s_installedFontCollection : s_cachedCollections.GetOrAdd(fontFamily.Key, CreateFontCollection); + } + private static SharpDX.DirectWrite.FontCollection CreateFontCollection(FontFamilyKey key) { var assets = FontFamilyLoader.LoadFontAssets(key); From 17dfa70b4f1fe4fcc3cdfc3bfc72d698bff2bd34 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Thu, 24 May 2018 01:39:38 +0200 Subject: [PATCH 33/36] ControlCatalog .csproj fix --- samples/ControlCatalog/ControlCatalog.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 390d8d6bcb..c37002ef6a 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -11,12 +11,6 @@ - - - - - - From 755ce215645c3d7b17d8b9267941a11a3abc546c Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 24 May 2018 04:11:15 +0200 Subject: [PATCH 34/36] Fix RadioButton bullet border at 1px. `BorderThickness` is now a `Thickness` so we can't bind `StrokeThickness` to it. --- src/Avalonia.Themes.Default/RadioButton.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Themes.Default/RadioButton.xaml b/src/Avalonia.Themes.Default/RadioButton.xaml index fb71432595..d29cb89452 100644 --- a/src/Avalonia.Themes.Default/RadioButton.xaml +++ b/src/Avalonia.Themes.Default/RadioButton.xaml @@ -8,7 +8,7 @@ From 0f7ab7e61f2786cbdfb720d9f2463f5d2a218c60 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 24 May 2018 19:29:46 +0100 Subject: [PATCH 35/36] add singleitem psuedo class on items control. --- src/Avalonia.Controls/ItemsControl.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 6a26e29187..910db2500a 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -364,6 +364,7 @@ namespace Avalonia.Controls var collection = sender as ICollection; PseudoClasses.Set(":empty", collection == null || collection.Count == 0); + PseudoClasses.Set(":singleitem", collection != null && collection.Count == 1); } /// @@ -421,6 +422,8 @@ namespace Avalonia.Controls private void SubscribeToItems(IEnumerable items) { PseudoClasses.Set(":empty", items == null || items.Count() == 0); + PseudoClasses.Set(":singleitem", items != null && items.Count() == 1); + var incc = items as INotifyCollectionChanged; From 4479734961c0ff02cf6433742873458f3ef58701 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 24 May 2018 19:42:58 +0100 Subject: [PATCH 36/36] remove added whitespace. --- src/Avalonia.Controls/ItemsControl.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 910db2500a..5119096965 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -424,7 +424,6 @@ namespace Avalonia.Controls PseudoClasses.Set(":empty", items == null || items.Count() == 0); PseudoClasses.Set(":singleitem", items != null && items.Count() == 1); - var incc = items as INotifyCollectionChanged; if (incc != null)

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 literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf b/samples/ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..82e8762011e6a3d937bf5f2fd9fb78e16d47e8f1 GIT binary patch literal 103828 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 E0N-o()Bpeg literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog/Assets/Fonts/SourceSansPro-Regular.ttf b/samples/ControlCatalog/Assets/Fonts/SourceSansPro-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..278ad8aa0a09592a759e39f8fc06d0fa9d986fb0 GIT binary patch literal 293516 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%0ACauZ%OI`!GPd*?{ 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 !Ih$)5?K~W=vG3ozB3)0nf!55x3ZA5aar=Ra8Fj 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 WZJ|m11)WV1+;LQ8al| + + + + + + + + + + + + diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml index db1c9cb69d..fb0d8fb7b1 100644 --- a/samples/ControlCatalog/Pages/TextBoxPage.xaml +++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml @@ -31,6 +31,12 @@ - + + + + + + + \ No newline at end of file diff --git a/src/Avalonia.Base/Platform/IAssetLoader.cs b/src/Avalonia.Base/Platform/IAssetLoader.cs index ba30af60bf..26d79d5567 100644 --- a/src/Avalonia.Base/Platform/IAssetLoader.cs +++ b/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. using System; +using System.Collections.Generic; using System.IO; using System.Reflection; @@ -58,6 +59,13 @@ namespace Avalonia.Platform /// /// The resource was not found. /// - Tuple OpenAndGetAssembly(Uri uri, Uri baseUri = null); + (Stream Stream, Assembly Assembly) OpenAndGetAssembly(Uri uri, Uri baseUri = null); + + ///