ReportLab中的Unicode处理
我正在尝试使用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’)中根本不存在。