如何在MuPDF中使用自定义字体渲染EPUB文档?
在MuPDF中使用自定义字体渲染EPUB文档
一、修正自定义字体加载函数实现
你当前的代码存在两处关键问题:
- 存在一行多余的
reinterpret_cast语句,需要删除; - 忽略了字体样式参数(bold/italic),无法匹配不同样式的字体请求,同时字体名称的传递方式可能导致MuPDF无法正确识别。
修正后的代码如下:
// 创建fz_context后立即注册自定义字体加载函数 fz_install_load_system_font_funcs(m_ctx, [](fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics) -> fz_font* { fz_font *f = nullptr; fz_try(ctx) { // 根据请求的字体名称和样式匹配对应文件 if (strcmp(name, "Ubuntu") == 0) { std::string font_path = "/Users/seyedmahdimousavi/Library/Fonts/Ubuntu-R.ttf"; // 匹配粗体、斜体等变体 if (bold && italic) { font_path = "/Users/seyedmahdimousavi/Library/Fonts/Ubuntu-BI.ttf"; } else if (bold) { font_path = "/Users/seyedmahdimousavi/Library/Fonts/Ubuntu-B.ttf"; } else if (italic) { font_path = "/Users/seyedmahdimousavi/Library/Fonts/Ubuntu-I.ttf"; } // 传入nullptr让MuPDF自动从字体文件读取名称,避免名称不匹配 f = fz_new_font_from_file(ctx, nullptr, font_path.c_str(), 0, 0); } } fz_catch(ctx) { return nullptr; } // 不匹配自定义字体时返回nullptr,让MuPDF使用默认逻辑加载系统字体 return f; }, nullptr, nullptr); // 验证字体是否加载成功 fz_font *ff = fz_load_system_font(m_ctx, "Ubuntu", 0, 0, 0); if (!ff) { fz_throw(m_ctx, FZ_ERROR_GENERIC, "Ubuntu字体加载失败,请检查路径是否正确"); }
二、调整用户CSS规则
你的CSS中使用了非标准的"default"字体族,MuPDF无法识别,应替换为标准通用字体族(如sans-serif)作为 fallback:
* { font-family: "Ubuntu", sans-serif !important; }
三、确保CSS应用时机正确
必须在打开EPUB文档之前设置用户CSS,否则MuPDF加载文档时不会应用自定义样式:
fz_try(m_ctx) { const char* myCssText = "* { font-family: \"Ubuntu\", sans-serif !important; }"; fz_set_user_css(m_ctx, myCssText); // 打开EPUB文档(必须在设置CSS之后) fz_document *doc = fz_open_document(m_ctx, "你的EPUB文件路径"); // 后续渲染逻辑... } fz_catch(m_ctx) { // 错误处理逻辑 }
额外注意事项
- 字体路径必须是绝对路径,或相对于程序当前工作目录的正确路径,确保MuPDF能访问到字体文件;
- 如果EPUB内嵌了字体,需确保
!important足够强制覆盖内嵌样式; - 建议使用MuPDF最新稳定版,旧版本可能存在自定义字体加载的兼容性问题。
内容的提问来源于stack exchange,提问作者S.M.Mousavi
相关产品推荐
相关产品推荐

