我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

Dear ImGui 嵌入式字体开发:把字体数据嵌入源码与从内存加载字体

Dear ImGui 嵌入式字体开发:把字体数据嵌入源码与从内存加载字体 Dear ImGui 嵌入式字体开发把字体数据嵌入源码与从内存加载字体【免费下载链接】imguiDear ImGui: Bloat-free Graphical User interface for C with minimal dependencies项目地址: https://gitcode.com/GitHub_Trending/im/imgui在嵌入式、控制台或受限文件系统中程序运行时往往拿不到磁盘上的.ttf文件却仍然需要自定义字体。Dear ImGui 自身就是这样设计的它把 ProggyClean.ttf 和 ProggyForever.ttf 直接嵌在代码里这样你可以不依赖任何文件系统访问来使用 Dear ImGui原文如此见 docs/FONTS.md。当你也想带自己的字体时项目文档给出两条路径把字体的原始二进制缓冲直接传入io.Fonts-AddFontFromMemoryTTF()或者先用仓库自带工具 misc/fonts/binary_to_compressed_c.cpp 把字体压缩成一个 C 数组嵌进源码再用AddFontFromMemoryCompressedTTF()加载。本文按从内存缓冲加载和嵌入压缩数组两条路径给出完整的命令、代码和验证方式。先选路径原始内存缓冲还是压缩数组两条路径都满足运行时不读字体文件差别在数据形态AddFontFromMemoryTTF()你已经在程序里有一段原始 TTF/OTF 数据例如打包在资源段、或由构建脚本生成直接传指针和长度即可。AddFontFromMemoryCompressedTTF()/AddFontFromMemoryCompressedBase85TTF()先用工具把.ttf文件压缩并导出成 C 数组。数据先经stb_compress()压缩再存为数组源码体积显著小于裸字节数组这是文档推荐的嵌入源码方式。另外一点与嵌入式目标直接相关如果应用根本不用 Dear ImGui 内嵌的默认字体可以在 imconfig.h 中定义IMGUI_DISABLE_DEFAULT_FONT这样发布的二进制里就不带字体、节省约 26 KB文档给出的数值。路径一用 AddFontFromMemoryTTF 从内存缓冲加载基本调用形式来自 docs/FONTS.md Loading Font Data from Memory 一节ImFont* font io.Fonts-AddFontFromMemoryTTF(data, data_size, size_pixels, ...);这里data指向原始字体文件内容data_size是字节数。函数名带 TTF但 imgui.h 中ImFontAtlas的注释明确说明尽管很多函数以 TTF 结尾OTF 数据同样支持。所有权是这个 API 的关键点。默认情况下AddFontFromMemoryTTF()会把数据缓冲的所有权移交给字体图集图集销毁时会尝试 free 这块内存——这是为了避免一次不必要的拷贝。如果你的缓冲是自己管理的静态数组、malloc后自己释放等必须显式清除FontDataOwnedByAtlasImFontConfig font_cfg; font_cfg.FontDataOwnedByAtlas false; ImFont* font io.Fonts-AddFontFromMemoryTTF(data, data_size, size_pixels, font_cfg);使用FontDataOwnedByAtlas false时有一个版本相关的前提自 1.92 起字体数据必须保持有效直到atlas-RemoveFont()或者更常见地直到所属 context / 字体图集关闭。1.92.0 中由于一个处理该标志的 bug这一点并不明显该 bug 在 1.92.6 修复见 docs/CHANGELOG.txt 中 1.92.6 的 Fonts 条目。也就是说不要把这段缓冲声明成函数内的临时变量然后返回指针。路径二用 binary_to_compressed_c 生成压缩数组工具源文件在 misc/fonts/binary_to_compressed_c.cpp文件头部注释给出了构建与用法。先编译工具# 任选其一工具源文件头部注释给出的构建方式 g binary_to_compressed_c.cpp clang binary_to_compressed_c.cpp cl.exe binary_to_compressed_c.cpp文档同时提到Windows 下可以在 demo 二进制包中找到预编译的binary_to_compressed_c.exe不一定要自己编译。生成数组的用法注释中的 Usage examplemyfont.ttf换成你的字体文件MyFont是你指定的符号名binary_to_compressed_c.exe myfont.ttf MyFont myfont.cpp可选参数参数名以工具实际输出的帮助为准-u8/-u32/-base85源码编码方式。自 2024/11 起默认是-u8按字节输出不依赖字节序-u32按整型输出大端 CPU 需要换序-base85源码最省约 5 字节源码对应 4 字节数据但 docs/FONTS.md 指出 Base85 输出在最终二进制里的只读数组大约大 20%且工具注释明确写着 Base85 encoding will be obsoleted by future version of Dear ImGui所以新代码建议走默认的-u8形式。-nocompress跳过stb_compress()压缩步骤。-nostatic输出的数组不加static。以默认-u8为例工具输出的文件形如符号名即你传入的第二个参数前缀自动加上compressed_static const unsigned int MyFont_compressed_size /* 压缩后字节数 */; static const unsigned char MyFont_compressed_data[] { /* 压缩数据 */ };把这个生成的.cpp文件加入你的工程即可字体数据从此成为可执行文件的一部分。加载嵌入的压缩字体生成数组后在初始化 ImGui 时调用NewFrame之前加载// 加载 -u8 生成的压缩数组 ImFont* font io.Fonts-AddFontFromMemoryCompressedTTF( MyFont_compressed_data, MyFont_compressed_size, size_pixels); // 或者如果用 -base85 生成的字符串数组 ImFont* font io.Fonts-AddFontFromMemoryCompressedBase85TTF( MyFont_compressed_data_base85, size_pixels);几点与上述代码直接相关的说明均来自 docs/FONTS.md 和 imgui.h 中的接口注释与路径一不同压缩数据的加载函数不接管所有权——AddFontFromMemoryCompressedTTF()的注释写明 compressed_font_data still owned by caller。上面的数组是static const程序生命周期内始终有效满足自 1.92 起数据需保持有效直到RemoveFont()或 context/图集销毁的要求。自 1.92 起配合支持新动态字体系统的 backend指定字号不再必要imgui.h中这两个函数的size_pixels默认值就是0.0f可以省略。加载后若要在界面中切换字体用法与文件加载一致ImGui::PushFont(font, 0.0f)切换、ImGui::PopFont()恢复第一个加载的字体是默认字体。验证字体是否真正加载成功文档给出的检查方式是Metrics/Debugger窗口从Demo Tools打开其中Metrics/Debugger - Fonts可以浏览已加载的字体、字体输入和加载的字形范围docs/FONTS.md 的 Troubleshooting 一节正是建议用它来确认 loaded fonts and loaded glyph ranges。字体加载后如果某个字符显示不出来先在这个窗口核对字形范围1.92 之前必须显式指定 glyph ranges缺范围是非 ASCII 字符显示问题的主因之一。另一个文档明确记录的失败现象是字形过多或多个字体导致图集纹理过大、上传 GPU 失败时典型结果是所有字形显示为空的白色矩形。如果你的嵌入字体加载后出现白块按文档给出的方向处理降低过采样如font_config.OversampleH 1纹理减半、质量损失、缩小字形范围或设置io.Fonts.Flags | ImFontAtlasFlags_NoPowerOfTwoHeight;禁止把纹理高度向上取整到 2 的幂。限制与版本注意1.92 的数据生命周期变化1.92 之前字体数据只需在AddFontXXX()调用期间有效自 1.92 起需保持到RemoveFont()或 context/图集销毁。使用FontDataOwnedByAtlas false的代码在 1.92.6 之前因 bug 实际做了拷贝修复后这一要求才真正生效——从旧版本迁移到 1.92.6 及以上时检查自己持有的字体缓冲生命周期。Base85 处于弃用轨道工具与文档均提示 Base85 输出将在未来版本废弃现有项目不要新增 Base85 依赖。仓库附带字体仅供参考misc/fonts/ 目录下提供了几种字体文件作为便利但文档说明这些文件如今大多已不再必要且可能最终被移除嵌入开发中应使用自己选型并确认授权的字体。完成上述步骤后验收标准就是Metrics/Debugger - Fonts中能看到你加载的字体输入与字形范围且目标文本而非白色矩形正常渲染。【免费下载链接】imguiDear ImGui: Bloat-free Graphical User interface for C with minimal dependencies项目地址: https://gitcode.com/GitHub_Trending/im/imgui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表