ReportLab中的Unicode处理

2 投票
2 回答
4443 浏览
提问于 2025-04-15 15:12

我正在尝试使用ReportLab处理Unicode字符,但遇到了问题。我追踪代码,发现了一行关键代码:

class TTFont:
    # ...
    def splitString(self, text, doc, encoding='utf-8'):
        # ...
        cur.append(n & 0xFF) # <-- here is the problem!
        # ...

(这段代码可以在ReportLab的代码库中找到,文件路径是 pdfbase/ttfonts.py,相关代码在第1059行。)

为什么要对n的值进行处理?

在上面那行代码中,n代表正在处理的字符的编码点(比如'A'的编码是65,'a'是97,阿拉伯字母'ش'是1588)。cur是一个列表,用来存放最终输出的字符(据我理解)。在这行代码之前,一切似乎都正常,但在这一行中,n的值被处理了,似乎被压缩到了扩展ASCII范围内!

这导致非ASCII的Unicode字符失去了它们的值。我不明白这行代码有什么用,或者为什么需要这样做!

所以我的问题是,为什么在这里要处理n的值,我该如何解决这个问题?

编辑:
针对评论中提到的我的代码片段,这里有一个导致这个错误的例子:

my_doctemplate.build([Paragraph(bulletText = None, encoding = 'utf8',
    caseSensitive = 1, debug = 0,
    text = '\xd8\xa3\xd8\xa8\xd8\xb1\xd8\xa7\xd8\xac',
    frags = [ParaFrag(fontName = 'DejaVuSansMono-BoldOblique',
        text = '\xd8\xa3\xd8\xa8\xd8\xb1\xd8\xa7\xd8\xac',
        sub = 0, rise = 0, greek = 0, link = None, italic = 0, strike = 0,
        fontSize = 12.0, textColor = Color(0,0,0), super = 0, underline = 0,
        bold = 0)])])

PDFTextObject._textOut中,调用了_formatText,它识别字体为_dynamicFont,并相应地调用font.splitString,这就是导致上述错误的原因。

2 个回答

0

我很确定,你需要把 0xFF 改成 0xFFFF,这样才能使用4字节的unicode字符,就像~unutbu建议的那样,也就是说要用四个字节而不是两个字节。

1

你说的“没用”是什么意思?你引用的reportlab源代码有误。实际上,它的做法是把每个16位的unicode字符的低字节和高字节分别编码(高字节只有在变化时才会被写出来,我猜这是为了PDF的特定优化,目的是让文档更小)。

请准确说明问题是什么,而不是你认为的根本原因。很可能你想显示的字符在你选择的字体(‘DejaVuSansMono-BoldOblique’)中根本不存在。

撰写回答