From ec94bdd36d956dbd77db685cd39f068c9bf2089a Mon Sep 17 00:00:00 2001 From: Zhang Dian <54255897+zdpcdt@users.noreply.github.com> Date: Mon, 18 May 2026 21:16:03 +0800 Subject: [PATCH] Integrate font management for Linux demo (#822) * feat: integrate font management by adding Semi.Avalonia.Demo.Fonts project. * chore: test on ubuntu. * feat: add linux options. * feat: update theme settings and adjust window decorations. * feat: add font to DRM project. * misc: net8.0->net10.0 --- Semi.Avalonia.slnx | 1 + .../Semi.Avalonia.Demo.Android/Application.cs | 3 +- .../AvaloniaAppBuilderExtensions.cs | 16 --------- .../Semi.Avalonia.Demo.Android.csproj | 4 +-- demo/Semi.Avalonia.Demo.Desktop/Program.cs | 34 ++++++++++-------- .../Semi.Avalonia.Demo.Desktop.csproj | 3 +- demo/Semi.Avalonia.Demo.Drm/Program.cs | 18 +++++----- .../Semi.Avalonia.Demo.Drm.csproj | 3 +- .../Assets}/SourceHanSansCN-Bold.otf | Bin .../Assets}/SourceHanSansCN-Regular.otf | Bin .../AvaloniaAppBuilderExtensions.cs | 16 +++++++++ .../Semi.Avalonia.Demo.Fonts.csproj | 16 +++++++++ .../AvaloniaAppBuilderExtensions.cs | 16 --------- demo/Semi.Avalonia.Demo.Web/Program.cs | 3 +- .../Semi.Avalonia.Demo.Web.csproj | 5 +-- demo/Semi.Avalonia.Demo/App.axaml | 1 + demo/Semi.Avalonia.Demo/App.axaml.cs | 30 +++++++++------- .../Semi.Avalonia.Demo.csproj | 2 +- demo/global.json | 5 --- global.json | 2 +- .../Controls/WindowDrawnDecorations.axaml | 14 ++++---- 21 files changed, 101 insertions(+), 91 deletions(-) delete mode 100644 demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs rename demo/{Fonts => Semi.Avalonia.Demo.Fonts/Assets}/SourceHanSansCN-Bold.otf (100%) rename demo/{Fonts => Semi.Avalonia.Demo.Fonts/Assets}/SourceHanSansCN-Regular.otf (100%) create mode 100644 demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs create mode 100644 demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj delete mode 100644 demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs delete mode 100644 demo/global.json diff --git a/Semi.Avalonia.slnx b/Semi.Avalonia.slnx index b1024c6..47a5506 100644 --- a/Semi.Avalonia.slnx +++ b/Semi.Avalonia.slnx @@ -3,6 +3,7 @@ + diff --git a/demo/Semi.Avalonia.Demo.Android/Application.cs b/demo/Semi.Avalonia.Demo.Android/Application.cs index 611e568..fb85aee 100644 --- a/demo/Semi.Avalonia.Demo.Android/Application.cs +++ b/demo/Semi.Avalonia.Demo.Android/Application.cs @@ -2,6 +2,7 @@ using Android.Runtime; using Avalonia; using Avalonia.Android; +using Semi.Avalonia.Demo.Fonts; namespace Semi.Avalonia.Demo.Android; @@ -17,4 +18,4 @@ public class Application : AvaloniaAndroidApplication return base.CustomizeAppBuilder(builder) .WithSourceHanSansCNFont(); } -} \ No newline at end of file +} diff --git a/demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs b/demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs deleted file mode 100644 index ef18895..0000000 --- a/demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Avalonia; -using Avalonia.Media; - -namespace Semi.Avalonia.Demo.Android; - -public static class AvaloniaAppBuilderExtensions -{ - private static string DefaultFontFamily => "avares://Semi.Avalonia.Demo.Android/Assets#Source Han Sans CN"; - - public static AppBuilder WithSourceHanSansCNFont(this AppBuilder builder) => - builder.With(new FontManagerOptions - { - DefaultFamilyName = DefaultFontFamily, - FontFallbacks = [new FontFallback { FontFamily = new FontFamily(DefaultFontFamily) }] - }); -} \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj b/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj index c65aded..ea4cb33 100644 --- a/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj +++ b/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj @@ -21,7 +21,6 @@ - @@ -31,5 +30,6 @@ + - \ No newline at end of file + diff --git a/demo/Semi.Avalonia.Demo.Desktop/Program.cs b/demo/Semi.Avalonia.Demo.Desktop/Program.cs index 8de4d49..c62a2ad 100644 --- a/demo/Semi.Avalonia.Demo.Desktop/Program.cs +++ b/demo/Semi.Avalonia.Demo.Desktop/Program.cs @@ -2,8 +2,10 @@ using Avalonia; using Avalonia.Dialogs; using Avalonia.Media; +using Semi.Avalonia.Demo.Fonts; namespace Semi.Avalonia.Demo.Desktop; +#pragma warning disable CA1416, AVALONIA_X11_CSD, AVALONIA_X11_FORCE_CSD sealed class Program { @@ -11,24 +13,28 @@ sealed class Program // SynchronizationContext-reliant code before AppMain is called: things aren't initialized // yet and stuff might break. [STAThread] - public static void Main(string[] args) => BuildAvaloniaApp() - .With(new FontManagerOptions - { - FontFallbacks = - [ - new FontFallback - { - FontFamily = new FontFamily("Microsoft YaHei") - } - ] - }) - .StartWithClassicDesktopLifetime(args); + public static void Main(string[] args) + { + var appBuilder = BuildAvaloniaApp(); + if (!OperatingSystem.IsLinux()) + appBuilder.With(new FontManagerOptions + { + FontFallbacks = [new FontFallback { FontFamily = new FontFamily("Microsoft YaHei") }] + }); + + appBuilder.StartWithClassicDesktopLifetime(args); + } // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() + { + var appBuilder = AppBuilder.Configure() .UseManagedSystemDialogs() .UsePlatformDetect() .With(new Win32PlatformOptions()) + .With(new X11PlatformOptions { EnableDrawnDecorations = true }) .LogToTrace(); -} \ No newline at end of file + if (OperatingSystem.IsLinux()) appBuilder.WithSourceHanSansCNFont(); + return appBuilder; + } +} diff --git a/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj b/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj index 4e50e58..45a0ea5 100644 --- a/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj +++ b/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj @@ -1,7 +1,7 @@  WinExe - net8.0 + net10.0 enable true ..\Semi.Avalonia.Demo\Assets\irihi.ico @@ -28,5 +28,6 @@ + diff --git a/demo/Semi.Avalonia.Demo.Drm/Program.cs b/demo/Semi.Avalonia.Demo.Drm/Program.cs index c04db70..efce36a 100644 --- a/demo/Semi.Avalonia.Demo.Drm/Program.cs +++ b/demo/Semi.Avalonia.Demo.Drm/Program.cs @@ -4,8 +4,10 @@ using System.Linq; using System.Threading; using Avalonia; using Avalonia.Dialogs; +using Semi.Avalonia.Demo.Fonts; namespace Semi.Avalonia.Demo.Drm; +#pragma warning disable CA1416, AVALONIA_X11_CSD, AVALONIA_X11_FORCE_CSD sealed class Program { @@ -40,17 +42,17 @@ sealed class Program => AppBuilder.Configure() .UseManagedSystemDialogs() .UsePlatformDetect() - .With(new Win32PlatformOptions()) + .With(new X11PlatformOptions { EnableDrawnDecorations = true }) + .WithSourceHanSansCNFont() .LogToTrace(); private static void SilenceConsole() { new Thread(() => - { - Console.CursorVisible = false; - while (true) - Console.ReadKey(true); - }) - { IsBackground = true }.Start(); + { + Console.CursorVisible = false; + while (true) + Console.ReadKey(true); + }) { IsBackground = true }.Start(); } -} \ No newline at end of file +} diff --git a/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj b/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj index 53b15ad..e09b1ee 100644 --- a/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj +++ b/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj @@ -1,7 +1,7 @@  WinExe - net8.0 + net10.0 enable true ..\Semi.Avalonia.Demo\Assets\irihi.ico @@ -29,5 +29,6 @@ + diff --git a/demo/Fonts/SourceHanSansCN-Bold.otf b/demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Bold.otf similarity index 100% rename from demo/Fonts/SourceHanSansCN-Bold.otf rename to demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Bold.otf diff --git a/demo/Fonts/SourceHanSansCN-Regular.otf b/demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Regular.otf similarity index 100% rename from demo/Fonts/SourceHanSansCN-Regular.otf rename to demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Regular.otf diff --git a/demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs b/demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs new file mode 100644 index 0000000..3a989d3 --- /dev/null +++ b/demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs @@ -0,0 +1,16 @@ +using Avalonia; +using Avalonia.Media; + +namespace Semi.Avalonia.Demo.Fonts; + +public static class AvaloniaAppBuilderExtensions +{ + public static AppBuilder WithSourceHanSansCNFont(this AppBuilder builder) + { + const string uri = "avares://Semi.Avalonia.Demo.Fonts/Assets#Source Han Sans CN"; + return builder.With(new FontManagerOptions + { + DefaultFamilyName = uri, FontFallbacks = [new FontFallback { FontFamily = new FontFamily(uri) }] + }); + } +} diff --git a/demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj b/demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj new file mode 100644 index 0000000..2878568 --- /dev/null +++ b/demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + + + + + + + + + + diff --git a/demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs b/demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs deleted file mode 100644 index 29386d5..0000000 --- a/demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Avalonia; -using Avalonia.Media; - -namespace Semi.Avalonia.Demo.Web; - -public static class AvaloniaAppBuilderExtensions -{ - private static string DefaultFontFamily => "avares://Semi.Avalonia.Demo.Web/Assets#Source Han Sans CN"; - - public static AppBuilder WithSourceHanSansCNFont(this AppBuilder builder) => - builder.With(new FontManagerOptions - { - DefaultFamilyName = DefaultFontFamily, - FontFallbacks = [new FontFallback { FontFamily = new FontFamily(DefaultFontFamily) }] - }); -} \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo.Web/Program.cs b/demo/Semi.Avalonia.Demo.Web/Program.cs index 62d4e94..5e70213 100644 --- a/demo/Semi.Avalonia.Demo.Web/Program.cs +++ b/demo/Semi.Avalonia.Demo.Web/Program.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Avalonia; using Avalonia.Browser; +using Semi.Avalonia.Demo.Fonts; [assembly: SupportedOSPlatform("browser")] @@ -15,4 +16,4 @@ internal sealed partial class Program public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure(); -} \ No newline at end of file +} diff --git a/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj b/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj index f52b4a3..96efbd8 100644 --- a/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj +++ b/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj @@ -6,15 +6,12 @@ enable - - - - + diff --git a/demo/Semi.Avalonia.Demo/App.axaml b/demo/Semi.Avalonia.Demo/App.axaml index cd3224a..cf66547 100644 --- a/demo/Semi.Avalonia.Demo/App.axaml +++ b/demo/Semi.Avalonia.Demo/App.axaml @@ -5,6 +5,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:semi="https://irihi.tech/semi" xmlns:vm="clr-namespace:Semi.Avalonia.Demo.ViewModels" + RequestedThemeVariant="Default" x:DataType="vm:ApplicationViewModel"> diff --git a/demo/Semi.Avalonia.Demo/App.axaml.cs b/demo/Semi.Avalonia.Demo/App.axaml.cs index b617ffe..d3255ed 100644 --- a/demo/Semi.Avalonia.Demo/App.axaml.cs +++ b/demo/Semi.Avalonia.Demo/App.axaml.cs @@ -1,6 +1,6 @@ +using System; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Data.Core.Plugins; using Avalonia.Markup.Xaml; using Semi.Avalonia.Demo.ViewModels; using Semi.Avalonia.Demo.Views; @@ -15,25 +15,29 @@ public partial class App : Application #if DEBUG this.AttachDeveloperTools(); #endif - this.DataContext = new ApplicationViewModel(); + DataContext = new ApplicationViewModel(); + if (OperatingSystem.IsLinux()) + { + Resources.Add("DefaultFontFamily", null); + } } public override void OnFrameworkInitializationCompleted() { - switch (ApplicationLifetime) + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - case IClassicDesktopStyleApplicationLifetime desktop: - // Line below is needed to remove Avalonia data validation. - // Without this line you will get duplicate validations from both Avalonia and CT - // BindingPlugins.DataValidators.RemoveAt(0); - desktop.MainWindow = new MainWindow(); - break; - case ISingleViewApplicationLifetime singleView: - singleView.MainView = new MainView(); - break; + desktop.MainWindow = new MainWindow { DataContext = new MainViewModel() }; + } + else if (ApplicationLifetime is IActivityApplicationLifetime applicationLifetime) + { + applicationLifetime.MainViewFactory = () => new MainView { DataContext = new MainViewModel() }; + } + else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform) + { + singleViewPlatform.MainView = new MainView { DataContext = new MainViewModel() }; } this.RegisterFollowSystemTheme(); base.OnFrameworkInitializationCompleted(); } -} \ No newline at end of file +} diff --git a/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj b/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj index ab804eb..12bb3c5 100644 --- a/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj +++ b/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj @@ -1,6 +1,6 @@  - net8.0 + net10.0 enable latest diff --git a/demo/global.json b/demo/global.json deleted file mode 100644 index b365003..0000000 --- a/demo/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "8.0" - } -} diff --git a/global.json b/global.json index dad2db5..a11f48e 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.0", + "version": "10.0.0", "rollForward": "latestMajor", "allowPrerelease": true } diff --git a/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml b/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml index b3d090f..997fc20 100644 --- a/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml +++ b/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml @@ -46,8 +46,8 @@ - - + + @@ -189,16 +189,16 @@ @@ -214,4 +214,4 @@ - \ No newline at end of file +