首页 > 解决方案 > 在 Win32 上从字节数组创建字体资源

问题描述

我有一个字节数组,其中包含读取字体文件的内容。我希望 WinAPI (No Gdi+) 从中创建一个字体资源,所以我可以用它来呈现文本。

我只知道AddFontResourceExW,它从文件加载字体资源,以及AddFontMemResourceEx,这听起来像是我需要的,但在我看来,它仍然是一些资源系统的东西,数据必须预先关联与程序。

我可以以某种方式将加载的字节数组转换为字体资源吗?(可能没有将其写入文件然后调用AddFontResourceExW

标签: winapi

解决方案


当您将资源脚本中的字体加载到内存中时,您使用如下代码(您没有添加语言标签,所以我使用的是 C/C++ 代码 - 如果有问题请告诉我):

    HANDLE H_myfont = INVALID_HANDLE_VALUE;
    HINSTANCE hResInstance = ::GetModuleHandle(nullptr);
    HRSRC ares = FindResource(hResInstance, MAKEINTRESOURCE(IDF_MYID), L"BINARY");
    if (ares) {
        HGLOBAL amem = LoadResource(hResInstance, ares);
        if (amem != nullptr) {
            void *adata = LockResource(amem);
            DWORD nFonts = 0, len = SizeofResource(hResInstance, ares);
            H_myfont = AddFontMemResourceEx(adata, len, nullptr, &nFonts);
        }
    }

这里的关键是void *adata = LockResource(amem);- 这会将作为加载的字体资源转换HGLOBAL为“可访问内存”(文档)。现在,假设您的字节数组格式正确(见下文),您可能只需void*在对AddFontMemResourceEx. (您可以使用已知的数组大小代替调用SizeofResource。)

我会建议这样的代码:

    void *my_font_data = (void*)(font_byte_array); // Your byte array data
    DWORD nFonts = 0, len = sizeof(font_byte_array);
    H_myfont = AddFontMemResourceEx(my_font_data, len, nullptr, &nFonts);

这(希望)会给你一个加载和可用的字体资源。

当你完成了字体(一旦加载,就可以像任何系统安装的字体一样使用),你可以释放它:

    RemoveFontMemResourceEx(H_myfont);

由于我没有你的字节数组,我不能(显然)测试这个想法。但是,如果您确实尝试过,请告诉我们它是否有效。(如果没有,可能需要添加一些其他相对简单的步骤。)

注意:虽然我不能说 100% 预期的“字体资源”的确切格式是什么,但上面给出的代码(对我来说)适用于 .rc 脚本中定义的资源,就像BINARY普通的一样,“ .ttf" 文件,建议如果您的字节数组遵循 Windows 字体文件的格式,那么它应该可以工作。这就是我将字体作为嵌入资源包含在内的方式:

IDF_MYFONT  BINARY  L"..\\Resource\\MyFont.ttf"

推荐阅读