From 9fdb66bff766bebd99c9f3d12ad823f736d0385f Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 18 Jun 2024 21:25:37 +0300 Subject: [PATCH] chore: Wasm - in progress --- src/Uno.UI/UI/Xaml/FontFamily.wasm.cs | 58 ------------- src/Uno.UI/UI/Xaml/FontFamilyLoader.wasm.cs | 86 +++++++++++++++---- .../UI/Xaml/UIElement.TextHelper.wasm.cs | 2 +- 3 files changed, 68 insertions(+), 78 deletions(-) diff --git a/src/Uno.UI/UI/Xaml/FontFamily.wasm.cs b/src/Uno.UI/UI/Xaml/FontFamily.wasm.cs index a0402066683a..761941ce70a2 100644 --- a/src/Uno.UI/UI/Xaml/FontFamily.wasm.cs +++ b/src/Uno.UI/UI/Xaml/FontFamily.wasm.cs @@ -14,69 +14,11 @@ public partial class FontFamily { private FontFamilyLoader _loader; - - /// - /// Contains the font-face name to use in CSS. - /// - internal string CssFontName { get; private set; } - - internal string? ExternalSource { get; private set; } - partial void Init(string fontName) { - ParseSource(Source); _loader = FontFamilyLoader.GetLoaderForFontFamily(this); } - [MemberNotNull(nameof(CssFontName))] - private void ParseSource(string source) - { - var sourceParts = source.Split('#', 2, StringSplitOptions.RemoveEmptyEntries); - - if (sourceParts.Length > 0) - { - if (TryGetExternalUri(sourceParts[0], out var externalUri) && externalUri is { }) - { - ExternalSource = externalUri.OriginalString; - CssFontName = "font" + ExternalSource.GetHashCode(); - } - else - { - CssFontName = sourceParts[sourceParts.Length == 2 ? 1 : 0]; - } - } - else - { - throw new InvalidOperationException("FontFamily source cannot be empty"); - } - } - - private static bool TryGetExternalUri(string? source, out Uri? uri) - { - if (source is not null && (source.IndexOf('.') > -1 || source.IndexOf('/') > -1)) - { - uri = new Uri(source, UriKind.RelativeOrAbsolute); - - if (!uri.IsAbsoluteUri || source.StartsWith('/')) - { - // Support for implicit ms-appx resolution - var assetUri = AssetsPathBuilder.BuildAssetUri(Uri.EscapeDataString(source.TrimStart('/')).Replace("%2F", "/")); - uri = new Uri(assetUri, UriKind.RelativeOrAbsolute); - } - - if (Uno.UI.Xaml.XamlFilePathHelper.TryGetMsAppxAssetPath(uri, out var path)) - { - var assetUri = AssetsPathBuilder.BuildAssetUri(path); - uri = new Uri(assetUri, UriKind.RelativeOrAbsolute); - } - - return true; - } - - uri = default; - return false; - } - /// /// Use this to launch the loading of a font before it is actually required to /// minimize loading time and prevent potential flicking. diff --git a/src/Uno.UI/UI/Xaml/FontFamilyLoader.wasm.cs b/src/Uno.UI/UI/Xaml/FontFamilyLoader.wasm.cs index 23bab6ffc77f..0ee14be7924a 100644 --- a/src/Uno.UI/UI/Xaml/FontFamilyLoader.wasm.cs +++ b/src/Uno.UI/UI/Xaml/FontFamilyLoader.wasm.cs @@ -18,7 +18,7 @@ namespace Microsoft.UI.Xaml.Media; /// internal partial class FontFamilyLoader { - private static readonly Dictionary _loaders = new(new FontFamilyComparer()); + private static readonly Dictionary _loaders = new(); private static readonly Dictionary _loadersFromCssName = new(); private readonly FontFamily _fontFamily; @@ -29,12 +29,19 @@ internal partial class FontFamilyLoader public bool IsLoading { get; private set; } + /// + /// Contains the font-face name to use in CSS. + /// + internal string CssFontName { get; private set; } + + internal string? ExternalSource { get; private set; } + /// /// Gets a loader for the specific /// internal static FontFamilyLoader GetLoaderForFontFamily(FontFamily forFamily) { - if (_loaders.TryGetValue(forFamily, out var loader)) + if (_loaders.TryGetValue(forFamily.Source, out var loader)) { // There is already a loader for this font family return loader; @@ -48,13 +55,63 @@ internal static FontFamilyLoader GetLoaderForFontFamily(FontFamily forFamily) private FontFamilyLoader(FontFamily fontFamily) { _fontFamily = fontFamily; + ParseSource(fontFamily.Source); if (this.Log().IsEnabled(LogLevel.Debug)) { this.Log().Debug($"Creating font loader for {fontFamily.Source}"); } - _loaders.Add(fontFamily, this); + _loaders.Add(fontFamily.Source, this); + } + + [MemberNotNull(nameof(CssFontName))] + private void ParseSource(string source) + { + var sourceParts = source.Split('#', 2, StringSplitOptions.RemoveEmptyEntries); + + if (sourceParts.Length > 0) + { + if (TryGetExternalUri(sourceParts[0], out var externalUri) && externalUri is { }) + { + ExternalSource = externalUri.OriginalString; + CssFontName = "font" + ExternalSource.GetHashCode(); + } + else + { + CssFontName = sourceParts[sourceParts.Length == 2 ? 1 : 0]; + } + } + else + { + throw new InvalidOperationException("FontFamily source cannot be empty"); + } + } + + private static bool TryGetExternalUri(string? source, out Uri? uri) + { + if (source is not null && (source.IndexOf('.') > -1 || source.IndexOf('/') > -1)) + { + uri = new Uri(source, UriKind.RelativeOrAbsolute); + + if (!uri.IsAbsoluteUri || source.StartsWith('/')) + { + // Support for implicit ms-appx resolution + var assetUri = AssetsPathBuilder.BuildAssetUri(Uri.EscapeDataString(source.TrimStart('/')).Replace("%2F", "/")); + uri = new Uri(assetUri, UriKind.RelativeOrAbsolute); + } + + if (Uno.UI.Xaml.XamlFilePathHelper.TryGetMsAppxAssetPath(uri, out var path)) + { + var assetUri = AssetsPathBuilder.BuildAssetUri(path); + uri = new Uri(assetUri, UriKind.RelativeOrAbsolute); + } + + return true; + } + + uri = default; + return false; } /// @@ -178,19 +235,19 @@ internal async Task LoadFontAsync() if (this.Log().IsEnabled(LogLevel.Debug)) { - this.Log().Debug($"Loading font: {_fontFamily.Source} ({_fontFamily.CssFontName}/{_fontFamily.ExternalSource}, {_loadersFromCssName.Count} loaders active)"); + this.Log().Debug($"Loading font: {_fontFamily.Source} ({CssFontName}/{ExternalSource}, {_loadersFromCssName.Count} loaders active)"); } IsLoading = true; - _loadersFromCssName.Add(_fontFamily.CssFontName, this); + _loadersFromCssName.Add(CssFontName, this); - if (_fontFamily.ExternalSource is { Length: > 0 }) + if (ExternalSource is { Length: > 0 }) { - NativeMethods.LoadFont(_fontFamily.CssFontName, _fontFamily.ExternalSource); + NativeMethods.LoadFont(CssFontName, ExternalSource); } else { - NativeMethods.ForceFontUsage(_fontFamily.CssFontName); + NativeMethods.ForceFontUsage(CssFontName); } _loadOperation = new TaskCompletionSource(); @@ -200,21 +257,12 @@ internal async Task LoadFontAsync() { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"Failed loading font: {_fontFamily.Source} ({_fontFamily.CssFontName}/{_fontFamily.ExternalSource}, {_loadersFromCssName.Count} loaders active)", e); + this.Log().Error($"Failed loading font: {_fontFamily.Source} ({CssFontName}/{ExternalSource}, {_loadersFromCssName.Count} loaders active)", e); } - NotifyFontLoadFailed(_fontFamily.CssFontName); + NotifyFontLoadFailed(CssFontName); return false; } } - - private class FontFamilyComparer : IEqualityComparer - { - public bool Equals(FontFamily? x, FontFamily? y) - => string.Equals(x!.CssFontName, y!.CssFontName, StringComparison.OrdinalIgnoreCase); - - public int GetHashCode(FontFamily obj) - => obj.CssFontName.GetHashCode(); - } } diff --git a/src/Uno.UI/UI/Xaml/UIElement.TextHelper.wasm.cs b/src/Uno.UI/UI/Xaml/UIElement.TextHelper.wasm.cs index e29af31a30a2..14a53b8f7e72 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.TextHelper.wasm.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.TextHelper.wasm.cs @@ -90,7 +90,7 @@ internal void SetFontFamily(object localValue) { font = FontFamily.Default; } - + // TODO: Maybe introduce CssFontNamePrefix to FontFamily, and use something like $"{font.CssFontNamePrefix}_{FontStyle}_{FontWeight}_{FontStretch}" ? SetStyle("font-family", font.CssFontName); font.RegisterForInvalidateMeasureOnFontLoaded(this);