贝利信息

如何在 PDF 中正确渲染古吉拉特语(Gujarati)文本

日期:2026-01-22 00:00 / 作者:心靈之曲

使用 pymupdf(fitz)向 pdf 插入古吉拉特语等复杂脚本文字时,若直接调用 `insert_text()` 且未正确配置字体与渲染方式,易出现字符错位、连字断裂(如“રવ્ નિદર”而非“રવિન્દ્ર”),根本原因是 `insert_text()` 不支持 opentype 特性(如 gsub/gpos 表),无法处理印度系文字的上下文连字与元音附标定位。

要可靠渲染古吉拉特语(以及泰米尔语、印地语、孟加拉语等印度系文字),必须避免 page.insert_text(),而应改用 page.insert_htmlbox() —— 这是 PyMuPDF 内置的轻量级 HTML 渲染引擎,底层基于 MuPDF 的 HTML/CSS 解析器,原生支持 Unicode、双向文本(BIDI)、OpenType 字体特性(包括连字、元音位置调整、辅音簇组合),能准确还原复杂脚本的视觉呈现。

✅ 正确做法:使用 insert_htmlbox()

insert_htmlbox() 接收 HTML 字符串和一个矩形区域(rect),自动选择系统或嵌入字体,并启用完整文本整形(shaping)。以下是适配您原始场景的修复版代码:

import fitz
from googletrans import Translator

def add_gujarati_text_to_pdf(pdf_path, output_path, text_to_add):
    # 打开现有 PDF(注意:insert_htmlbox 可用于已有文档)
    doc = fitz.open(pdf_path)

    # 定义插入区域:x0, y0, x1, y1(左上→右下)
    # 示例:在第3页(索引2)的 (175, 215) 附近放置一个宽150高40的文本框
    rect = fitz.Rect(175, 215, 325, 255)  # 宽度=150, 高度=40

    for page_num in range(doc.page_count):
        if page_num == 2:  # 第三页(0-indexed)
            page = doc[page_num]

            # 构建带内联样式的 HTML(确保字体可读且支持 Gujarati)
            html = f'''
            {text_to_add}
            '''

            # 关键:使用 insert_htmlbox 替代 insert_text
            page.insert_htmlbox(rect, html)
            break

    # 启用字体子集化(减小体积,保留所需字符)
    doc.subset_fonts()

    # 保存并压缩
    doc.save(output_path, garbage=3, deflate=True)
    doc.close()

# 使用示例
if __name__ == "__main__":
    input_pdf_path = "input.pdf"
    output_pdf_path = "output_with_gujarati.pdf"

    translator = Translator()
    result = translator.translate('Ravindra Nakrani', src='en', dest='gu')
    gujarati_name = result.text  # 如:રવિન્દ્ર નાકરાણી
    print("Translated:",

gujarati_name) add_gujarati_text_to_pdf(input_pdf_path, output_pdf_path, gujarati_name)

⚠️ 关键注意事项