Devanagari字体PDF集成问题:印地语文字显示乱码求助
问题
手动用C语言生成PDF时,Devanagari(印地语)文本显示乱码(如२०८०)。已下载NotoSansDevanagari-VariableFont_wdth,wght.ttf字体,但调用该字体输出印地语文本时无效。
问题代码片段
fprintf(file, "BT\n"); fprintf(file, "40 100 TD\n"); fprintf(file, "/NotoSansDevanagari-VariableFont_wdth,wght 17 Tf\n"); fprintf(file, "(Result pdf created on : २०८० साउन ३, बुधवार) Tj\n"); fprintf(file, "ET\n");
当前乱码输出
Result pdf created on : २०८० साउन ३, बॕधà¤μ
解决方案
手动生成PDF支持Devanagari字体需要解决字体嵌入、编码处理、PDF资源定义三个核心问题,以下是具体步骤:
1. 注册并嵌入TrueType字体
你当前仅定义了Helvetica(Type1字体),未将下载的Noto Devanagari字体注册到PDF资源中:
- 新增字体对象,指定
/Subtype /TrueType,并嵌入字体文件的二进制数据 - 在页面资源(3 0 obj的
/Font字典)中添加该字体的引用,比如新增/NotoDeva 6 0 R
2. 修正文本编码逻辑
PDF不支持直接将UTF-8字符串传入Tj操作符,Devanagari字符需做编码转换:
- 不要直接用
fprintf输出UTF-8印地语文本,需将字符转换为对应字体的字形编码,或使用/Identity-H编码(直接用字形索引作为编码) - 配合
ToUnicode映射表,让PDF阅读器能将字形索引解析为正确的Unicode字符
3. 修复文本流长度计算
当前代码中/Length %d仅计算了name和school的长度,完全忽略了其他文本(包括印地语文本)的字节数,会导致PDF解析器读取错误:
- 先将所有内容写入临时缓冲区,计算缓冲区总字节数后再填入
/Length字段 - 避免硬编码长度,确保与实际内容流字节数一致
4. 字体嵌入代码示例
新增字体对象的核心结构(需替换为实际字体二进制数据):
// 6 0 obj:嵌入Noto Devanagari字体 fprintf(file, "6 0 obj\n"); fprintf(file, "<<\n"); fprintf(file, " /Type /Font\n"); fprintf(file, " /Subtype /TrueType\n"); fprintf(file, " /BaseFont /NotoSansDevanagari\n"); fprintf(file, " /Encoding /Identity-H\n"); fprintf(file, " /FontFile2 7 0 R\n"); // 指向字体二进制数据对象 fprintf(file, " /ToUnicode 8 0 R\n"); // 定义ToUnicode映射表对象 fprintf(file, ">>\n"); fprintf(file, "endobj\n");
5. 输出印地语文本的正确方式
使用十六进制形式传递字符(对应UTF-8编码),或使用字形索引:
// 示例:输出"साउन"的UTF-8十六进制形式 fprintf(file, "BT\n"); fprintf(file, "/NotoDeva 17 Tf\n"); fprintf(file, "<E0A4B9E0A4BE0A489E0A4A8> Tj\n"); fprintf(file, "ET\n");
内容的提问来源于stack exchange,提问作者IllTime00qw
相关产品推荐
相关产品推荐

