使用 DirectWrite,我正在尝试获取 名为 Copyduck 的字体。
在我的 Windows 11 (10.0.22631.2861) 计算机上,我提供的代码没有找到该字体,但在我的 Windows 10 (10.0.19045.4046) 计算机上它找到了它。需要注意的是,在我的 Windows 11 机器中,在许多使用 directwrite 的应用程序中,我可以毫无问题地使用该字体。另外,我可以看到C:\Windows\Fonts
中的字体。重要注意事项。为了安装这个字体,我使用了
fontbase 并在其中激活 Copyduck。我想它使用 AddFontResource 并且似乎在 HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Fonts
中添加字体。 Directwrite 无法查询由fontbase 激活的任何字体,这很奇怪,但我可以查询任何“系统”字体。 为什么会发生这种情况?为什么所有应用程序(如 Word、Photoshop、Aegisub、libass)都能够看到
fontbase 安装的字体,但我的小程序却看不到。
这是我的代码(PS:我在 Visual Studio 2022 中运行它):
#include <iostream>
#include <dwrite_3.h>
#pragma comment(lib, "Dwrite.lib")
int main() {
IDWriteFactory3* dwrite_factory;
if (FAILED(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(dwrite_factory), reinterpret_cast<IUnknown**>(&dwrite_factory))))
return 1;
IDWriteFontSet* font_set;
if (FAILED(dwrite_factory->GetSystemFontSet(&font_set)))
return 1;
std::wcout << L"There is " << font_set->GetFontCount() << L" fonts installed." << std::endl;
DWRITE_FONT_PROPERTY_ID property_ids[] = {
DWRITE_FONT_PROPERTY_ID_WIN32_FAMILY_NAME,
DWRITE_FONT_PROPERTY_ID_FULL_NAME,
DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME,
};
for (int i = 0; i < sizeof property_ids / sizeof * property_ids; i++) {
DWRITE_FONT_PROPERTY property = {
property_ids[i],
L"Copyduck",
L"",
};
IDWriteFontSet* filtered_set;
HRESULT hr = font_set->GetMatchingFonts(&property, 1, &filtered_set);
if (FAILED(hr) || !filtered_set)
continue;
std::wcout << L"GetFontCount " << filtered_set->GetFontCount() << std::endl;
filtered_set->Release();
}
font_set->Release();
dwrite_factory->Release();
return 0;
}
编辑 (15-03-2024)C:\Windows\Fonts
)但是,在 Windows 10 上,我看到了 这很奇怪。我询问了一位通过将Windows 10升级到11来安装Windows 11的用户,他能够使用directwrite来查询fontbase安装的字体。
在 Windows 10 上,如果我有
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Fonts
的条目,我可以直接使用 directwrite 查询它。但是,在 Windows 11 上,如果我输入了
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Fonts
,directwrite 不会检测到字体!。需要注意的是,GDI 能够检测到它,因此它会在 GDI 和 Directwrite 之间造成不一致。此时,我非常确定这是 Windows 11 中的一个错误。即使我真的不知道该怎么做,我也会尝试将其报告给微软。
FontBase 并激活字体(文件)时,它会做两件事
c:\users\simon\fontbase
)。
完成后,您可以在“旧”Windows UI 中看到此字体,其中该字体标有链接/快捷方式覆盖:
有些程序可以使用它,我猜是因为它们手动读取注册表设置并直接加载指向的字体文件。
但是DirectWrite
也无法读取它,可能是因为它不喜欢自定义文件夹,这可能是(我猜,找不到任何关于此的官方文档)一个安全问题,因为这个相对较新的功能字体Microsoft Store 中的设置和字体 允许直接从应用程序商店安装字体。
因此,要使其正常工作,您可以将 FontBase 配置为指向 HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Fonts
现在一旦激活,DirectWrite 将看到它以及更新的 Windows UI:
顺便说一句,既然有了这个功能,安装字体就很简单了,你也可以自己修改注册表,把文件放到Fonts文件夹里,不需要FontBase之类的工具了。
否则,如果您确实想使用 FontBase 而无需重新配置它,您还可以编写一个 DirectWrite 自定义字体文件加载器,读取注册表并“手动”加载字体(但 DirectWrite 不会枚举它)。