当前位置: 首页 > news >正文

ImGui 学习笔记(五) —— 字体文件加载问题

ImGui 加载字体文件的函数似乎存在编码问题,这一点可能跟源文件的编码也有关系,我目前源文件编码是 UTF-16。

当参数中包含中文字符时,ImGui 内部将字符转换为宽字符字符集时候,采用的 MultiByteToWideChar API 参数不太对,应该改为 CP_ACP 才对,原本它使用的是 CP_UTF8。

函数位于 imgui.cpp :

ImFileHandle ImFileOpen(const char* filename, const char* mode)
{
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && (defined(__MINGW32__) || (!defined(__CYGWIN__) && !defined(__GNUC__)))
    // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.
    // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
    const int filename_wsize = ::MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
    const int mode_wsize = ::MultiByteToWideChar(CP_ACP, 0, mode, -1, NULL, 0);

    // Use stack buffer if possible, otherwise heap buffer. Sizes include zero terminator.
    // We don't rely on current ImGuiContext as this is implied to be a helper function which doesn't depend on it (see #7314).
    wchar_t local_temp_stack[FILENAME_MAX];
    ImVector<wchar_t> local_temp_heap;
    if (filename_wsize + mode_wsize > IM_ARRAYSIZE(local_temp_stack))
        local_temp_heap.resize(filename_wsize + mode_wsize);
    wchar_t* filename_wbuf = local_temp_heap.Data ? local_temp_heap.Data : local_temp_stack;
    wchar_t* mode_wbuf = filename_wbuf + filename_wsize;
    ::MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_wbuf, filename_wsize);
    ::MultiByteToWideChar(CP_ACP, 0, mode, -1, mode_wbuf, mode_wsize);
    DBGPRINT(L"FileOpen Path: %s", filename_wbuf);
    return ::_wfopen(filename_wbuf, mode_wbuf);
#else
    return fopen(filename, mode);
#endif

修改前,字体加载失败,然后我发现它处理相对路径的方式也不好。改用完整路径后也还是一样失败:

输出更多信息看看:
 

明显路径中中文编码出现了乱码 ?????。

按照上面方法修改后,你可能会在 Read 失败。继续看,发现这里可能有问题:
void*   ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size, int padding_bytes)

找到 ImFileRead(file_data, 1, file_size, f) 他直接写在条件里面的,我们把他改成两步:

size_t ret_size = ImFileRead(file_data, 1, file_size, f);
if (ret_size != file_size)
{
    ImFileClose(f);
    IM_FREE(file_data);
    return NULL;
}

最后,再次尝试:
 

绝对路径(加载字体文件)已经没有问题了;如果用相对路径则还有问题,并且可能与访问权限有关系。

我注入的程序在 C:\Windows\ 下,这里创建 imgui.ini 默认的配置文件失败。这个好解决,在加载函数前面加上一些路径检查和转换的代码,比如转为绝对路径(程序目录+文件名),然后检查权限,权限不够就改用 COM 或者提权(我这里不考虑跨平台,所以没关系,如果考虑跨平台,可能需要更多修改)。

相关文章:

  • Redis集群扩容实战指南:从原理到生产环境最佳实践
  • DICOM医学影像数据加密技术应用的重要性及其实现方法详解
  • 优选算法的匠心之艺:二分查找专题(二)
  • 双模型协作机制的deepseek图片识别
  • Linux错误(2)程序触发SIGBUS信号分析
  • CTF类题目复现总结-真的很杂 1
  • Spring Boot 集成 Lua 脚本:实现高效业务逻辑处理
  • 【小项目】四连杆机构的Python运动学求解和MATLAB图形仿真
  • Elasticsearch:为推理端点配置分块设置
  • 【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解
  • Qt SQL-1
  • 基于MapReduce的气候数据分析
  • [JAVASE] 反射
  • USB转多路串口项目资料汇总
  • 第九讲 排序(上)
  • (链表)面试题 02.07. 链表相交
  • 【vue2 + Cesium】相机视角移动+添加模型、模型点击事件
  • 鸿蒙开发:什么是ArkTs?
  • Vue学习笔记集--props组件
  • 快速进行数据验证的优雅实现-注解
  • 百度网站描述/sem营销是什么意思
  • 优斗士做网站怎么样/模板免费网站建设
  • 沧州企业做网站/企业培训内容
  • 佛山做推广网站的/教育培训机构营销方案
  • 记事本做网站如何排版/今日小说排行榜百度搜索榜
  • 济南冰河世纪网站建设/青岛seo杭州厂商