diff --git a/src/Uno.UI/Controls/UIStringAttributesHelper.iOS.cs b/src/Uno.UI/Controls/UIStringAttributesHelper.iOS.cs index 8498f32eff19..5cc96219064e 100644 --- a/src/Uno.UI/Controls/UIStringAttributesHelper.iOS.cs +++ b/src/Uno.UI/Controls/UIStringAttributesHelper.iOS.cs @@ -6,6 +6,7 @@ using Microsoft.UI.Xaml.Documents; using UIKit; using Uno.Extensions; +using Uno.UI.Xaml; namespace Uno.UI { @@ -15,6 +16,7 @@ private static Func< ( FontWeight fontWeight, FontStyle fontStyle, + FontStretch fontStretch, FontFamily fontFamily, Brush foreground, double fontSize, @@ -35,6 +37,7 @@ static UIStringAttributesHelper() internal static UIStringAttributes GetAttributes( FontWeight fontWeight, FontStyle fontStyle, + FontStretch fontStretch, FontFamily fontFamily, Brush foreground, double fontSize, @@ -43,12 +46,13 @@ internal static UIStringAttributes GetAttributes( TextDecorations textDecorations ) { - return _getAttributes((fontWeight, fontStyle, fontFamily, foreground, fontSize, characterSpacing, baseLineAlignment, textDecorations, UIFont.PreferredBody.FontDescriptor.FontAttributes.Size)); + return _getAttributes((fontWeight, fontStyle, fontStretch, fontFamily, foreground, fontSize, characterSpacing, baseLineAlignment, textDecorations, UIFont.PreferredBody.FontDescriptor.FontAttributes.Size)); } private static UIStringAttributes InternalGetAttributes(( FontWeight fontWeight, FontStyle fontStyle, + FontStretch fontStretch, FontFamily fontFamily, Brush foreground, double fontSize, @@ -74,7 +78,7 @@ private static UIStringAttributes InternalGetAttributes(( } } - var font = FontHelper.TryGetFont((float)tuple.fontSize, tuple.fontWeight, tuple.fontStyle, tuple.fontFamily, tuple.preferredBodyFontSize); + var font = FontHelper.TryGetFont(new((float)tuple.fontSize, tuple.fontWeight, tuple.fontStyle, tuple.fontStretch), tuple.fontFamily, tuple.preferredBodyFontSize); var attributes = new UIStringAttributes() { // TODO: Handle other brushes. diff --git a/src/Uno.UI/UI/Xaml/Documents/InlineExtensions.iOS.cs b/src/Uno.UI/UI/Xaml/Documents/InlineExtensions.iOS.cs index 27a7c6194ba7..95547c114e95 100644 --- a/src/Uno.UI/UI/Xaml/Documents/InlineExtensions.iOS.cs +++ b/src/Uno.UI/UI/Xaml/Documents/InlineExtensions.iOS.cs @@ -13,6 +13,7 @@ internal static UIStringAttributes GetAttributes(this Inline inline) return Uno.UI.UIStringAttributesHelper.GetAttributes( inline.FontWeight, inline.FontStyle, + inline.FontStretch, inline.FontFamily, inline.Foreground, inline.FontSize, diff --git a/src/Uno.UI/UI/Xaml/Extensions/FontHelper.iOS.cs b/src/Uno.UI/UI/Xaml/Extensions/FontHelper.iOS.cs index 776527b1cb18..3b70abac73de 100644 --- a/src/Uno.UI/UI/Xaml/Extensions/FontHelper.iOS.cs +++ b/src/Uno.UI/UI/Xaml/Extensions/FontHelper.iOS.cs @@ -115,27 +115,25 @@ private static nfloat GetScaledFontSize(nfloat size, nfloat? basePreferredSize) return ApplyStyle( UIFont.SystemFontOfSize(properties.Size, properties.Weight.ToUIFontWeight()), - properties.Size, - properties.Style); + properties); } #region Load Custom Font - private static string TryAdjustFromManifest(string source, FontProperties properties) + private static string TryAdjustFromManifest(NSUrl manifestUrl, FontProperties properties) { - var manifestPath = source + ".manifest"; - manifestPath = AssetsHelper.FindAssetFile(manifestPath); + var fontData = NSData.FromUrl(manifestUrl); - if (manifestPath is not null) - { - using var jsonStream = ContextHelper.Current.Assets!.Open(manifestPath); - var fontStyle = (style & TypefaceStyle.Italic) != 0 ? FontStyle.Italic : FontStyle.Normal; - var familyName = FontManifestHelpers.GetFamilyNameFromManifest(jsonStream, properties.Weight, properties.Style, properties.Stretch); - familyName = familyName.TrimStart("ms-appx://", ignoreCase: true); - return encodePath ? AndroidResourceNameEncoder.EncodeFileSystemPath(familyName, prefix: "") : familyName; - } + using var jsonStream = new MemoryStream(fontData.ToArray()); + var familyName = FontManifestHelpers.GetFamilyNameFromManifest( + jsonStream, + properties.Weight, + properties.Style, + properties.Stretch); + + familyName = familyName.TrimStart("ms-appx://", ignoreCase: true); - return source; + return familyName; } private static UIFont? GetCustomFont(string fontPath, FontProperties fontProperties) @@ -149,7 +147,31 @@ private static string TryAdjustFromManifest(string source, FontProperties proper UIFont? font; //In Windows we define FontFamily with the path to the font file followed by the font family name, separated by a # var indexOfHash = fontPath.IndexOf('#'); + + var actualFontPath = ""; + bool testFontFamilyName = false; + bool skipAdjustments = false; if (indexOfHash > 0 && indexOfHash < fontPath.Length - 1) + { + actualFontPath = fontPath.Substring(0, indexOfHash); + } + else + { + actualFontPath = fontPath; + } + + if (GetFontManifestUrl(actualFontPath) is { } manifestUrl && + TryAdjustFromManifest(manifestUrl, fontProperties) is { } adjustedPath) + { + fontPath = adjustedPath; + skipAdjustments = true; + } + else + { + testFontFamilyName = true; + } + + if (testFontFamilyName && indexOfHash > 0 && indexOfHash < fontPath.Length - 1) { font = GetFontFromFamilyName(fontProperties.Size, fontPath.Substring(indexOfHash + 1)) ?? GetFontFromFile(fontProperties.Size, fontPath.Substring(0, indexOfHash)); @@ -164,30 +186,44 @@ private static string TryAdjustFromManifest(string source, FontProperties proper font = GetDefaultFont(fontProperties); } - if (font is not null) + if (font is not null && !skipAdjustments) { - font = ApplyFontProperties(font, fontProperties); + //font = ApplyFontProperties(font, fontProperties); } return font; } + private static NSUrl? GetFontManifestUrl(string actualFontPath) + { + var fileName = actualFontPath; + var fileExtension = "manifest"; + + var url = NSBundle + .MainBundle + .GetUrlForResource( + name: Path.GetFileName(fileName), + fileExtension: fileExtension, + subdirectory: Path.GetDirectoryName(actualFontPath)); + + return url; + } + private static UIFont ApplyFontProperties(UIFont font, FontProperties fontProperties) { - font = ApplyWeight(font, size, fontWeight); - font = ApplyStyle(font, size, fontStyle); - font = ApplyStretch(font, size, FontStretch); + font = ApplyWeight(font, fontProperties); + font = ApplyStyle(font, fontProperties); return font; } - private static UIFont ApplyWeight(UIFont font, nfloat size, FontWeight fontWeight) + private static UIFont ApplyWeight(UIFont font, FontProperties fontProperties) { - if (fontWeight.Weight == FontWeights.Bold.Weight && !font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Bold)) + if (fontProperties.Weight.Weight == FontWeights.Bold.Weight && !font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Bold)) { var descriptor = font.FontDescriptor.CreateWithTraits(font.FontDescriptor.SymbolicTraits | UIFontDescriptorSymbolicTraits.Bold); if (descriptor != null) { - font = UIFont.FromDescriptor(descriptor, size); + font = UIFont.FromDescriptor(descriptor, fontProperties.Size); } else { @@ -195,14 +231,14 @@ private static UIFont ApplyWeight(UIFont font, nfloat size, FontWeight fontWeigh } } else if ( - fontWeight.Weight != FontWeights.SemiBold.Weight && // For some reason, when we load a Semibold font, we must keep the native Bold flag. - fontWeight.Weight < FontWeights.Bold.Weight && + fontProperties.Weight.Weight != FontWeights.SemiBold.Weight && // For some reason, when we load a Semibold font, we must keep the native Bold flag. + fontProperties.Weight.Weight < FontWeights.Bold.Weight && font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Bold)) { var descriptor = font.FontDescriptor.CreateWithTraits(font.FontDescriptor.SymbolicTraits & ~UIFontDescriptorSymbolicTraits.Bold); if (descriptor != null) { - font = UIFont.FromDescriptor(descriptor, size); + font = UIFont.FromDescriptor(descriptor, fontProperties.Size); } else { @@ -213,26 +249,26 @@ private static UIFont ApplyWeight(UIFont font, nfloat size, FontWeight fontWeigh return font; } - private static UIFont ApplyStyle(UIFont font, nfloat size, FontStyle fontStyle) + private static UIFont ApplyStyle(UIFont font, FontProperties fontProperties) { - if (fontStyle == FontStyle.Italic && !font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic)) + if (fontProperties.Style == FontStyle.Italic && !font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic)) { var descriptor = font.FontDescriptor.CreateWithTraits(font.FontDescriptor.SymbolicTraits | UIFontDescriptorSymbolicTraits.Italic); if (descriptor != null) { - font = UIFont.FromDescriptor(descriptor, size); + font = UIFont.FromDescriptor(descriptor, fontProperties.Size); } else { typeof(FontHelper).Log().Error($"Can't apply Italic on font \"{font.Name}\". Make sure the font supports it or use another FontFamily."); } } - else if (fontStyle == FontStyle.Normal && font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic)) + else if (fontProperties.Style == FontStyle.Normal && font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic)) { var descriptor = font.FontDescriptor.CreateWithTraits(font.FontDescriptor.SymbolicTraits & ~UIFontDescriptorSymbolicTraits.Italic); if (descriptor != null) { - font = UIFont.FromDescriptor(descriptor, size); + font = UIFont.FromDescriptor(descriptor, fontProperties.Size); } else {