Skip to content

Commit 88be67d

Browse files
committed
fix(fonts): Adjust font loading for ms-appx resources from assemblies
- Font loading now uses common ms-appx path building properly to allow for arbitrary font loading. - Enables dynamic inclusion of font files on apple targets
1 parent 6cf8e3b commit 88be67d

File tree

18 files changed

+229
-80
lines changed

18 files changed

+229
-80
lines changed

src/SourceGenerators/SourceGeneratorHelpers/Helpers/Nullable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace System.Diagnostics.CodeAnalysis
1010
{
11-
#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48 || (!NET6_0_OR_GREATER && (__IOS__ || __ANDROID__ || __MACOS__))
11+
#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48
1212
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
1313
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
1414
#if SYSTEM_PRIVATE_CORELIB

src/Uno.Foundation/Uno.Core.Extensions/Uno.Core.Extensions/StringExtensions.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using System.Globalization;
2222
using System.Text;
2323
using System.Text.RegularExpressions;
24+
using System.Diagnostics.CodeAnalysis;
2425

2526
#endregion
2627

@@ -87,22 +88,23 @@ public static LineSplitEnumerator SplitLines(this ReadOnlySpan<char> instance)
8788
return new LineSplitEnumerator(instance);
8889
}
8990

90-
public static bool IsNullOrEmpty(this string instance)
91+
92+
public static bool IsNullOrEmpty([NotNullWhen(false)] this string instance)
9193
{
9294
return string.IsNullOrEmpty(instance);
9395
}
94-
95-
public static bool IsNullOrWhiteSpace(this string instance)
96+
97+
public static bool IsNullOrWhiteSpace([NotNullWhen(false)] this string instance)
9698
{
9799
return string.IsNullOrWhiteSpace(instance);
98100
}
99101

100-
public static bool HasValue(this string instance)
102+
public static bool HasValue([NotNullWhen(true)] this string instance)
101103
{
102104
return !string.IsNullOrWhiteSpace(instance);
103105
}
104106

105-
public static bool HasValueTrimmed(this string instance)
107+
public static bool HasValueTrimmed([NotNullWhen(true)] this string instance)
106108
{
107109
return !string.IsNullOrWhiteSpace(instance);
108110
}

src/Uno.Foundation/Uno.Foundation.Reference.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
</EmbeddedResource>
4242
</ItemGroup>
4343

44+
<ItemGroup>
45+
<Compile Include="..\SourceGenerators\SourceGeneratorHelpers\Helpers\Nullable.cs" Link="Extensions\Nullable.cs" />
46+
</ItemGroup>
47+
4448
<ItemGroup>
4549
<UpToDateCheckInput Include="**\*.cs" Exclude="bin\**\*.cs;obj\**\*.cs;" Visible="False" />
4650
</ItemGroup>

src/Uno.Foundation/Uno.Foundation.Skia.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
<ProjectReference Include="..\Uno.Foundation.Logging\Uno.Foundation.Logging.csproj" />
3232
</ItemGroup>
3333

34+
<ItemGroup>
35+
<Compile Include="..\SourceGenerators\SourceGeneratorHelpers\Helpers\Nullable.cs" Link="Extensions\Nullable.cs" />
36+
</ItemGroup>
37+
3438
<Import Project="..\Uno.CrossTargetting.props" />
3539
<Import Project="Uno.Core.Extensions\Uno.Core.Extensions.props" />
3640

src/Uno.Foundation/Uno.Foundation.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
<UpToDateCheckInput Include="**\*.cs" Exclude="bin\**\*.cs;obj\**\*.cs;" Visible="False" />
3939
</ItemGroup>
4040

41+
<ItemGroup>
42+
<Compile Include="..\SourceGenerators\SourceGeneratorHelpers\Helpers\Nullable.cs" Link="Extensions\Nullable.cs" />
43+
</ItemGroup>
44+
4145
<Import Project="..\Uno.CrossTargetting.props" />
4246
<Import Project="Uno.Core.Extensions\Uno.Core.Extensions.props" />
4347
</Project>

src/Uno.UI.RemoteControl/Uno.UI.RemoteControl.Reference.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@
3333
<UpToDateCheckInput Include="**\*.cs" Exclude="bin\**\*.cs;obj\**\*.cs;" />
3434
</ItemGroup>
3535

36-
<ItemGroup>
37-
<Compile Include="..\SourceGenerators\SourceGeneratorHelpers\Helpers\Nullable.cs" Link="Helpers\Nullable.cs" />
38-
</ItemGroup>
39-
4036
<ItemGroup>
4137
<Content Include="buildTransitive\Uno.UI.RemoteControl.targets">
4238
<PackagePath>build</PackagePath>

src/Uno.UI.RemoteControl/Uno.UI.RemoteControl.Skia.csproj

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
4+
<TargetFrameworks>netstandard2.0</TargetFrameworks>
55
</PropertyGroup>
66

77
<PropertyGroup Condition="'$(MSBuildRuntimeType)'=='Core' or '$(IsRunningInsideVisualStudio)'=='true'">
@@ -36,10 +36,6 @@
3636
<UpToDateCheckInput Include="**\*.cs" Exclude="bin\**\*.cs;obj\**\*.cs;" />
3737
</ItemGroup>
3838

39-
<ItemGroup>
40-
<Compile Include="..\SourceGenerators\SourceGeneratorHelpers\Helpers\Nullable.cs" Link="Helpers\Nullable.cs" />
41-
</ItemGroup>
42-
4339
<ItemGroup>
4440
<EmbeddedResource Include="LinkerDefinition.Wasm.xml">
4541
<LogicalName>$(AssemblyName).xml</LogicalName>

src/Uno.UI.RemoteControl/Uno.UI.RemoteControl.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@
2727
<UpToDateCheckInput Include="**\*.cs" Exclude="bin\**\*.cs;obj\**\*.cs;" />
2828
</ItemGroup>
2929

30-
<ItemGroup>
31-
<Compile Include="..\SourceGenerators\SourceGeneratorHelpers\Helpers\Nullable.cs" Link="Helpers\Nullable.cs" />
32-
</ItemGroup>
33-
3430
<ItemGroup Condition="'$(TargetFramework)'!='netstandard2.0'">
3531
<EmbeddedResource Include="LinkerDefinition.Xamarin.xml">
3632
<LogicalName>$(AssemblyName).xml</LogicalName>

src/Uno.UI.RemoteControl/Uno.UI.RemoteControl.netcoremobile.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@
3434
<UpToDateCheckInput Include="**\*.cs" Exclude="bin\**\*.cs;obj\**\*.cs;" />
3535
</ItemGroup>
3636

37-
<ItemGroup>
38-
<Compile Include="..\SourceGenerators\SourceGeneratorHelpers\Helpers\Nullable.cs" Link="Helpers\Nullable.cs" />
39-
</ItemGroup>
40-
4137
<ItemGroup Condition="'$(TargetFramework)'!='netstandard2.0'">
4238
<EmbeddedResource Include="LinkerDefinition.Xamarin.xml">
4339
<LogicalName>$(AssemblyName).xml</LogicalName>
Binary file not shown.

src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_TextBlock.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,35 @@ public void When_Inlines_XamlRoot()
109109
Assert.AreEqual(SUT.XamlRoot, inline.XamlRoot);
110110
}
111111
}
112+
113+
[TestMethod]
114+
[RunsOnUIThread]
115+
public async Task When_FontFamily_In_Separate_Assembly()
116+
{
117+
var SUT = new TextBlock { Text = "\xE102\xE102\xE102\xE102\xE102" };
118+
WindowHelper.WindowContent = SUT;
119+
await WindowHelper.WaitForIdle();
120+
121+
var size = new Size(1000, 1000);
122+
SUT.Measure(size);
123+
124+
var originalSize = SUT.DesiredSize;
125+
126+
Assert.AreNotEqual(0, SUT.DesiredSize.Width);
127+
Assert.AreNotEqual(0, SUT.DesiredSize.Height);
128+
129+
SUT.FontFamily = new Windows.UI.Xaml.Media.FontFamily("ms-appx://Uno.UI.RuntimeTests/Assets/Fonts/uno-fluentui-assets-v2.ttf");
130+
131+
int counter = 3;
132+
133+
do
134+
{
135+
await WindowHelper.WaitForIdle();
136+
await Task.Delay(100);
137+
}
138+
while (SUT.DesiredSize == originalSize && counter-- > 0);
139+
140+
Assert.AreNotEqual(originalSize, SUT.DesiredSize);
141+
}
112142
}
113143
}

src/Uno.UI.RuntimeTests/Uno.UI.RuntimeTests.Wasm.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,8 @@
101101

102102
<UpToDateCheckInput Include="$(PlatformItemsBasePath)**\*.xaml" Exclude="$(PlatformItemsBasePath)bin\**\*.xaml;$(PlatformItemsBasePath)obj\**\*.xaml" />
103103
</ItemGroup>
104+
105+
<ItemGroup>
106+
<None Remove="Assets\Fonts\uno-fluentui-assets-v2.ttf" />
107+
</ItemGroup>
104108
</Project>

src/Uno.UI/Controls/NSFontHelper.macOS.cs

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -199,32 +199,64 @@ private static NSFont ApplyStyle(NSFont font, nfloat size, FontStyle fontStyle)
199199
private static NSFont? GetFontFromFile(nfloat size, string file)
200200
{
201201
var fileName = Path.GetFileNameWithoutExtension(file);
202-
var fileExtension = Path.GetExtension(file)?.Replace(".", "") ?? "";
203-
204-
var url = NSBundle
205-
.MainBundle
206-
.GetUrlForResource(
207-
name: fileName,
208-
fileExtension: fileExtension,
209-
subdirectory: "Fonts"
210-
);
211-
212-
if (url == null)
202+
var fileExtension = Path.GetExtension(file)!.Substring(1);
203+
204+
var url = file.Contains("/")
205+
206+
// Search the file using the appropriate subdirectory
207+
? NSBundle
208+
.MainBundle
209+
.GetUrlForResource(
210+
name: fileName,
211+
fileExtension: fileExtension,
212+
subdirectory: Path.GetDirectoryName(file))
213+
214+
// Legacy behavior when fonts were located in the fonts folder.
215+
: NSBundle
216+
.MainBundle
217+
.GetUrlForResource(
218+
name: fileName,
219+
fileExtension: fileExtension,
220+
subdirectory: "Fonts");
221+
222+
if (url is null)
213223
{
224+
if (typeof(NSFontHelper).Log().IsEnabled(LogLevel.Debug))
225+
{
226+
typeof(NSFontHelper).Log().Debug($"Unable to find font in bundle using {file}");
227+
}
228+
214229
return null;
215230
}
216231

217232
var fontData = NSData.FromUrl(url);
218-
if (fontData == null)
233+
if (fontData is null)
219234
{
235+
if (typeof(NSFontHelper).Log().IsEnabled(LogLevel.Debug))
236+
{
237+
typeof(NSFontHelper).Log().Debug($"Unable to load font in bundle using {url}");
238+
}
239+
220240
return null;
221241
}
222242

223243
//iOS loads NSFonts based on the PostScriptName of the font file
224244
using var fontProvider = new CGDataProvider(fontData);
225-
using var font = CGFont.CreateFromProvider(fontProvider);
245+
var font = CGFont.CreateFromProvider(fontProvider);
226246

227-
return font != null ? NSFont.FromFontName(font.PostScriptName, size) : null;
247+
if (font is not null && CoreText.CTFontManager.RegisterGraphicsFont(font, out var error))
248+
{
249+
return NSFont.FromFontName(font.PostScriptName, size);
250+
}
251+
else
252+
{
253+
if (typeof(NSFontHelper).Log().IsEnabled(LogLevel.Debug))
254+
{
255+
typeof(NSFontHelper).Log().Debug($"Unable to register font from {file}");
256+
}
257+
258+
return null;
259+
}
228260
}
229261
#endregion
230262

0 commit comments

Comments
 (0)