☰
Windows-universal-samples 之 XamlCloudFontIntegration:XAML 集成 DirectWrite 可下载字体的实践指南
2026/9/25 5:26:26 网站建设 项目流程
  • 示例工程

【免费下载链接】Windows-universal-samples

API samples for the Universal Windows Platform.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-universal-samples
点击查看免费下载

导读

本文围绕 Samples/XamlCloudFontIntegration 示例,深入讲解 Windows 10 引入的 DirectWrite 可下载字体(Downloadable Fonts)机制如何在 XAML 应用中开箱即用:开发者无需任何特殊 API 或标记,仅需像平时一样为文本元素设置 Windows 字体,系统便会在字体缺失时自动从微软服务下载并按需缓存。读完本文,你将掌握该机制的运行原理、三个文档场景的源码实现、缓存清理脚本的用法,以及构建与运行该示例的完整步骤。

示例概览:一个展示"云端字体"的 UWP 应用

该示例的核心价值在于演示"可下载字体机制已被直接集成进 XAML"这一事实。正如 README.md 所述,应用只需使用 Windows 字体格式化 XAML 文本元素,即可自动获得字体下载能力,无需任何特殊 API 或标记。

从仓库结构看,示例提供 C#(cs/)与 C++/CX(cpp/)两套实现,每套均包含 5 个场景页面。在 C# 侧,场景列表由 SampleConfiguration.cs 注册:

public const string FEATURE_NAME = "XAML Integration of DirectWrite Downloadable Fonts"; List<Scenario> scenarios = new List<Scenario> { new Scenario() { Title="Using this sample app", ClassType=typeof(Scenario_SampleOverview)}, new Scenario() { Title="Downloadable fonts overview", ClassType=typeof(Scenario_CloudFontOverview)}, new Scenario() { Title="Document 1", ClassType=typeof(Scenario_Document1)}, new Scenario() { Title="Document 2", ClassType=typeof(Scenario_Document2)}, new Scenario() { Title="Document 3", ClassType=typeof(Scenario_Document3)} };

5 个场景分工明确:前两个提供使用引导与机制说明,后三个分别用不同字体模拟加载三份"文档",用于实际体验按需下载行为。

可下载字体机制的核心原理

机制来源:XAML 之下的 DirectWrite

DirectWrite 是 DirectX 图形平台的一部分,XAML 依赖它完成文本与图形的显示。Windows 10 为 DirectWrite 增加了新能力:允许应用使用设备上未安装的字体格式化文本内容,并在文本显示时自动从微软服务下载该字体。这一能力直接集成在 XAML 层,XAML 开发者无需编写任何特殊代码。

运行时行为:回退字体 → 自动刷新

Scenario_CloudFontOverview.xaml 对机制行为给出了权威描述,可归纳为以下几点:

  1. 先回退、后刷新:内容加载时,XAML 先用回退字体(fallback fonts)显示文本;短暂延迟后,XAML 自动刷新视图,改用请求的字体显示内容。
  2. 系统级缓存:字体数据会被本地缓存,且缓存跨应用共享——即使某个应用首次使用某字体,它可能早已存在于缓存中,从而跳过回退阶段。若字体长时间未使用,缓存可能被清除,下次使用时会再次触发下载。
  3. 大字体按需分段下载:某些字体体积很大(尤其是中文、日文、韩文字体),DirectWrite 只下载足以显示当前内容的字体片段;当后续内容包含之前未出现的字符时,再补充下载其余片段。
  4. 网络依赖与流量提示:无网络连接时,内容将以回退字体或先前已下载的片段显示;在按流量计费(metered)连接上使用该机制会产生数据流量,因此静态 UI 应只使用在所有 Windows 10 设备上保证本地可用的推荐字体。

三个文档场景:源码级剖析

三个文档场景的文件分别为Scenario_Document1.*、Scenario_Document2.*、Scenario_Document3.*。它们结构一致,差别仅在于所选字体与正文语言,用于展示不同脚本/字体组合的下载行为。

字体通过代码在运行时设置

一个关键设计是:字体格式化在页面加载时以编程方式应用,而非直接写在 XAML 标记中。这样做的原因(源码注释中已明确说明)是:如果字体写在 XAML 里,仅凭 Visual Studio 的 XAML 设计器查看文件就会触发字体数据下载,从而破坏"运行时体验下载行为"的演示目的。参见 Scenario_Document1.xaml 中的注释:

In order to better simulate runtime behavior in this sample, font formatting will be set in code when the page is loaded. Otherwise, if it were set here, the font data would have already been downloaded just by viewing this file in Visual Studio with the Xaml designer.

C# 实现:设置 Page.FontFamily

三个场景的 C# 实现极其简洁,均在Page_Loaded事件中为整个页面设置FontFamily,格式化会作用于页面上所有未显式设置FontFamily的内容元素:

// Scenario_Document1.xaml.cs:Neue Haas Grotesk Text Pro(拉丁文本,Lorem ipsum) this.FontFamily = new Windows.UI.Xaml.Media.FontFamily("Neue Haas Grotesk Text Pro"); // Scenario_Document2.xaml.cs:FangSong(仿宋) this.FontFamily = new Windows.UI.Xaml.Media.FontFamily("FangSong"); // Scenario_Document3.xaml.cs:Kokila this.FontFamily = new Windows.UI.Xaml.Media.FontFamily("Kokila");

对应文件:Scenario_Document1.xaml.cs、Scenario_Document2.xaml.cs、Scenario_Document3.xaml.cs。

C++/CX 实现:同样的思路,不同的语法

C++/CX 版本在Page_Loaded中通过ref new创建FontFamily对象,逻辑完全一致:

// Scenario_Document1.xaml.cpp:Neue Haas Grotesk Text Pro this->FontFamily = ref new Windows::UI::Xaml::Media::FontFamily("Neue Haas Grotesk Text Pro"); // Scenario_Document2.xaml.cpp:FangSong this->FontFamily = ref new Windows::UI::Xaml::Media::FontFamily("FangSong");

对应文件:Scenario_Document1.xaml.cpp、Scenario_Document2.xaml.cpp(Scenario_Document3的 C++ 版本与之同理)。

页面 XAML 布局

每个文档页的 XAML 布局相似(见 Scenario_Document1.xaml):通过Grid.Resources中的隐式Style统一设置TextBlock的TextWrapping="Wrap"、Margin与FontSize="20";正文放在带滚动能力的ScrollViewer中,便于容纳大段文本。页面在Loaded="Page_Loaded"时触发字体设置。

三个文档的对照关系如下:

场景文件字体(FontFamily)正文内容设计意图
Scenario_Document1.*Neue Haas Grotesk Text ProLorem ipsum(拉丁文)演示拉丁字体按需下载
Scenario_Document2.*FangSong(仿宋)中文字符内容演示中文字体按需下载
Scenario_Document3.*Kokila相应语言内容演示其他字体按需下载

重置机制:ClearDownloadableFontCache.ps1

为什么要重置缓存

一旦某个文档被显示,其字体便会缓存在设备本地。若要反复体验"字体未缓存时首次加载"的场景,必须先清空缓存。示例的 Scenario_SampleOverview.xaml 给出了完整操作步骤。该脚本虽不属于示例项目本身,却是演示与调试该机制的重要工具。

脚本实现解析

cpp/ClearDownloadableFontCache.ps1 与 cs/ClearDownloadableFontCache.ps1 内容一致,其核心逻辑如下:

# 1. 校验管理员权限 $Identity = [Security.Principal.WindowsIdentity]::GetCurrent() $Principal = [Security.Principal.WindowsPrincipal]$Identity if (!$Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Warning 'You must run this script as administrator.' Exit } # 2. 停止 FontCache 服务 → 删除缓存目录中的 .bin 文件 → 重启服务 $FontCachePath = "$env:WinDir\ServiceProfiles\LocalService\AppData\Local\FontCache\Fonts" if (Test-Path $FontCachePath) { Get-Service 'FontCache' | Stop-Service Get-ChildItem -Path $FontCachePath -Filter *.bin | Remove-Item Get-Service 'FontCache' | Start-Service }

要点说明:

  • 必须以管理员身份运行:脚本首先通过WindowsPrincipal.IsInRole检查当前进程是否具有管理员权限,否则输出警告并退出。
  • 操作的是系统 FontCache 服务:字体缓存位于%WinDir%\ServiceProfiles\LocalService\AppData\Local\FontCache\Fonts,脚本先停止FontCache服务、删除目录下所有.bin缓存文件、再重启服务,从而完全重置下载字体状态。
  • 适用于 Windows 桌面系统:示例文档明确说明,此重置流程在 Windows 桌面系统上可行。

推荐命令行用法

在管理员权限的cmd.exe(或 PowerShell)中,先切换到示例项目所在目录,再执行:

powershell -ExecutionPolicy Bypass -File ClearDownloadableFontCache.ps1

完整重置流程为:①关闭示例应用 → ②以管理员身份打开控制台窗口并切换到示例项目目录 → ③运行上述脚本 → ④重新启动示例应用。该流程同样适用于调试你自己的应用。

观察机制运行:任务管理器中的网络活动

Scenario_SampleOverview.xaml 还给出一个观察平台行为的实用技巧:在应用运行期间打开任务管理器并切换到"性能"(Performance)选项卡观察网络活动,每打开一个文档,都应能看到一次短暂的网络活动尖峰,那正是字体被下载的时刻。

需要注意的是:在桌面系统上,示例用到的部分字体可能本机已经安装。这种情况下 XAML 会直接使用本地字体立即显示文档,无需任何下载——这也从侧面印证了"按需下载"的前提是字体在本地不可用。

构建与运行示例

系统要求

目标平台要求
ClientWindows 10
ServerWindows Server 2016 Technical Preview
PhoneWindows 10

构建步骤

  1. 若下载的是样例 ZIP 包,务必解压整个归档,而不仅是包含目标示例的文件夹——解压完整才能访问共享依赖(本仓库中即SharedContent目录)。
  2. 启动 Visual Studio,选择文件>打开>项目/解决方案。
  3. 从解压目录进入Samples子文件夹,再进入本示例文件夹(XamlCloudFontIntegration),选择首选语言子目录(C++ 或 C#),双击解决方案文件(.sln)。C# 侧为 CloudFontIntegration.sln,C++ 侧为 CloudFontIntegration.sln。
  4. 按Ctrl+Shift+B,或选择生成>生成解决方案。

运行步骤

运行方式取决于仅部署还是部署并运行:

  • 仅部署:选择生成>部署解决方案。
  • 部署并运行:按F5(或选择调试>开始调试)进行调试运行;按Ctrl+F5(或选择调试>开始执行(不调试))则不调试直接运行。

总结与延伸阅读

XamlCloudFontIntegration 示例用最少的代码量展示了 Windows 10 一项颇具实用价值的能力:XAML 开发者零成本获得按需字体下载。其核心要点可总结为:

  • 零 API 接入:只需设置FontFamily,无需任何特殊 API 或标记。
  • 自动回退与刷新:字体缺失时先以回退字体显示,随后自动刷新为请求字体。
  • 系统级缓存:字体数据跨应用共享缓存,重复使用可跳过下载;长时间不用则可能被清除。
  • 按需分段下载:中日韩等大字体仅下载所需片段,字符扩充时增量补充。
  • 重置工具:ClearDownloadableFontCache.ps1可在管理员权限下清空字体缓存,用于反复演示与调试。

若想进一步了解 UWP 中的字体与排版设计规范,可参考仓库中其他相关示例;本示例本身还可在任务管理器网络活动面板中观察下载过程,作为验证机制运行的有效手段。

  • 示例工程

【免费下载链接】Windows-universal-samples

API samples for the Universal Windows Platform.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-universal-samples
点击查看免费下载
上一篇:Vim.js 开源项目使用教程:在浏览器中体验经典Vim编辑器
下一篇:5分钟完成黑苹果EFI配置:OpCore-Simplify智能自动化工具完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询