首页 > 解决方案 > UWP 和 .NetCore - 不一致的字体系列名称

问题描述

我将 UWP 用于前端 GUI 和用 .NetCore 3.1 编写的完全信任后台进程,用于一些繁重的任务。但是,在拉回所有已安装的字体时,我遇到了一个奇怪的问题,因为返回的列表在两个框架之间并不一致。

在 UWP 中,以下代码(基于对这个 SO question的回答)用于填充下拉列表并返回大约 241 个字体系列:

public List<string> FontFamilies
{
    get
    {
        return CanvasTextFormat.GetSystemFontFamilies(ApplicationLanguages.Languages).OrderBy(x => x).ToList();
    }
}

然后将选定的字体系列作为字符串传递给尝试获取字体的 .NetCore 后台进程。但是,var fonts = System.Drawing.Text.InstalledFontCollection()会向 UWP 函数返回一个非常不同的列表(477 个元素)。许多这些额外的项目似乎是因为字体系列的变化(例如常规、粗体和斜体)没有被折叠成一个单一的系列。但在某些情况下,名称不同;例如Playlist Script,UWP 中的 OpenType 字体变成Playlist了 NetCore。

我试图查看语言 ID 是否与差异有关,但没有成功,并想知道是否有其他人不得不处理类似的问题?

标签: .net-coreuwpfonts

解决方案


我讨厌互联网上没有答案的问题,所以我发布了我在解决这个问题时的想法。我不会将其标记为答案,但以防其他人在以后提出更优雅的解决方案。

在填充 FontFamily 名称时,C# 中的各种字体库/框架似乎会拉回不同的名称 ID 。通常,所有字体名称都会匹配,这无关紧要,但有时它们不匹配并且(鉴于我的特定用例中有大量 OTF 字体)这就是导致我的问题的原因。

使用dp4 字体查看器,我能够检查字体元数据并将字段交叉引用到库返回的数据。使用上面示例中的播放列表脚本字体,结果发现我的代码中实际上有 3 个名称。

  1. 播放列表脚本 - 我认为 UWP 使用家族名称和子家族名称的组合。
  2. 播放列表 - 提供的姓氏System.Drawing.Text.InstalledFontCollection
  3. Playlist-Script - 我用来渲染一些图像的 ImageMagick.NET 库所需的完整字体名称。

d4p 字体信息

最后,我使用了现已废弃的SharpDX库,因为这是我能找到的唯一一个库,它可以让我访问字体元数据,以便能够始终如一地提取我需要的确切名称。

fontFamily.GetFont(0).GetInformationalStrings(InformationalStringId.FullName, out var localizedStrings);
if (!familyNames.FindLocaleName(CultureInfo.CurrentCulture.Name, out int index))
{
    if (!familyNames.FindLocaleName("en-us", out index))
    {
        index = 0;
    }
}

var coreName = localizedStrings.Count > 0 ? localizedStrings.GetString(0) : familyNames.GetString(index);

然后,我能够构建 UWP 兼容名称到 .NETCore 兼容名称的映射,并按预期呈现图像。


推荐阅读