Itext PDF 无法正确显示缅甸 Unicode 字体

Cat*_*ysm 6 java pdf itext

Itext 5 不能在为缅甸 Unicode 字体生成的 pdf 文件中正确显示。

文本版本:5.5.13.1

预期结果:????????? ?????????????????????????????????????????? ???????????????????????? ???????????? ???????????????

实际结果

在此处输入图片说明

生成的 PDF 的Google Drive 链接

我的测试字符串与英文的“The quick brown fox jump over the lazy dog”类似。它包含大部分缅甸字母。

我曾经在 pdf 上生产的 Java 程序

    String fileName = "sample.pdf";
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
        Document doc = new Document();
        PdfWriter writer = PdfWriter.getInstance(doc, baos);
        writer.setCloseStream(false);

        BaseFont unicode = BaseFont.createFont("/fonts/NotoSansMyanmar-Regular.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font myanmarUniCodeFont = new Font(unicode, 11, Font.NORMAL, BaseColor.BLACK);
        Rectangle pageSize = new Rectangle(PageSize.A4);
        doc.setPageSize(pageSize);
        doc.open();
        String textStr = "????????? ?????????????????????????????????????? ????????????????????? ????????????? ??????????????";
        doc.add(new Paragraph(textStr, myanmarUniCodeFont));
        doc.close();
    }
    catch (Exception e) {
        e.printStackTrace();
    }

    response.setCharacterEncoding(StandardCharsets.UTF_8.name());
    response.setHeader("Cache-Control", "no-cache,no-store,max-age=0");
    response.setHeader("Pragma", "No-cache");
    response.setHeader("Content-Disposition", "inline; filename=" + fileName);
    response.setContentType("application/pdf");
    response.setContentLength(baos.size());
    OutputStream os = response.getOutputStream();
    baos.writeTo(os);
    os.flush();
    os.close();
    baos.close();
Run Code Online (Sandbox Code Playgroud)

输出文本正确(您可以复制并粘贴到 Notepad++ 等文本编辑器中并查看结果)但在 pdf 文件中显示错误。

我应该怎么做才能使用 itext-pdf-5 正确显示缅甸 Unicode 字体?

现在我使用肮脏的方式来查看可读的字体。我将所有 unicode 字符串转换为“Zawgyi 字体” (这是另一种缅甸字体,我们永远不应该使用它。)并嵌入到 pdf 中。这不是一个好的解决方案,我们不能保证所有 unicode 都正确转换为 Zawgyi-One 字体字符串,我不想将 unicode 文本转换为非标准文本。这就是为什么我不想使用这种方式。

使用 Itext 编辑 ZawGyi 字体

某些文本也无法使用 itext 正确呈现。例如:??????? ??

rhe*_*ens 3

(全面披露:我在 iText Software 工作。)

\n\n

iText 5 不支持缅甸书写系统的正确基于 Unicode 的处理。尽管 iText 5 有针对阿拉伯语的特定实现,但其字体基础结构的固有限制阻碍了对各种其他书写系统所需的字体功能的支持。

\n\n

iText 7 通过新的字体实现和可选模块(pdfCalligraph,非开源)对此进行了改进,以支持不同的书写系统。但是,缅甸(尚未)不受支持。

\n\n

相应的 iText 7 代码如下所示:

\n\n
PdfWriter writer = new PdfWriter(baos);\nPdfDocument pdfdoc = new PdfDocument(writer);\nDocument doc = new Document(pdfdoc);\n\nPdfFont f = PdfFontFactory.createFont("/fonts/NotoSansMyanmar-Regular.ttf",\n    PdfEncodings.IDENTITY_H, true);\n\nString textStr =\n    "\xe1\x80\x9e\xe1\x80\xae\xe1\x80\x9f\xe1\x80\xad\xe1\x80\xaf\xe1\x80\xa0\xe1\x80\xba\xe1\x80\x99\xe1\x80\xbe \xe1\x80\x89\xe1\x80\xac\xe1\x80\x8f\xe1\x80\xba\xe1\x80\x80\xe1\x80\xbc\xe1\x80\xae\xe1\x80\xb8\xe1\x80\x9b\xe1\x80\xbe\xe1\x80\x84\xe1\x80\xba\xe1\x80\x9e\xe1\x80\x8a\xe1\x80\xba\xe1\x80\xa1\xe1\x80\xac\xe1\x80\x9a\xe1\x80\xaf\xe1\x80\x9d\xe1\x80\x8e\xe1\x80\xb9\xe1\x80\x8d\xe1\x80\x94\xe1\x80\x86\xe1\x80\xb1\xe1\x80\xb8\xe1\x80\x8a\xe1\x80\xbd\xe1\x80\xbe\xe1\x80\x94\xe1\x80\xba\xe1\x80\xb8\xe1\x80\x85\xe1\x80\xac\xe1\x80\x80\xe1\x80\xad\xe1\x80\xaf \xe1\x80\x87\xe1\x80\x9c\xe1\x80\xbd\xe1\x80\x94\xe1\x80\xba\xe1\x80\x88\xe1\x80\xb1\xe1\x80\xb8\xe1\x80\x98\xe1\x80\xb1\xe1\x80\xb8\xe1\x80\x97\xe1\x80\xac\xe1\x80\x92\xe1\x80\xb6\xe1\x80\x95\xe1\x80\x84\xe1\x80\xba\xe1\x80\x91\xe1\x80\x80\xe1\x80\xba \xe1\x80\xa1\xe1\x80\x93\xe1\x80\xad\xe1\x80\x8b\xe1\x80\xb9\xe1\x80\x8c\xe1\x80\xac\xe1\x80\x94\xe1\x80\xba\xe1\x80\x9c\xe1\x80\xbb\xe1\x80\x80\xe1\x80\xba \xe1\x80\x82\xe1\x80\x83\xe1\x80\x94\xe1\x80\x8f\xe1\x80\x96\xe1\x80\x90\xe1\x80\xba\xe1\x80\x81\xe1\x80\xb2\xe1\x80\xb7\xe1\x80\x9e\xe1\x80\x8a\xe1\x80\xba\xe1\x81\x8b";\n// Explicit writing system\n//doc.add(new Paragraph(textStr).setFont(f).setFontScript(Character.UnicodeScript.MYANMAR));\n// Rely on autodetection\ndoc.add(new Paragraph(textStr).setFont(f));\ndoc.close();\n
Run Code Online (Sandbox Code Playgroud)\n\n

无论是否使用pdfCalligraph,渲染仍然错误​​:

\n\n

错误的缅甸渲染

\n\n

如果您可以选择商业许可证,请提交此功能请求。仍在积极添加其他书写系统。如果没有,恐怕 iText 无法做到这一点,您将不得不寻找其他解决方案。

\n